gluttonberg-core 2.5.5 → 2.5.6

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.
Files changed (66) hide show
  1. data/app/assets/javascripts/gb_application.js +34 -0
  2. data/app/assets/stylesheets/gb_admin-override.sass +17 -1
  3. data/app/controllers/gluttonberg/admin/asset_library/assets_controller.rb +4 -2
  4. data/app/controllers/gluttonberg/admin/content/articles_controller.rb +22 -22
  5. data/app/controllers/gluttonberg/admin/content/comments_controller.rb +80 -23
  6. data/app/controllers/gluttonberg/admin/main_controller.rb +1 -1
  7. data/app/controllers/gluttonberg/public/comments_controller.rb +9 -8
  8. data/app/helpers/gluttonberg/admin.rb +3 -3
  9. data/app/helpers/gluttonberg/asset_library.rb +14 -11
  10. data/app/models/gluttonberg/asset.rb +8 -6
  11. data/app/models/gluttonberg/comment.rb +57 -3
  12. data/app/models/gluttonberg/comment_subscription.rb +2 -0
  13. data/app/models/gluttonberg/setting.rb +11 -5
  14. data/app/views/gluttonberg/admin/asset_library/assets/_browser_root.html.haml +20 -3
  15. data/app/views/gluttonberg/admin/asset_library/assets/search.json.haml +1 -1
  16. data/app/views/gluttonberg/admin/content/comments/index.html.haml +36 -10
  17. data/app/views/gluttonberg/admin/content/main/_sidebar.html.haml +6 -3
  18. data/app/views/gluttonberg/admin/main/index.html.haml +4 -4
  19. data/app/views/gluttonberg/admin/settings/generic_settings/index.html.haml +11 -7
  20. data/config/routes.rb +10 -0
  21. data/db/migrate/20130201025800_spam_flag_for_comments.rb +6 -0
  22. data/lib/engine.rb +3 -2
  23. data/lib/generators/gluttonberg/installer/installer_generator.rb +33 -32
  24. data/lib/gluttonberg/content/block.rb +2 -0
  25. data/lib/gluttonberg/content/clean_html.rb +16 -14
  26. data/lib/gluttonberg/content/despamilator/conf/unusual_characters.txt +6674 -0
  27. data/lib/gluttonberg/content/despamilator/filter/emails.rb +49 -0
  28. data/lib/gluttonberg/content/despamilator/filter/gtubs_test_filter.rb +25 -0
  29. data/lib/gluttonberg/content/despamilator/filter/html_tags.rb +134 -0
  30. data/lib/gluttonberg/content/despamilator/filter/ip_address_url.rb +27 -0
  31. data/lib/gluttonberg/content/despamilator/filter/long_words.rb +29 -0
  32. data/lib/gluttonberg/content/despamilator/filter/mixed_case.rb +25 -0
  33. data/lib/gluttonberg/content/despamilator/filter/naughty_words.rb +80 -0
  34. data/lib/gluttonberg/content/despamilator/filter/no_vowels.rb +28 -0
  35. data/lib/gluttonberg/content/despamilator/filter/numbers_and_words.rb +55 -0
  36. data/lib/gluttonberg/content/despamilator/filter/obfuscated_urls.rb +45 -0
  37. data/lib/gluttonberg/content/despamilator/filter/prices.rb +23 -0
  38. data/lib/gluttonberg/content/despamilator/filter/script_tag.rb +25 -0
  39. data/lib/gluttonberg/content/despamilator/filter/shouting.rb +38 -0
  40. data/lib/gluttonberg/content/despamilator/filter/spammy_tlds.rb +26 -0
  41. data/lib/gluttonberg/content/despamilator/filter/square_brackets.rb +27 -0
  42. data/lib/gluttonberg/content/despamilator/filter/trailing_number.rb +25 -0
  43. data/lib/gluttonberg/content/despamilator/filter/unusual_characters.rb +51 -0
  44. data/lib/gluttonberg/content/despamilator/filter/urls.rb +45 -0
  45. data/lib/gluttonberg/content/despamilator/filter/very_long_domain_name.rb +31 -0
  46. data/lib/gluttonberg/content/despamilator/filter/weird_punctuation.rb +48 -0
  47. data/lib/gluttonberg/content/despamilator/filter.rb +57 -0
  48. data/lib/gluttonberg/content/despamilator/subject/text.rb +36 -0
  49. data/lib/gluttonberg/content/despamilator/subject.rb +34 -0
  50. data/lib/gluttonberg/content/despamilator/version.rb +7 -0
  51. data/lib/gluttonberg/content/despamilator.rb +79 -0
  52. data/lib/gluttonberg/content.rb +12 -11
  53. data/lib/gluttonberg/library/attachment_mixin.rb +52 -269
  54. data/lib/gluttonberg/library/config/image_sizes.rb +61 -0
  55. data/lib/gluttonberg/library/config.rb +10 -0
  56. data/lib/gluttonberg/library/processor/audio.rb +42 -0
  57. data/lib/gluttonberg/library/processor/image.rb +134 -0
  58. data/lib/gluttonberg/library/processor.rb +11 -0
  59. data/lib/gluttonberg/library/storage/filesystem.rb +76 -0
  60. data/lib/gluttonberg/library/storage/s3.rb +196 -0
  61. data/lib/gluttonberg/library/storage.rb +11 -0
  62. data/lib/gluttonberg/library.rb +87 -86
  63. data/lib/gluttonberg/record_history.rb +14 -15
  64. data/lib/gluttonberg/tasks/asset.rake +25 -3
  65. data/lib/gluttonberg/version.rb +1 -1
  66. metadata +53 -2
@@ -6,35 +6,38 @@ module Gluttonberg
6
6
  # Asset class for each major category of assets e.g. ImageAsset,
7
7
  # DocumentAsset.
8
8
 
9
- require "mp3info"
10
-
11
9
  module AttachmentMixin
12
10
 
13
- # Default sizes used when thumbnailing an image.
14
- DEFAULT_THUMBNAILS = {
15
- :small_thumb => {:label => "Small Thumb", :filename => "_thumb_small", :geometry => "360x268#" },
16
- :large_thumb => {:label => "Large Thumb", :filename => "_thumb_large", :geometry => "360x268>"},
17
- :backend_logo => {:label => "Backend Logo", :filename => "_backend_logo", :geometry => "1000x30"}
18
- }
19
-
20
- # The default max image size. This can be overwritten on a per project
21
- # basis via the rails configuration.
22
- MAX_IMAGE_SIZE = "2000x2000>" #Resize image to have specified area in pixels. Aspect ratio is preserved.
23
-
24
11
  def self.included(klass)
25
12
  klass.class_eval do
26
-
27
- after_destroy :remove_file_from_disk
13
+ after_destroy :remove_file_from_storage
28
14
  before_save :generate_reference_hash
15
+ after_save :update_file_on_storage
16
+ attr_accessor :file_dirty
29
17
 
30
18
  extend ClassMethods
31
19
  include InstanceMethods
20
+ extend Library::Config::ImageSizes::ClassMethods
21
+ include Library::Config::ImageSizes::InstanceMethods
32
22
 
23
+ initialize_storage()
33
24
  end
34
25
  end
35
26
 
27
+
36
28
  module ClassMethods
37
29
 
30
+ def initialize_storage
31
+ storage_class_name = Rails.configuration.asset_storage.to_s.downcase.camelize
32
+ begin
33
+ storage_module = Gluttonberg::Library::Storage.const_get(storage_class_name)
34
+ rescue NameError
35
+ raise Exception, "Cannot load storage module '#{storage_class_name}'"
36
+ end
37
+ include(storage_module.const_get("InstanceMethods"))
38
+ extend(storage_module.const_get("ClassMethods"))
39
+ end
40
+
38
41
 
39
42
  # Generate auto titles for those assets without name
40
43
  def generate_name
@@ -47,24 +50,6 @@ module Gluttonberg
47
50
  'done' # this just makes the output nicer when running from slice -i
48
51
  end
49
52
 
50
- # Returns a collection of thumbnail definitions — sizes, filename etc. —
51
- # which is a merge of defaults and any custom thumbnails defined by the
52
- # user.
53
- def sizes
54
- @thumbnail_sizes ||= if Rails.configuration.thumbnails
55
- Rails.configuration.thumbnails.merge(DEFAULT_THUMBNAILS)
56
- else
57
- DEFAULT_THUMBNAILS
58
- end
59
- end
60
-
61
- # Returns the max image size as a hash containing :width and :height.
62
- # May be the default, or the value configured for a particular project.
63
- def max_image_size
64
- Rails.configuration.max_image_size || MAX_IMAGE_SIZE
65
- end
66
-
67
-
68
53
  end #ClassMethods
69
54
 
70
55
 
@@ -86,11 +71,11 @@ module Gluttonberg
86
71
  clean_filename = 'thumb.#{file_extension}'
87
72
  end
88
73
 
89
-
90
74
  self.mime_type = new_file.content_type
91
75
  self.file_name = clean_filename
92
76
  self.size = new_file.size
93
77
  @file = new_file
78
+ self.file_dirty = true
94
79
  end
95
80
  end
96
81
 
@@ -103,34 +88,18 @@ module Gluttonberg
103
88
  file_name.split(".").last
104
89
  end
105
90
 
106
- # Returns the public URL to this asset, relative to the domain.
107
- def url
108
- "/user_assets/#{asset_hash}/#{file_name}"
109
- end
110
-
111
91
  def asset_folder_path
112
- "/user_assets/#{asset_hash}"
92
+ # "/user_assets/#{asset_hash}"
93
+ directory
113
94
  end
114
95
 
115
- # Returns the URL for the specified image size.
116
-
117
- def url_for(name)
118
- if self.class.sizes.has_key? name
119
- filename = self.class.sizes[name][:filename]
120
- "/user_assets/#{asset_hash}/#{filename}.#{file_extension}"
121
- end
96
+ def asset_directory_public_url
97
+ "#{assets_directory_public_url}/#{asset_hash}"
122
98
  end
123
99
 
124
- # Returns the public URL to the asset’s small thumbnail relative
125
- # to the domain.
126
- def thumb_small_url
127
- url_for(:small_thumb) if category.downcase == "image"
128
- end
129
-
130
- # Returns the public URL to the asset’s large thumbnail — relative
131
- # to the domain.
132
- def thumb_large_url
133
- url_for(:large_thumb) if category.downcase == "image"
100
+ # Returns the public URL to this asset, relative to the domain.
101
+ def url
102
+ "#{asset_directory_public_url}/#{file_name}"
134
103
  end
135
104
 
136
105
  # Returns the full path to the file’s location on disk.
@@ -138,242 +107,56 @@ module Gluttonberg
138
107
  directory + "/" + file_name
139
108
  end
140
109
 
141
- # In the case where an uploaded image has been larger that the
142
- # specified max-size and consequently resized, this method will provide
143
- # the path to the original, un-altered file.
110
+ # asset path in actual assets directory
144
111
  def original_file_on_disk
145
112
  directory + "/original_" + file_name
146
113
  end
147
114
 
148
- # The generated directory where this file is located. If it is an image
149
- # it’s thumbnails will be stored here as well.
150
- def directory
151
- Library.setup
152
- Library.root + "/" + self.asset_hash
115
+ # Returns the full path to the file's location on disk in tmp directory.
116
+ def tmp_location_on_disk
117
+ tmp_directory + "/" + file_name
153
118
  end
154
119
 
155
- def suggested_measures(object , required_geometry)
156
- required_geometry = required_geometry.delete("#")
157
- required_geometry_tokens = required_geometry.split("x")
158
- actual_width = object.width.to_i
159
- actual_height = object.height.to_i
160
- required_width = required_geometry_tokens.first.to_i
161
- required_height = required_geometry_tokens.last.to_i
162
-
163
- ratio_required = required_width.to_f / required_height
164
- ratio_actual = actual_width.to_f / actual_height
165
-
166
- crossover_ratio = required_height.to_f / actual_height
167
- crossover_ratio2 = required_width.to_f / actual_width
168
-
169
- if(crossover_ratio < crossover_ratio2 )
170
- crossover_ratio = crossover_ratio2
171
- end
172
-
173
- projected_height = actual_height * crossover_ratio
174
-
175
- if(projected_height < required_height )
176
- required_width = required_width * (1 + (ratio_actual - ratio_required ) )
177
- end
178
- projected_width = actual_width * crossover_ratio
179
-
180
- "#{(projected_width).ceil}x#{(projected_width/ratio_actual).ceil}"
181
- end
182
-
183
- def generate_cropped_image(x , y , w , h, image_type)
184
-
185
- asset_thumb = self.asset_thumbnails.find(:first , :conditions => {:thumbnail_type => image_type.to_s })
186
- if asset_thumb.blank?
187
- asset_thumb = self.asset_thumbnails.create({:thumbnail_type => image_type.to_s , :user_generated => true })
188
- else
189
- asset_thumb.update_attributes(:user_generated => true)
190
- end
191
-
192
- path = original_file_on_disk
193
- original_ext = original_file_on_disk.split(".").last
194
- path = File.join(directory, "#{self.class.sizes[image_type.to_sym][:filename]}.#{file_extension}") unless image_type.blank?
195
- begin
196
- image = QuickMagick::Image.read(original_file_on_disk).first
197
- rescue
198
- image = QuickMagick::Image.read(original_file_on_disk).first
199
- end
200
- begin
201
- thumb_defined_width = self.class.sizes[image_type.to_sym][:geometry].split('x').first#.to_i
202
- scaling_percent = (thumb_defined_width.to_i/(w.to_i*1.0))*100
203
- image.arguments << " -crop #{w}x#{h}+#{x}+#{y} +repage"
204
- if scaling_percent != 1.0
205
- image.arguments << " -resize #{scaling_percent}%"
206
- end
207
- rescue => e
208
- puts e
209
- end
210
- image.save path
120
+ # asset full path in tmp directory
121
+ def tmp_original_file_on_disk
122
+ tmp_directory + "/original_" + file_name
211
123
  end
212
124
 
213
- # Create thumbnailed versions of image attachements.
214
- # TODO: generate thumbnails with the correct extension
215
- def generate_image_thumb
216
-
217
- begin
218
-
219
- self.class.sizes.each_pair do |name, config|
220
-
221
- asset_thumb = self.asset_thumbnails.find(:first , :conditions => {:thumbnail_type => name.to_s, :user_generated => true })
222
-
223
- if asset_thumb.blank?
224
- #image = QuickMagick::Image.read(location_on_disk).first
225
- begin
226
- image = QuickMagick::Image.read(original_file_on_disk).first
227
- rescue
228
- image = QuickMagick::Image.read(location_on_disk).first
229
- end
230
-
231
- original_ext = original_file_on_disk.split(".").last
232
-
233
- path = File.join(directory, "#{config[:filename]}.#{file_extension}")
234
- if config[:geometry].include?("#")
235
- #todo
236
- begin
237
- image.resize suggested_measures(image, config[:geometry])
238
- image.arguments << " -gravity Center -crop #{config[:geometry].delete("#")}+0+0 +repage"
239
- rescue => e
240
- puts e
241
- end
242
- else
243
- image.resize config[:geometry]
244
- end
245
- image.save path
246
- end
247
- end
248
125
 
249
- update_attribute( :custom_thumbnail , true)
250
- rescue => e
251
- update_attribute( :custom_thumbnail , false)
126
+ def generate_cropped_image(x , y , w , h, image_type)
127
+ if !File.exist?(self.tmp_location_on_disk) && !File.exist?(self.tmp_original_file_on_disk)
128
+ self.download_asset_to_tmp_file
252
129
  end
253
-
130
+ processor = Library::Processor::Image.new
131
+ processor.asset = self
132
+ processor.generate_cropped_image(x , y , w , h, image_type)
133
+ self.remove_file_from_tmp_storage
254
134
  end
255
135
 
256
- def generate_proper_resolution
257
-
258
- begin
259
- make_backup
260
- begin
261
- image = QuickMagick::Image.read(original_file_on_disk).first
262
- rescue => e
263
- image = QuickMagick::Image.read(location_on_disk).first
264
- end
265
-
266
- actual_width = image.width.to_i
267
- actual_height = image.height.to_i
268
-
269
- update_attributes( :width => actual_width ,:height => actual_height)
270
-
271
- image.resize self.class.max_image_size
272
- image.save File.join(directory, file_name)
273
- # remove mp3 info if any image have. it may happen in the case of updating asset from mp3 to image
274
- audio = AudioAssetAttribute.find( :first , :conditions => {:asset_id => asset.id})
275
- audio.destroy
276
- rescue #TypeError => error
277
- # ignore TypeErrors, just means it wasn't a supported image
278
- update_attribute( :custom_thumbnail , false)
279
- end
280
- end
281
-
282
-
283
- # Generates thumbnails for images, but also additionally checks to see
284
- #TODO if the uploaded image exceeds the specified maximum, in which case it will resize it down.
285
- def generate_thumb_and_proper_resolution(asset)
286
- asset.generate_proper_resolution
287
- asset.generate_image_thumb
288
- end
289
-
290
-
291
- #TODO Collect mp3 files info using Mp3Info gem
292
- def collect_mp3_info(asset)
293
- audio = AudioAssetAttribute.find( :first , :conditions => {:asset_id => asset.id})
294
-
295
- begin
296
- #open mp3 file
297
- Mp3Info.open(location_on_disk) do |mp3|
298
- if audio.blank?
299
- #, :genre => mp3.genre
300
- AudioAssetAttribute.create( :asset_id => asset.id , :length => mp3.length , :title => mp3.tag.title , :artist => mp3.tag.artist , :album => mp3.tag.album , :tracknum => mp3.tag.tracknum)
301
- else
302
- audio.update_attributes( {:length => mp3.length, :genre =>"" , :title => mp3.tag.title , :artist => mp3.tag.artist , :album => mp3.tag.album , :tracknum => mp3.tag.tracknum })
303
- end
304
-
305
- end
306
- if Gluttonberg::Setting.get_setting("audio_assets") == "Enable"
307
- Delayed::Job.enqueue AudioJob.new(asset.id)
308
- end
309
- rescue => detail
310
- # if exception occurs and asset has some attributes, then remove them.
311
- unless audio.blank?
312
- audio.update_attributes( {:length => nil , :title => nil , :artist => nil , :album => nil , :tracknum => nil })
313
- end
314
- end
315
-
316
- end
317
136
 
318
137
  def asset_processing
319
138
  asset_id_to_process = self.id
320
139
  asset = Asset.find(:first , :conditions => { :id => asset_id_to_process } )
321
140
  if asset
322
- #if it is an image, then create a thumbnail
323
- if asset.asset_type.asset_category.name == "image"
324
-
325
- generate_thumb_and_proper_resolution(asset)
326
- elsif asset.asset_type.asset_category.name == "audio"
327
- # If its mp3 file, collect its sound info
328
- puts "==========step1 - audio"
329
- collect_mp3_info(asset)
330
- puts "==========step last - audio"
331
- end
332
- #additional processing
333
- asset_processors = Rails.configuration.asset_processors
334
- unless asset_processors.blank?
335
- asset_processors.each do |processor|
336
- processor.process(asset)
337
- end
141
+ asset_processors = [Library::Processor::Image , Library::Processor::Audio] #Core processors
142
+ asset_processors << Rails.configuration.asset_processors unless Rails.configuration.asset_processors.blank? #additional processors
143
+ asset_processors = asset_processors.flatten
144
+ unless asset_processors.blank?
145
+ asset_processors.each do |processor|
146
+ processor.process(asset)
338
147
  end
339
-
148
+ end
340
149
  end
341
-
342
- end
150
+ end # asset_processing
343
151
 
344
152
 
345
153
  private
346
154
 
347
- def make_backup
348
- unless File.exist?(original_file_on_disk)
349
- FileUtils.cp location_on_disk, original_file_on_disk
350
- FileUtils.chmod(0755,original_file_on_disk)
351
- end
352
- end
353
-
354
-
355
- def remove_file_from_disk
356
- if File.exists?(directory)
357
- FileUtils.rm_r(directory)
358
- end
359
- end
360
-
361
- def update_file_on_disk
362
- if file
363
- FileUtils.mkdir(directory) unless File.exists?(directory)
364
- FileUtils.cp file.tempfile.path, location_on_disk
365
- FileUtils.chmod(0755, location_on_disk)
366
-
367
- # new file has been upload, if its image generate thumbnails, if mp3 collect sound info.
368
- asset_processing
369
- end
370
- end
371
-
372
- def generate_reference_hash
373
- unless self.asset_hash
374
- self.asset_hash = Digest::SHA1.hexdigest(Time.now.to_s + file_name)
155
+ def generate_reference_hash
156
+ unless self.asset_hash
157
+ self.asset_hash = Digest::SHA1.hexdigest(Time.now.to_s + file_name)
158
+ end
375
159
  end
376
- end
377
160
  end
378
161
  end # AttachmentMixin
379
162
  end #Library
@@ -0,0 +1,61 @@
1
+ module Gluttonberg
2
+ module Library
3
+ module Config
4
+ module ImageSizes
5
+
6
+ # Default sizes used when thumbnailing an image.
7
+ DEFAULT_THUMBNAILS = {
8
+ :small_thumb => {:label => "Small Thumb", :filename => "_thumb_small", :geometry => "360x268#" },
9
+ :large_thumb => {:label => "Large Thumb", :filename => "_thumb_large", :geometry => "360x268>"},
10
+ :backend_logo => {:label => "Backend Logo", :filename => "_backend_logo", :geometry => "1000x30"}
11
+ }
12
+
13
+ # The default max image size. This can be overwritten on a per project
14
+ # basis via the rails configuration.
15
+ MAX_IMAGE_SIZE = "2000x2000>" #Resize image to have specified area in pixels. Aspect ratio is preserved.
16
+
17
+ module ClassMethods
18
+ # Returns a collection of thumbnail definitions — sizes, filename etc. —
19
+ # which is a merge of defaults and any custom thumbnails defined by the
20
+ # user.
21
+ def sizes
22
+ @thumbnail_sizes ||= if Rails.configuration.thumbnails
23
+ Rails.configuration.thumbnails.merge(DEFAULT_THUMBNAILS)
24
+ else
25
+ DEFAULT_THUMBNAILS
26
+ end
27
+ end
28
+
29
+ # Returns the max image size as a hash containing :width and :height.
30
+ # May be the default, or the value configured for a particular project.
31
+ def max_image_size
32
+ Rails.configuration.max_image_size || MAX_IMAGE_SIZE
33
+ end
34
+
35
+ end #ClassMethods
36
+
37
+ module InstanceMethods
38
+ # Returns the URL for the specified image size.
39
+ def url_for(name)
40
+ if self.class.sizes.has_key? name
41
+ filename = self.class.sizes[name][:filename]
42
+ "#{asset_directory_public_url}/#{filename}.#{file_extension}"
43
+ end
44
+ end
45
+
46
+ # Returns the public URL to the asset’s small thumbnail — relative
47
+ # to the domain.
48
+ def thumb_small_url
49
+ url_for(:small_thumb) if category.downcase == "image"
50
+ end
51
+
52
+ # Returns the public URL to the asset’s large thumbnail — relative
53
+ # to the domain.
54
+ def thumb_large_url
55
+ url_for(:large_thumb) if category.downcase == "image"
56
+ end
57
+ end #InstanceMethods
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,10 @@
1
+ library = Pathname(__FILE__).dirname.expand_path
2
+ require File.join(library, "config", "image_sizes")
3
+
4
+
5
+ module Gluttonberg
6
+ module Library
7
+ module Config
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,42 @@
1
+ module Gluttonberg
2
+ module Library
3
+ module Processor
4
+ require "mp3info"
5
+ class Audio
6
+ attr_accessor :asset
7
+
8
+ def self.process(asset_obj)
9
+ if asset_obj.asset_type.asset_category.name == "audio"
10
+ collect_mp3_info(asset)
11
+ end
12
+ end
13
+
14
+ # Collect mp3 files info using Mp3Info gem
15
+ def collect_mp3_info(asset)
16
+ audio = AudioAssetAttribute.find( :first , :conditions => {:asset_id => asset.id})
17
+
18
+ begin
19
+ #open mp3 file
20
+ Mp3Info.open(location_on_disk) do |mp3|
21
+ if audio.blank?
22
+ AudioAssetAttribute.create( :asset_id => asset.id , :length => mp3.length , :title => mp3.tag.title , :artist => mp3.tag.artist , :album => mp3.tag.album , :tracknum => mp3.tag.tracknum)
23
+ else
24
+ audio.update_attributes( {:length => mp3.length, :genre =>"" , :title => mp3.tag.title , :artist => mp3.tag.artist , :album => mp3.tag.album , :tracknum => mp3.tag.tracknum })
25
+ end
26
+ end
27
+ if Gluttonberg::Setting.get_setting("audio_assets") == "Enable"
28
+ Delayed::Job.enqueue AudioJob.new(asset.id)
29
+ end
30
+ rescue => detail
31
+ # if exception occurs and asset has some attributes, then remove them.
32
+ unless audio.blank?
33
+ audio.update_attributes( {:length => nil , :title => nil , :artist => nil , :album => nil , :tracknum => nil })
34
+ end
35
+ end
36
+
37
+ end #collect_mp3_info
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,134 @@
1
+ module Gluttonberg
2
+ module Library
3
+ module Processor
4
+ class Image
5
+
6
+ attr_accessor :asset
7
+
8
+ def self.process(asset_obj)
9
+ if asset_obj.asset_type.asset_category.name == "image"
10
+ processor = self.new
11
+ processor.asset = asset_obj
12
+ processor.generate_thumb_and_proper_resolution
13
+ end
14
+ end
15
+
16
+ # Generates thumbnails for images, but also additionally checks to see
17
+ # if the uploaded image exceeds the specified maximum, in which case it will resize it down.
18
+ def generate_thumb_and_proper_resolution
19
+ generate_proper_resolution
20
+ generate_image_thumb
21
+ end
22
+
23
+ def suggested_measures(object , required_geometry)
24
+ required_geometry = required_geometry.delete("#")
25
+ required_geometry_tokens = required_geometry.split("x")
26
+ actual_width = object.width.to_i
27
+ actual_height = object.height.to_i
28
+ required_width = required_geometry_tokens.first.to_i
29
+ required_height = required_geometry_tokens.last.to_i
30
+
31
+ ratio_required = required_width.to_f / required_height
32
+ ratio_actual = actual_width.to_f / actual_height
33
+
34
+ crossover_ratio = required_height.to_f / actual_height
35
+ crossover_ratio2 = required_width.to_f / actual_width
36
+
37
+ if(crossover_ratio < crossover_ratio2 )
38
+ crossover_ratio = crossover_ratio2
39
+ end
40
+
41
+ projected_height = actual_height * crossover_ratio
42
+
43
+ if(projected_height < required_height )
44
+ required_width = required_width * (1 + (ratio_actual - ratio_required ) )
45
+ end
46
+ projected_width = actual_width * crossover_ratio
47
+
48
+ "#{(projected_width).ceil}x#{(projected_width/ratio_actual).ceil}"
49
+ end
50
+
51
+ def generate_cropped_image(x , y , w , h, image_type)
52
+ asset_thumb = asset.asset_thumbnails.find(:first , :conditions => {:thumbnail_type => image_type.to_s })
53
+ if asset_thumb.blank?
54
+ asset_thumb = asset.asset_thumbnails.create({:thumbnail_type => image_type.to_s , :user_generated => true })
55
+ else
56
+ asset_thumb.update_attributes(:user_generated => true)
57
+ end
58
+
59
+ file_name = "#{asset.class.sizes[image_type.to_sym][:filename]}.#{asset.file_extension}"
60
+ begin
61
+ image = QuickMagick::Image.read(asset.tmp_original_file_on_disk).first
62
+ rescue
63
+ image = QuickMagick::Image.read(asset.tmp_original_file_on_disk).first
64
+ end
65
+ thumb_defined_width = asset.class.sizes[image_type.to_sym][:geometry].split('x').first#.to_i
66
+ scaling_percent = (thumb_defined_width.to_i/(w.to_i*1.0))*100
67
+ image.arguments << " -crop #{w}x#{h}+#{x}+#{y} +repage"
68
+ if scaling_percent != 1.0
69
+ image.arguments << " -resize #{scaling_percent}%"
70
+ end
71
+ image.save File.join(asset.tmp_directory, file_name)
72
+ asset.move_tmp_file_to_actual_directory(file_name , true)
73
+ end
74
+
75
+ # Create thumbnailed versions of image attachements.
76
+ # TODO: generate thumbnails with the correct extension
77
+ def generate_image_thumb
78
+ asset.class.sizes.each_pair do |name, config|
79
+ asset_thumb = asset.asset_thumbnails.find(:first , :conditions => {:thumbnail_type => name.to_s, :user_generated => true })
80
+ if asset_thumb.blank?
81
+ begin
82
+ image = QuickMagick::Image.read(asset.tmp_original_file_on_disk).first
83
+ rescue
84
+ image = QuickMagick::Image.read(asset.tmp_location_on_disk).first
85
+ end
86
+
87
+ file_name = "#{config[:filename]}.#{asset.file_extension}"
88
+
89
+ if config[:geometry].include?("#")
90
+ #todo
91
+ begin
92
+ image.resize(suggested_measures(image, config[:geometry]))
93
+ image.arguments << " -gravity Center -crop #{config[:geometry].delete("#")}+0+0 +repage"
94
+ rescue => e
95
+ puts e
96
+ end
97
+ else
98
+ image.resize config[:geometry]
99
+ end
100
+ image.save File.join(asset.tmp_directory, file_name)
101
+ asset.move_tmp_file_to_actual_directory(file_name, true)
102
+ end # asset_thumb.blank?
103
+ end # sizes loop
104
+
105
+ asset.update_attribute(:custom_thumbnail , true)
106
+ end
107
+
108
+ def generate_proper_resolution
109
+ asset.make_backup
110
+ begin
111
+ image = QuickMagick::Image.read(asset.tmp_original_file_on_disk).first
112
+ rescue => e
113
+ image = QuickMagick::Image.read(asset.tmp_location_on_disk).first
114
+ end
115
+
116
+ actual_width = image.width.to_i
117
+ actual_height = image.height.to_i
118
+
119
+ asset.update_attributes( :width => actual_width ,:height => actual_height)
120
+
121
+ image.resize asset.class.max_image_size
122
+ image.save File.join(asset.tmp_directory, asset.file_name)
123
+ asset.move_tmp_file_to_actual_directory(asset.file_name , true)
124
+ # remove mp3 info if any image have. it may happen in the case of updating asset from mp3 to image
125
+ audio = AudioAssetAttribute.find( :first , :conditions => {:asset_id => asset.id})
126
+ audio.destroy unless audio.blank?
127
+ end
128
+
129
+
130
+
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,11 @@
1
+ library = Pathname(__FILE__).dirname.expand_path
2
+ require File.join(library, "processor", "image")
3
+ require File.join(library, "processor", "audio")
4
+
5
+
6
+ module Gluttonberg
7
+ module Library
8
+ module Processor
9
+ end
10
+ end
11
+ end