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.
- data/app/assets/javascripts/gb_application.js +34 -0
- data/app/assets/stylesheets/gb_admin-override.sass +17 -1
- data/app/controllers/gluttonberg/admin/asset_library/assets_controller.rb +4 -2
- data/app/controllers/gluttonberg/admin/content/articles_controller.rb +22 -22
- data/app/controllers/gluttonberg/admin/content/comments_controller.rb +80 -23
- data/app/controllers/gluttonberg/admin/main_controller.rb +1 -1
- data/app/controllers/gluttonberg/public/comments_controller.rb +9 -8
- data/app/helpers/gluttonberg/admin.rb +3 -3
- data/app/helpers/gluttonberg/asset_library.rb +14 -11
- data/app/models/gluttonberg/asset.rb +8 -6
- data/app/models/gluttonberg/comment.rb +57 -3
- data/app/models/gluttonberg/comment_subscription.rb +2 -0
- data/app/models/gluttonberg/setting.rb +11 -5
- data/app/views/gluttonberg/admin/asset_library/assets/_browser_root.html.haml +20 -3
- data/app/views/gluttonberg/admin/asset_library/assets/search.json.haml +1 -1
- data/app/views/gluttonberg/admin/content/comments/index.html.haml +36 -10
- data/app/views/gluttonberg/admin/content/main/_sidebar.html.haml +6 -3
- data/app/views/gluttonberg/admin/main/index.html.haml +4 -4
- data/app/views/gluttonberg/admin/settings/generic_settings/index.html.haml +11 -7
- data/config/routes.rb +10 -0
- data/db/migrate/20130201025800_spam_flag_for_comments.rb +6 -0
- data/lib/engine.rb +3 -2
- data/lib/generators/gluttonberg/installer/installer_generator.rb +33 -32
- data/lib/gluttonberg/content/block.rb +2 -0
- data/lib/gluttonberg/content/clean_html.rb +16 -14
- data/lib/gluttonberg/content/despamilator/conf/unusual_characters.txt +6674 -0
- data/lib/gluttonberg/content/despamilator/filter/emails.rb +49 -0
- data/lib/gluttonberg/content/despamilator/filter/gtubs_test_filter.rb +25 -0
- data/lib/gluttonberg/content/despamilator/filter/html_tags.rb +134 -0
- data/lib/gluttonberg/content/despamilator/filter/ip_address_url.rb +27 -0
- data/lib/gluttonberg/content/despamilator/filter/long_words.rb +29 -0
- data/lib/gluttonberg/content/despamilator/filter/mixed_case.rb +25 -0
- data/lib/gluttonberg/content/despamilator/filter/naughty_words.rb +80 -0
- data/lib/gluttonberg/content/despamilator/filter/no_vowels.rb +28 -0
- data/lib/gluttonberg/content/despamilator/filter/numbers_and_words.rb +55 -0
- data/lib/gluttonberg/content/despamilator/filter/obfuscated_urls.rb +45 -0
- data/lib/gluttonberg/content/despamilator/filter/prices.rb +23 -0
- data/lib/gluttonberg/content/despamilator/filter/script_tag.rb +25 -0
- data/lib/gluttonberg/content/despamilator/filter/shouting.rb +38 -0
- data/lib/gluttonberg/content/despamilator/filter/spammy_tlds.rb +26 -0
- data/lib/gluttonberg/content/despamilator/filter/square_brackets.rb +27 -0
- data/lib/gluttonberg/content/despamilator/filter/trailing_number.rb +25 -0
- data/lib/gluttonberg/content/despamilator/filter/unusual_characters.rb +51 -0
- data/lib/gluttonberg/content/despamilator/filter/urls.rb +45 -0
- data/lib/gluttonberg/content/despamilator/filter/very_long_domain_name.rb +31 -0
- data/lib/gluttonberg/content/despamilator/filter/weird_punctuation.rb +48 -0
- data/lib/gluttonberg/content/despamilator/filter.rb +57 -0
- data/lib/gluttonberg/content/despamilator/subject/text.rb +36 -0
- data/lib/gluttonberg/content/despamilator/subject.rb +34 -0
- data/lib/gluttonberg/content/despamilator/version.rb +7 -0
- data/lib/gluttonberg/content/despamilator.rb +79 -0
- data/lib/gluttonberg/content.rb +12 -11
- data/lib/gluttonberg/library/attachment_mixin.rb +52 -269
- data/lib/gluttonberg/library/config/image_sizes.rb +61 -0
- data/lib/gluttonberg/library/config.rb +10 -0
- data/lib/gluttonberg/library/processor/audio.rb +42 -0
- data/lib/gluttonberg/library/processor/image.rb +134 -0
- data/lib/gluttonberg/library/processor.rb +11 -0
- data/lib/gluttonberg/library/storage/filesystem.rb +76 -0
- data/lib/gluttonberg/library/storage/s3.rb +196 -0
- data/lib/gluttonberg/library/storage.rb +11 -0
- data/lib/gluttonberg/library.rb +87 -86
- data/lib/gluttonberg/record_history.rb +14 -15
- data/lib/gluttonberg/tasks/asset.rake +25 -3
- data/lib/gluttonberg/version.rb +1 -1
- 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
|
-
|
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
|
125
|
-
|
126
|
-
|
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
|
-
#
|
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
|
-
#
|
149
|
-
|
150
|
-
|
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
|
-
|
156
|
-
|
157
|
-
|
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
|
-
|
250
|
-
|
251
|
-
|
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
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
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
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
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,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
|