photo_folder 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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/