photo_folder 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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