photo_folder 1.0.6 → 1.0.7

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/lib/models/photo.rb CHANGED
@@ -50,27 +50,52 @@ class Photo < ActiveRecord::Base
50
50
  end
51
51
 
52
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]
53
+ if full_path.match(/\.(png|jpg)$/)
54
+ if PhotoFolder.mini_exiftool_available?
55
+ set_exif_data_with_mini_exiftool
63
56
  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
57
+ set_exif_data_without_mini_exiftool
66
58
  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 = []
59
+ else
60
+ set_default_exif_data
61
+ end
62
+ end
63
+
64
+ def set_default_exif_data
65
+ self.height = 0
66
+ self.width = 0
67
+ @tags = []
68
+ end
69
+
70
+ def set_exif_data_with_mini_exiftool
71
+ exif = EXIFData.new(MiniExiftool.new(full_path),logger)
72
+ [:focal_length,:iso,:shutter_speed,:f_stop,:camera,:caption,:location,:height,:width].each do |key|
73
+ self.send(key.to_s + '=',exif[key] || nil)
74
+ end
75
+ #date,title,lens and tags are special cases
76
+ if exif[:date].is_a? Time
77
+ self.date = exif[:date]
78
+ else
79
+ date_match = (exif[:date] || '').match(/([\d]+):([\d]+):([\d]+) ([\d]+):([\d]+):([\d]+)/)
80
+ 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
81
+ end
82
+ self.name = exif[:title] || full_path.split('/').pop.gsub(/\.[a-zA-Z]{1,4}/,'')
83
+ self.lens = exif[:lens] ? exif[:lens] : nil
84
+ @tags = exif[:tags] || []
85
+ end
86
+
87
+ def set_exif_data_without_mini_exiftool
88
+ self.name = full_path.split('/').pop.gsub(/\.[a-zA-Z]{1,4}/,'')
89
+ if(full_path.match(/\.png$/))
90
+ width, height = File.read(full_path)[0x10..0x18].unpack('NN')
91
+ else
92
+ jpeg_meta_info = JPEGMetaInfo.new(full_path)
93
+ width = jpeg_meta_info.width
94
+ height = jpeg_meta_info.height
73
95
  end
96
+ self.width = width
97
+ self.height = height
98
+ @tags = []
74
99
  end
75
100
 
76
101
  class EXIFData
@@ -37,6 +37,23 @@ class PhotoCollection < ActiveRecord::Base
37
37
  end
38
38
  end
39
39
 
40
+ def self.title_card_path
41
+ File.join(PhotoFolder.source_directory_location,'index.markdown')
42
+ end
43
+
44
+ def self.add_title_card
45
+ if File.exists?(PhotoCollection.title_card_path)
46
+ truncated_title_card_path = title_card_path[PhotoFolder.source_directory_location.length + 1,title_card_path.length]
47
+ title_card = Photo.find_by_photo_collection_id_and_path(0,truncated_title_card_path) || Photo.create(
48
+ :photo_collection_id => 0,
49
+ :path => truncated_title_card_path
50
+ )
51
+ title_card.update_attribute :caption, Maruku.new(File.read(title_card_path)).to_html
52
+ else
53
+ false
54
+ end
55
+ end
56
+
40
57
  def set_children_parent_id
41
58
  PhotoFolder::all_paths_in_database.select{|path| self.path.underscore.gsub(/\s/,'_') == path.gsub(/\/[^\/]+$/,'').underscore.gsub(/\s/,'_')}.each do |path|
42
59
  Photo.update_all("photo_collection_id = #{self.id}","path = '#{path}'")
@@ -82,6 +99,21 @@ class PhotoCollection < ActiveRecord::Base
82
99
  meta_data
83
100
  end
84
101
 
102
+ def title_card_path
103
+ File.join(full_path,'index.markdown')
104
+ end
105
+
106
+ def add_title_card
107
+ if File.exists?(title_card_path)
108
+ truncated_title_card_path = title_card_path[PhotoFolder.source_directory_location.length + 1,title_card_path.length]
109
+ title_card = photos.find_by_path(truncated_title_card_path) || photos.create(:path => truncated_title_card_path)
110
+ title_card.update_attribute :caption, Maruku.new(File.read(title_card_path)).to_html
111
+ title_card.move_to_top
112
+ else
113
+ false
114
+ end
115
+ end
116
+
85
117
  def set_correct_positions
86
118
  positions.each_with_index do |file_name,i|
87
119
  photo = photos.find_by_path("#{path}/#{file_name}")
@@ -93,4 +125,4 @@ class PhotoCollection < ActiveRecord::Base
93
125
  end
94
126
  end
95
127
  end
96
- end
128
+ end
data/lib/photo_folder.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'rubygems'
3
3
  gem 'sqlite3-ruby'
4
4
  gem 'activerecord'
5
+ gem 'maruku'
5
6
  require 'active_record'
6
7
  require 'fileutils'
7
8
  require 'tempfile'
@@ -10,12 +11,14 @@ require 'set'
10
11
  require 'ftools'
11
12
  require 'digest/md5'
12
13
  require 'yaml'
14
+ require 'maruku'
13
15
 
14
16
  #internal libraries
15
17
  current_dir = File.expand_path(File.dirname(__FILE__))
16
18
  require File.join(current_dir,'..','vendor','acts_as_tree.rb')
17
19
  require File.join(current_dir,'..','vendor','acts_as_list.rb')
18
20
  require File.join(current_dir,'..','vendor','mini_exiftool.rb')
21
+ require File.join(current_dir,'..','vendor','jpeg_meta_info.rb')
19
22
  require File.join(current_dir,'models','photo.rb')
20
23
  require File.join(current_dir,'models','photo_tag.rb')
21
24
  require File.join(current_dir,'models','photo_tagging.rb')
@@ -30,16 +33,16 @@ unless Numeric.instance_methods.include? 'to_a'
30
33
  end
31
34
 
32
35
  module PhotoFolder
33
- def self.setup_database(database_location)
36
+ def self.establish_database_connection(database_location)
34
37
  ActiveRecord::Base.establish_connection(
35
38
  :adapter => "sqlite3",
36
39
  :database => database_location,
37
40
  :timeout => 5000
38
41
  )
39
- PhotoFolder::create_schema
40
42
  end
41
43
 
42
44
  def self.create_schema
45
+ schema_created = false
43
46
  if !Photo.table_exists?
44
47
  ActiveRecord::Base.connection.create_table("photos") do |t|
45
48
  t.integer "photo_collection_id"
@@ -62,6 +65,7 @@ module PhotoFolder
62
65
  t.integer "nsfw"
63
66
  t.integer "featured"
64
67
  end
68
+ schema_created = true
65
69
  end
66
70
 
67
71
  if !PhotoCollection.table_exists?
@@ -72,12 +76,14 @@ module PhotoFolder
72
76
  t.integer "position"
73
77
  t.text "meta"
74
78
  end
79
+ schema_created = true
75
80
  end
76
81
 
77
82
  if !PhotoTag.table_exists?
78
83
  ActiveRecord::Base.connection.create_table("photo_tags") do |t|
79
84
  t.string "tag"
80
85
  end
86
+ schema_created = true
81
87
  end
82
88
 
83
89
  if !PhotoTagging.table_exists?
@@ -85,12 +91,15 @@ module PhotoFolder
85
91
  t.integer "photo_tag_id"
86
92
  t.integer "photo_id"
87
93
  end
94
+ schema_created = true
88
95
  end
96
+
97
+ schema_created
89
98
  end
90
99
 
91
100
  def self.photos_list
92
101
  return @photos_list if !@photos_list.nil?
93
- @photos_list = Dir[PhotoFolder.source_directory_location + '/**/*.{png,jpg}']
102
+ @photos_list = Dir[PhotoFolder.source_directory_location + '/**/*.{png,jpg,markdown}']
94
103
  end
95
104
 
96
105
  def self.all_paths_in_database
@@ -138,6 +147,9 @@ module PhotoFolder
138
147
 
139
148
  to_add.reject!{|item| to_update.include?(item)}
140
149
 
150
+ to_add.reject!{|item| item.match(/index\.markdown$/)}
151
+ to_update.reject!{|item| item.match(/index\.markdown$/)}
152
+
141
153
  [to_add,to_update,to_remove]
142
154
  end
143
155
 
@@ -199,21 +211,30 @@ module PhotoFolder
199
211
  @source_directory_location
200
212
  end
201
213
 
214
+ def self.mini_exiftool_available?
215
+ @mini_exiftool_available
216
+ end
217
+
202
218
  def self.generate(source_directory_location,database_location,json_location,include_nsfw = false,exif_tool_location = 'exiftool')
203
219
  Photo.send(:with_scope, :find => {:conditions => include_nsfw ? "nsfw = 1 OR nsfw = 0" : "nsfw = 0"}) do
220
+ puts "PhotoFolder Database Generator"
221
+ puts "=============================="
204
222
 
205
223
  @source_directory_location = source_directory_location
206
224
 
207
225
  begin
208
226
  MiniExiftool.configure(exif_tool_location)
227
+ @mini_exiftool_available = true
209
228
  rescue
229
+ @mini_exiftool_available = false
210
230
  puts "WARNING: Could not configure MiniExifTool, EXIF data will not be parsed."
211
231
  end
212
232
 
213
- puts "PhotoFolder Database Generator"
214
- puts "=============================="
233
+ PhotoFolder::establish_database_connection(database_location)
234
+ if PhotoFolder::create_schema
235
+ puts "Generated schema in #{database_location}"
236
+ end
215
237
 
216
- PhotoFolder::setup_database(database_location)
217
238
  photos_list = PhotoFolder::photos_list
218
239
  puts "Scanning #{photos_list.length} photos in #{source_directory_location}"
219
240
 
@@ -278,6 +299,9 @@ module PhotoFolder
278
299
  if PhotoCollection.positions
279
300
  puts "Setting positions for root collections from #{PhotoCollection.positions_file_path}"
280
301
  end
302
+ if PhotoCollection.add_title_card
303
+ puts "Adding title card to root from #{PhotoCollection.title_card_path}"
304
+ end
281
305
  PhotoCollection.set_correct_positions(PhotoCollection.find_all_by_parent_id(0))
282
306
  PhotoCollection.find(:all).each do |photo_collection|
283
307
  if photo_collection.positions
@@ -287,6 +311,9 @@ module PhotoFolder
287
311
  if photo_collection.set_meta
288
312
  puts "Setting meta data for #{photo_collection.name} from #{photo_collection.meta_file_path}"
289
313
  end
314
+ if photo_collection.add_title_card
315
+ puts "Adding title card to #{photo_collection.name} from #{photo_collection.title_card_path}"
316
+ end
290
317
  end
291
318
  end
292
319
 
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.6"
3
+ s.version = "1.0.7"
4
4
  s.date = "2010-05-11"
5
5
  s.summary = "JavaScript gallery"
6
6
  s.email = "ryan@syntacticx.com"
@@ -15,4 +15,5 @@ Gem::Specification.new do |s|
15
15
  Dir['vendor/**/*']
16
16
  s.add_dependency("sqlite3-ruby", ["> 0.0.0"])
17
17
  s.add_dependency("activerecord", ["> 0.0.0"])
18
+ s.add_dependency("maruku", ["> 0.0.0"])
18
19
  end
@@ -0,0 +1,39 @@
1
+ class JPEGMetaInfo
2
+ attr_reader :width, :height, :bits
3
+
4
+ def initialize(file)
5
+ if file.kind_of? IO
6
+ examine(file)
7
+ else
8
+ File.open(file, 'rb') { |io| examine(io) }
9
+ end
10
+ end
11
+
12
+ private
13
+ def examine(io)
14
+ raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
15
+
16
+ class << io
17
+ def readint; (readchar << 8) + readchar; end
18
+ def readframe; read(readint - 2); end
19
+ def readsof; [readint, readchar, readint, readint, readchar]; end
20
+ def next
21
+ c = readchar while c != 0xFF
22
+ c = readchar while c == 0xFF
23
+ c
24
+ end
25
+ end
26
+
27
+ while marker = io.next
28
+ case marker
29
+ when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
30
+ length, @bits, @height, @width, components = io.readsof
31
+ raise 'malformed JPEG' unless length == 8 + components * 3
32
+ when 0xD9, 0xDA: break # EOI, SOS
33
+ when 0xFE: @comment = io.readframe # COM
34
+ when 0xE1: io.readframe # APP1, contains EXIF tag
35
+ else io.readframe # ignore frame
36
+ end
37
+ end
38
+ end
39
+ end
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 6
10
- version: 1.0.6
9
+ - 7
10
+ version: 1.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Johnson
@@ -50,6 +50,22 @@ dependencies:
50
50
  version: 0.0.0
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: maruku
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">"
60
+ - !ruby/object:Gem::Version
61
+ hash: 31
62
+ segments:
63
+ - 0
64
+ - 0
65
+ - 0
66
+ version: 0.0.0
67
+ type: :runtime
68
+ version_requirements: *id003
53
69
  description: JavaScript gallery
54
70
  email: ryan@syntacticx.com
55
71
  executables: []
@@ -68,6 +84,7 @@ files:
68
84
  - lib/photo_folder.rb
69
85
  - vendor/acts_as_list.rb
70
86
  - vendor/acts_as_tree.rb
87
+ - vendor/jpeg_meta_info.rb
71
88
  - vendor/mini_exiftool.rb
72
89
  has_rdoc: true
73
90
  homepage: http://photofolder.org/