photo_folder 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/models/photo.rb ADDED
@@ -0,0 +1,115 @@
1
+ class Photo < ActiveRecord::Base
2
+ belongs_to :photo_collection
3
+ has_many :photo_taggings, :dependent => :destroy
4
+ has_many :photo_tags, :through => :photo_taggings
5
+ acts_as_list :scope => :photo_collection
6
+ before_create :set_exif_data, :set_last_modified, :set_guid, :set_nsfw
7
+ after_create :set_tags
8
+
9
+ def self.guid(path,date)
10
+ Digest::MD5.hexdigest([
11
+ path,
12
+ date
13
+ ].join(''))
14
+ end
15
+
16
+ def full_path
17
+ File.join(PhotoFolder.source_directory_location,path)
18
+ end
19
+
20
+ def update_meta
21
+ set_exif_data
22
+ set_last_modified
23
+ set_guid
24
+ set_nsfw
25
+ save
26
+ set_tags
27
+ end
28
+
29
+ def set_guid
30
+ self.guid = Photo.guid(path,date)
31
+ end
32
+
33
+ def set_tags
34
+ #@tags was set by set_exif_data, which is always called first
35
+ self.photo_taggings.destroy_all
36
+ @tags.each do |str|
37
+ self.photo_taggings.create({
38
+ :photo_tag_id => (PhotoTag.find_by_tag(str) || PhotoTag.create(:tag => str)).id,
39
+ :photo_id => self.id
40
+ })
41
+ end
42
+ end
43
+
44
+ def set_nsfw
45
+ self.nsfw = @tags.collect(&:downcase).include?('nsfw') ? 1 : 0
46
+ end
47
+
48
+ def set_last_modified
49
+ self.last_modified = File.mtime(full_path)
50
+ end
51
+
52
+ def set_exif_data
53
+ begin
54
+ exif = EXIFData.new(MiniExiftool.new(full_path),logger)
55
+
56
+ [:focal_length,:iso,:shutter_speed,:f_stop,:camera,:caption,:location,:height,:width].each do |key|
57
+ self.send(key.to_s + '=',exif[key] || nil)
58
+ end
59
+
60
+ #date,title,lens and tags are special cases
61
+ if exif[:date].is_a? Time
62
+ self.date = exif[:date]
63
+ else
64
+ date_match = (exif[:date] || '').match(/([\d]+):([\d]+):([\d]+) ([\d]+):([\d]+):([\d]+)/)
65
+ self.date = Time.mktime(date_match[1],date_match[2],date_match[3],date_match[4],date_match[5],date_match[6]) if date_match
66
+ end
67
+ self.name = exif[:title] || full_path.split('/').pop.gsub(/\.[a-zA-Z]{1,4}/,'')
68
+ self.lens = exif[:lens] ? exif[:lens] : nil
69
+ @tags = exif[:tags] || []
70
+ rescue
71
+ self.name = full_path.split('/').pop.gsub(/\.[a-zA-Z]{1,4}/,'')
72
+ @tags = []
73
+ end
74
+ end
75
+
76
+ class EXIFData
77
+ EXIF_TRANSLATIONS = {
78
+ :title => ['Title','ObjectName'],
79
+ :focal_length => ['FocalLength'],
80
+ :iso => ['ISO'],
81
+ :height => ['ImageHeight'],
82
+ :width => ['ImageWidth'],
83
+ :shutter_speed => ['ShutterSpeedValue'],
84
+ :f_stop => ['ApertureValue'],
85
+ :lens => ['Lens','LensType'],
86
+ :camera => ['Model'],
87
+ :date => ['DateTimeOriginal'],
88
+ :caption => ['Description','ImageDescription','Caption-Abstract'],
89
+ :tags => ['Keywords','Subject'],
90
+ :location => ['Location'],
91
+ }
92
+
93
+ EXIF_TRANSFORMATIONS = {
94
+ #:date => lambda{|exif_value| exif_value.to_s.split('-').shift},
95
+ :shutter_speed => lambda{|exif_value| exif_value.to_s.gsub(/1\//,'')},
96
+ :focal_length => lambda{|exif_value| exif_value.to_s.gsub(/\.([\d]{1,})?\s?.+$/,'')},
97
+ :tags => lambda{|exif_value| (exif_value.is_a?(Array) ? exif_value.join(',') : exif_value).gsub(/["']+/,'').gsub(/\s+?,\s+?/,',').split(',').collect(&:strip).collect(&:downcase)}
98
+ }
99
+
100
+ def initialize(exif_data,logger)
101
+ @exif_data = exif_data
102
+ @logger = logger
103
+ end
104
+
105
+ def [](key)
106
+ EXIF_TRANSLATIONS[key.to_sym].each do |exif_key_name|
107
+ exif_value = @exif_data[exif_key_name.to_s]
108
+ if !exif_value.nil? && exif_value != false && exif_value != '' && exif_value != 'false' && exif_value != 'nil'
109
+ return EXIF_TRANSFORMATIONS[key] ? EXIF_TRANSFORMATIONS[key].call(exif_value) : exif_value
110
+ end
111
+ end
112
+ false
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,96 @@
1
+ class PhotoCollection < ActiveRecord::Base
2
+ has_many :photos, :order => 'position'
3
+ acts_as_list :scope => :parent_id
4
+ acts_as_tree :order => :name
5
+ after_create :set_children_parent_id
6
+ before_create :set_name
7
+
8
+ def self.set_correct_positions(collections,is_callback = false)
9
+ collections.sort_by(&:name).each_with_index do |collection,i|
10
+ collection.update_attribute :position, i
11
+ set_correct_positions(PhotoCollection.find_all_by_parent_id(collection.id),true)
12
+ end
13
+ if self.positions && !is_callback
14
+ self.positions.each_with_index do |file_name,i|
15
+ photo_collection = PhotoCollection.find_by_path(file_name,{
16
+ :conditions => {
17
+ :parent_id => 0
18
+ }
19
+ })
20
+ if photo_collection
21
+ photo_collection.insert_at i + 1
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.positions_file_path
28
+ File.join(PhotoFolder.source_directory_location,'positions.yml')
29
+ end
30
+
31
+ def self.positions
32
+ return @positions if !@positions.nil?
33
+ if File.exists?(self.positions_file_path)
34
+ @positions = YAML.load(File.read(self.positions_file_path))
35
+ else
36
+ nil
37
+ end
38
+ end
39
+
40
+ def set_children_parent_id
41
+ PhotoFolder::all_paths_in_database.select{|path| self.path.underscore.gsub(/\s/,'_') == path.gsub(/\/[^\/]+$/,'').underscore.gsub(/\s/,'_')}.each do |path|
42
+ Photo.update_all("photo_collection_id = #{self.id}","path = '#{path}'")
43
+ end
44
+ end
45
+
46
+ def set_parent_id
47
+ update_attribute :parent_id, parent_from_path ? parent_from_path.id : 0
48
+ end
49
+
50
+ def set_name
51
+ self.name = path.split('/').pop.gsub(/[\_\-]+/,' ').split(/\s+/).each(&:capitalize!).join(' ')
52
+ end
53
+
54
+ def parent_from_path
55
+ self.path.count('/') > 0 ? PhotoCollection.find_by_path(self.path.gsub(/\/[^\/]+$/,'')) : false
56
+ end
57
+
58
+ def full_path
59
+ File.join(PhotoFolder.source_directory_location,path)
60
+ end
61
+
62
+ def positions_file_path
63
+ File.join(full_path,'positions.yml')
64
+ end
65
+
66
+ def positions
67
+ return @positions if !@positions.nil?
68
+ if File.exists?(positions_file_path)
69
+ @positions = YAML.load(File.read(positions_file_path))
70
+ else
71
+ nil
72
+ end
73
+ end
74
+
75
+ def meta_file_path
76
+ File.join(full_path,'meta.json')
77
+ end
78
+
79
+ def set_meta
80
+ meta_data = File.exists?(meta_file_path) ? File.read(meta_file_path) : false
81
+ write_attribute :meta, meta_data
82
+ meta_data
83
+ end
84
+
85
+ def set_correct_positions
86
+ positions.each_with_index do |file_name,i|
87
+ photo = photos.find_by_path("#{path}/#{file_name}")
88
+ photo_collection = children.find_by_path("#{path}/#{file_name}")
89
+ if photo
90
+ photo.insert_at i + 1
91
+ elsif photo_collection
92
+ photo_collection.insert_at i + 1
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,3 @@
1
+ class PhotoTag < ActiveRecord::Base
2
+ has_many :photos, :through => :photo_taggings
3
+ end
@@ -0,0 +1,4 @@
1
+ class PhotoTagging < ActiveRecord::Base
2
+ belongs_to :photo_tag
3
+ belongs_to :photo
4
+ end
data/photo_folder.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "photo_folder"
3
- s.version = "1.0.2"
3
+ s.version = "1.0.3"
4
4
  s.date = "2010-05-11"
5
5
  s.summary = "JavaScript gallery"
6
6
  s.email = "ryan@syntacticx.com"
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.files = [
12
12
  "README.markdown",
13
13
  "photo_folder.gemspec"] +
14
- Dir['lib/**/*'] +
14
+ Dir['models/**/*'] +
15
15
  Dir['vendor/**/*']
16
16
  s.autorequire = "lib/photo_folder.rb"
17
17
  s.add_dependency("sqlite3-ruby", ["> 0.0.0"])
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: photo_folder
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 2
10
- version: 1.0.2
9
+ - 3
10
+ version: 1.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Johnson
@@ -61,6 +61,10 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - README.markdown
63
63
  - photo_folder.gemspec
64
+ - models/photo.rb
65
+ - models/photo_collection.rb
66
+ - models/photo_tag.rb
67
+ - models/photo_tagging.rb
64
68
  - vendor/acts_as_list.rb
65
69
  - vendor/acts_as_tree.rb
66
70
  - vendor/mini_exiftool.rb