cloudhdr_rails 0.0.1
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/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/cloudhdr/updater.js +115 -0
- data/app/assets/stylesheets/cloudhdr/updater.css +8 -0
- data/app/controllers/cloudhdr_controller.rb +64 -0
- data/app/helpers/cloudhdr_helper.rb +245 -0
- data/app/models/cloudhdr_job.rb +189 -0
- data/app/views/cloudhdr/_thumbnail_update.html.erb +3 -0
- data/app/views/cloudhdr/multi_thumbnail_update.json.erb +7 -0
- data/app/views/cloudhdr/thumbnail_update.js.erb +1 -0
- data/config/routes.rb +8 -0
- data/lib/cloudhdr_rails/acts_as_cloudhdr.rb +1020 -0
- data/lib/cloudhdr_rails/engine.rb +4 -0
- data/lib/cloudhdr_rails/errors.rb +46 -0
- data/lib/cloudhdr_rails/version.rb +3 -0
- data/lib/cloudhdr_rails.rb +7 -0
- data/lib/generators/cloudhdr_rails/model_update_generator.rb +52 -0
- data/lib/generators/cloudhdr_rails/scaffold_generator.rb +94 -0
- data/lib/generators/cloudhdr_rails/setup_generator.rb +33 -0
- data/lib/generators/cloudhdr_rails/templates/cloudhdr.yml +19 -0
- data/lib/generators/cloudhdr_rails/templates/controller.rb +71 -0
- data/lib/generators/cloudhdr_rails/templates/helper.rb +5 -0
- data/lib/generators/cloudhdr_rails/templates/migration.rb +21 -0
- data/lib/generators/cloudhdr_rails/templates/model.rb +15 -0
- data/lib/generators/cloudhdr_rails/templates/model_migration.rb +56 -0
- data/lib/generators/cloudhdr_rails/templates/model_thumbnail.rb +5 -0
- data/lib/generators/cloudhdr_rails/templates/model_update_migration.rb +64 -0
- data/lib/generators/cloudhdr_rails/templates/views/_form.html.erb.tt +23 -0
- data/lib/generators/cloudhdr_rails/templates/views/index.html.erb.tt +26 -0
- data/lib/generators/cloudhdr_rails/templates/views/new.html.erb.tt +5 -0
- data/lib/generators/cloudhdr_rails/templates/views/show.html.erb.tt +12 -0
- data/lib/tasks/cloudhdr_rails_tasks.rake +19 -0
- metadata +212 -0
@@ -0,0 +1,1020 @@
|
|
1
|
+
module ActsAsCloudhdr
|
2
|
+
|
3
|
+
require 'cloudhdr'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'aws-sdk'
|
6
|
+
require 'mimetype_fu'
|
7
|
+
# Storeage mode controls how uploads are handled.
|
8
|
+
# Valid options are:
|
9
|
+
# offline : For development mode with no net connection. No processing.
|
10
|
+
# local : To store images locally but use Cloudhdr for processing.
|
11
|
+
# s3 : Store image in S3 and use Cloudhdr for processing.
|
12
|
+
# Set this options either in evnironment.rb or
|
13
|
+
# in environments/development.rb etc...
|
14
|
+
|
15
|
+
mattr_accessor :storeage_mode
|
16
|
+
self.storeage_mode = "local"
|
17
|
+
|
18
|
+
|
19
|
+
# Processing mode controls when images get sent to cloudhdr
|
20
|
+
# Valid options are:
|
21
|
+
# automatic : Send to cloudhdr as soon as the file is stored.
|
22
|
+
# With 'local' storage mode, this submits the job
|
23
|
+
# to cloudhdr while the user is still waiting.
|
24
|
+
# delayed : Handle storage/processing in a background process.
|
25
|
+
mattr_accessor :processing_mode
|
26
|
+
self.processing_mode = "automatic"
|
27
|
+
|
28
|
+
# This is used as the base address for cloudhdr notifications.
|
29
|
+
# When storeage_mode == "local" this is also used to point
|
30
|
+
# cloudhdr at the file.
|
31
|
+
# It should only be the host.domain portion of the URL
|
32
|
+
# no path components.
|
33
|
+
mattr_accessor :base_url
|
34
|
+
self.base_url = "http://your-domain.com"
|
35
|
+
|
36
|
+
# The bucket for storing s3 files
|
37
|
+
mattr_accessor :s3_bucket_name
|
38
|
+
self.s3_bucket_name = "your-bucket"
|
39
|
+
|
40
|
+
# The cloudfront host or a Proc that returns a cloud front host
|
41
|
+
mattr_accessor :cloudfront_host
|
42
|
+
self.cloudfront_host = nil
|
43
|
+
|
44
|
+
# The javascript library to use for updates
|
45
|
+
# either 'prototype' or 'jquery'
|
46
|
+
mattr_accessor :javascript_library
|
47
|
+
self.javascript_library = 'prototype'
|
48
|
+
|
49
|
+
# The local directory where files should be stored
|
50
|
+
mattr_accessor :local_base_dir
|
51
|
+
self.local_base_dir = '/tmp'
|
52
|
+
|
53
|
+
# The config file that tells cloudhdr where to find
|
54
|
+
# config options.
|
55
|
+
mattr_accessor :config_file
|
56
|
+
self.config_file = "config/cloudhdr.yml"
|
57
|
+
|
58
|
+
# The actual configuration parameters
|
59
|
+
mattr_accessor :config
|
60
|
+
self.config = nil
|
61
|
+
|
62
|
+
def self.cloudhdr_config
|
63
|
+
#puts "checking cloudhdr_config for #{self.config}"
|
64
|
+
self.read_cloudhdr_configuration if self.config.nil?
|
65
|
+
self.config
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.read_cloudhdr_configuration
|
69
|
+
|
70
|
+
config_path = File.join(::Rails.root.to_s, ActsAsCloudhdr.config_file)
|
71
|
+
#puts "#{self.config} - looking for a config in #{config_path}"
|
72
|
+
self.config = YAML.load(ERB.new(File.read(config_path)).result)[::Rails.env.to_s].symbolize_keys
|
73
|
+
self.apply_cloudhdr_configuration
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# The list of image content types that are considered web safe
|
78
|
+
# These can be displayed directly, skipping processing if in offline mode
|
79
|
+
mattr_accessor :web_safe_image_types
|
80
|
+
self.web_safe_image_types = [
|
81
|
+
'image/jpeg',
|
82
|
+
'image/jpg',
|
83
|
+
'image/gif',
|
84
|
+
'image/png',
|
85
|
+
'image/x-png',
|
86
|
+
'image/jpg',
|
87
|
+
'application/png',
|
88
|
+
'application/x-png'
|
89
|
+
]
|
90
|
+
|
91
|
+
# The list of image content types that are not considered web safe
|
92
|
+
# These can not be displayed directly
|
93
|
+
mattr_accessor :other_image_types
|
94
|
+
self.other_image_types = [
|
95
|
+
'image/pjpeg',
|
96
|
+
'image/x-ms-bmp',
|
97
|
+
'image/bmp',
|
98
|
+
'image/x-bmp',
|
99
|
+
'image/x-bitmap',
|
100
|
+
'image/x-xbitmap',
|
101
|
+
'image/x-win-bitmap',
|
102
|
+
'image/x-windows-bmp',
|
103
|
+
'image/ms-bmp',
|
104
|
+
'application/bmp',
|
105
|
+
'application/x-bmp',
|
106
|
+
'application/x-win-bitmap',
|
107
|
+
'application/preview',
|
108
|
+
'image/jp_',
|
109
|
+
'application/jpg',
|
110
|
+
'application/x-jpg',
|
111
|
+
'image/pipeg',
|
112
|
+
'image/vnd.swiftview-jpeg',
|
113
|
+
'image/x-xbitmap',
|
114
|
+
'image/gi_',
|
115
|
+
'image/x-citrix-pjpeg',
|
116
|
+
'image/x-nikon-nef',
|
117
|
+
'image/tiff',
|
118
|
+
'image/x-olympus-orf',
|
119
|
+
'image/x-dcraw',
|
120
|
+
'image/x-adobe-dng'
|
121
|
+
]
|
122
|
+
|
123
|
+
# The list of content types that will trigger image handling.
|
124
|
+
def image_types
|
125
|
+
web_safe_image_types + other_image_types
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
# TODO : This needs to be fixed.
|
130
|
+
# It currently matches anything with an 'x' in it
|
131
|
+
mattr_accessor :label_size_regex
|
132
|
+
self.label_size_regex = /(\d*)x(\d*)(pad|crop|stretch|preserve)?/ #
|
133
|
+
|
134
|
+
mattr_accessor :size_string_regex
|
135
|
+
self.size_string_regex = /(\d*)x(\d*)([!>]?)/
|
136
|
+
|
137
|
+
def image?(content_type)
|
138
|
+
image_types.include?(content_type)
|
139
|
+
end
|
140
|
+
|
141
|
+
def web_safe?(content_type)
|
142
|
+
web_safe_image_types.include?(content_type)
|
143
|
+
end
|
144
|
+
|
145
|
+
#def self.storeage_mode
|
146
|
+
# @@storeage_mode
|
147
|
+
#end
|
148
|
+
|
149
|
+
|
150
|
+
def acts_as_cloudhdr(options = { })
|
151
|
+
|
152
|
+
include InstanceMethods
|
153
|
+
attr_reader :saved_file
|
154
|
+
attr_accessor :processing
|
155
|
+
after_save :save_local_file
|
156
|
+
before_destroy :cleanup #:remove_local_file,:destroy_thumbnails,:remove_s3_file
|
157
|
+
|
158
|
+
include ActiveSupport::Callbacks
|
159
|
+
|
160
|
+
define_callbacks :local_file_saved, :file_saved, :file_ready, :process_hdr, :process_hdrhtml, :process_composite, :process_tone_mapping
|
161
|
+
|
162
|
+
#cattr_accessor :cloudhdr_options
|
163
|
+
#self.cloudhdr_options = options
|
164
|
+
|
165
|
+
cattr_accessor :cloudhdr_thumbnails
|
166
|
+
self.cloudhdr_thumbnails = options[:thumbnails] ||= []
|
167
|
+
|
168
|
+
cattr_accessor :thumbnail_class
|
169
|
+
self.thumbnail_class = options[:thumbnail_class] ? options[:thumbnail_class].constantize : self
|
170
|
+
|
171
|
+
cattr_accessor :parent_class
|
172
|
+
self.parent_class = options[:parent_class] ? options[:parent_class].constantize : self
|
173
|
+
|
174
|
+
has_many :thumbnails, :class_name => "::#{self.thumbnail_class.name}",:as => :parent
|
175
|
+
if self.thumbnail_class != self.parent_class
|
176
|
+
#we have to do this to get the poster for videos covered
|
177
|
+
belongs_to :parent, :polymorphic => true
|
178
|
+
else
|
179
|
+
belongs_to :parent, :class_name => "::#{self.parent_class.name}" ,:foreign_key => "parent_id"
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
has_many :cloudhdr_jobs, :as => :image
|
184
|
+
|
185
|
+
scope :top_level, where({:parent_id=>nil}) if respond_to?(:parent_id)
|
186
|
+
scope :top_level, where({}) if !respond_to?(:parent_id)
|
187
|
+
# we can't just call this next scope 'parents' because that is already
|
188
|
+
# taken and returns an array of parent classes of the ruby object
|
189
|
+
scope :parent_items, where({:parent_id=>nil}) if respond_to?(:parent_id)
|
190
|
+
scope :parent_items, where({}) if !respond_to?(:parent_id)
|
191
|
+
|
192
|
+
scope :thumbnails, where("#{base_class.table_name}.parent_id is not null")
|
193
|
+
|
194
|
+
#just a writer, the reader is below
|
195
|
+
#cattr_accessor :cloudhdr_configuration
|
196
|
+
#read_cloudhdr_configuration
|
197
|
+
end
|
198
|
+
|
199
|
+
#def config
|
200
|
+
#return cloudhdr_configuration if !cloudhdr_configuration.blank?
|
201
|
+
#self.read_cloudhdr_configuration
|
202
|
+
#end
|
203
|
+
|
204
|
+
def validates_cloudhdr
|
205
|
+
validates_presence_of :content_type, :filename, :if=>lambda{ parent_id.blank? }
|
206
|
+
end
|
207
|
+
|
208
|
+
def update_from_cloudhdr(params)
|
209
|
+
Rails.logger.debug "tying to call update from cloudhdr for params = #{params.to_json}"
|
210
|
+
if !params[:output].blank?
|
211
|
+
Rails.logger.debug "find_by_cloudhdr_output_id #{params[:output][:id]}"
|
212
|
+
iu = find_by_cloudhdr_output_id params[:output][:id]
|
213
|
+
Rails.logger.debug "the item = #{iu}"
|
214
|
+
img_params = params[:output]
|
215
|
+
iu.filename = File.basename(params[:output][:url]) #if iu.filename.blank?
|
216
|
+
if ActsAsCloudhdr.storeage_mode == "local"
|
217
|
+
iu.save_url(params[:output][:url])
|
218
|
+
end
|
219
|
+
else
|
220
|
+
iu = find_by_cloudhdr_input_id params[:input][:id]
|
221
|
+
img_params = params[:input]
|
222
|
+
end
|
223
|
+
[:file_size,:width,:height,:taken_at,:lat,:lng].each do |att|
|
224
|
+
setter = att.to_s + "="
|
225
|
+
if iu.respond_to? setter and !img_params[att].blank?
|
226
|
+
iu.send setter, img_params[att]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
#iu.file_size = img_params[:file_size]
|
231
|
+
#iu.width = img_params[:width]
|
232
|
+
#iu.height = img_params[:height]
|
233
|
+
iu.cloudhdr_status = "ready"
|
234
|
+
iu.save
|
235
|
+
iu
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
def thumbnail_attributes_for(thumbnail_name = "small")
|
241
|
+
atts = self.cloudhdr_thumbnails.select{|atts| atts[:label] == thumbnail_name }.first
|
242
|
+
if atts.blank?
|
243
|
+
atts = create_atts_from_size_string(thumbnail_name)
|
244
|
+
end
|
245
|
+
if atts.blank?
|
246
|
+
raise ThumbnailAttributesNotFoundError.new("No thumbnail attributes were found for label '#{thumbnail_name}'")
|
247
|
+
end
|
248
|
+
atts
|
249
|
+
end
|
250
|
+
|
251
|
+
def create_label_from_size_string(size_string)
|
252
|
+
if size_string.match ActsAsCloudhdr.size_string_regex
|
253
|
+
size_string = size_string.gsub("!","crop")
|
254
|
+
size_string = size_string.gsub(">","preserve")
|
255
|
+
end
|
256
|
+
size_string
|
257
|
+
end
|
258
|
+
|
259
|
+
def create_atts_from_size_string(label_string)
|
260
|
+
match = label_string.match ActsAsCloudhdr.label_size_regex
|
261
|
+
return nil if match.blank?
|
262
|
+
atts = {}
|
263
|
+
if !match[1].blank?
|
264
|
+
atts[:width] = match[1]
|
265
|
+
end
|
266
|
+
if !match[2].blank?
|
267
|
+
atts[:height] = match[2]
|
268
|
+
end
|
269
|
+
if !match[3].blank?
|
270
|
+
atts[:aspect_mode] = match[3]
|
271
|
+
end
|
272
|
+
atts[:label] = label_string
|
273
|
+
#atts[:label] = "#{atts[:width]}x#{atts[:height]}"
|
274
|
+
#atts[:label] += "_#{atts[:aspect_mode]}" if atts[:aspect_mode]
|
275
|
+
atts
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
#def read_cloudhdr_configuration
|
280
|
+
##raise "This method is going away!"
|
281
|
+
##puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
282
|
+
##puts "This method is going away!"
|
283
|
+
##puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
284
|
+
#self.cloudhdr_configuration = ActsAsCloudhdr.cloudhdr_config
|
285
|
+
#self.apply_cloudhdr_configuration
|
286
|
+
#end
|
287
|
+
|
288
|
+
|
289
|
+
def self.cloudhdr_configuration
|
290
|
+
self.config
|
291
|
+
end
|
292
|
+
|
293
|
+
def self.apply_cloudhdr_configuration
|
294
|
+
if self.cloudhdr_configuration[:base_url]
|
295
|
+
ActsAsCloudhdr.base_url = cloudhdr_configuration[:base_url]
|
296
|
+
end
|
297
|
+
if self.cloudhdr_configuration[:storeage_mode]
|
298
|
+
ActsAsCloudhdr.storeage_mode = cloudhdr_configuration[:storeage_mode]
|
299
|
+
end
|
300
|
+
if self.cloudhdr_configuration[:processing_mode]
|
301
|
+
ActsAsCloudhdr.processing_mode = cloudhdr_configuration[:processing_mode]
|
302
|
+
end
|
303
|
+
if self.cloudhdr_configuration[:s3_bucket_name]
|
304
|
+
ActsAsCloudhdr.s3_bucket_name = cloudhdr_configuration[:s3_bucket_name]
|
305
|
+
end
|
306
|
+
if self.cloudhdr_configuration[:javascript_library]
|
307
|
+
ActsAsCloudhdr.javascript_library = cloudhdr_configuration[:javascript_library]
|
308
|
+
end
|
309
|
+
if self.cloudhdr_configuration[:local_base_dir]
|
310
|
+
ActsAsCloudhdr.local_base_dir = cloudhdr_configuration[:local_base_dir]
|
311
|
+
end
|
312
|
+
|
313
|
+
if self.cloudhdr_configuration[:cloudhdr_url]
|
314
|
+
::Cloudhdr.base_url = cloudhdr_configuration[:cloudhdr_url]
|
315
|
+
end
|
316
|
+
if self.cloudhdr_configuration[:cloudhdr_api_key]
|
317
|
+
::Cloudhdr.api_key = cloudhdr_configuration[:cloudhdr_api_key]
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
module InstanceMethods
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
def image?
|
333
|
+
self.class.image?(content_type)
|
334
|
+
end
|
335
|
+
|
336
|
+
def web_safe?
|
337
|
+
self.class.web_safe?(content_type)
|
338
|
+
end
|
339
|
+
|
340
|
+
def encode
|
341
|
+
if image?
|
342
|
+
process
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def recode
|
347
|
+
reload #make sure that we have current thumbs
|
348
|
+
destroy_thumbnails
|
349
|
+
reload
|
350
|
+
encode
|
351
|
+
end
|
352
|
+
|
353
|
+
def ready?
|
354
|
+
if ActsAsCloudhdr.storeage_mode == "offline"
|
355
|
+
true
|
356
|
+
#elsif image?
|
357
|
+
# return cloudhdr_status=='ready'
|
358
|
+
#else
|
359
|
+
# return false
|
360
|
+
else
|
361
|
+
return cloudhdr_status == "ready"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def error?
|
366
|
+
if ActsAsCloudhdr.storeage_mode == "offline"
|
367
|
+
false
|
368
|
+
#elsif image?
|
369
|
+
# return cloudhdr_status=='failed'
|
370
|
+
#elsif video?
|
371
|
+
# return zencoder_status=='failed'
|
372
|
+
#else
|
373
|
+
# true
|
374
|
+
else
|
375
|
+
return cloudhdr_status == "ready"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def create_thumbnails_from_response(response_thumbs,job_id)
|
380
|
+
new_thumbs = []
|
381
|
+
response_thumbs.each do |thumb_params|
|
382
|
+
#puts "creating a thumb for #{thumb_params["label"]}"
|
383
|
+
# we do this the long way around just in case some of these
|
384
|
+
# atts are attr_protected
|
385
|
+
thumb = nil
|
386
|
+
if respond_to?(:parent_id) and !self.parent_id.blank?
|
387
|
+
Rails.logger.debug "trying to create a thumb from the parent "
|
388
|
+
thumb = self.parent.thumbnails.new()
|
389
|
+
self.parent.thumbnails << thumb
|
390
|
+
else
|
391
|
+
Rails.logger.debug "trying to create a thumb from myself "
|
392
|
+
thumb = self.thumbnails.new()
|
393
|
+
self.thumbnails << thumb
|
394
|
+
end
|
395
|
+
|
396
|
+
|
397
|
+
thumb.thumbnail = thumb_params["label"]
|
398
|
+
thumb.filename = thumb_params["filename"]
|
399
|
+
thumb.width = thumb_params["width"]
|
400
|
+
thumb.height = thumb_params["height"]
|
401
|
+
thumb.cloudhdr_status = "processing"
|
402
|
+
thumb.save
|
403
|
+
new_thumbs << thumb
|
404
|
+
Rails.logger.debug " thumb.errors = #{thumb.errors.to_json}"
|
405
|
+
#puts " thumb.errors = #{thumb.errors.to_json}"
|
406
|
+
end
|
407
|
+
new_thumbs
|
408
|
+
end
|
409
|
+
|
410
|
+
def clear_processing
|
411
|
+
processing = false
|
412
|
+
end
|
413
|
+
|
414
|
+
def dedupe_input_thumbs(input_thumbs)
|
415
|
+
needed_thumbs = []
|
416
|
+
input_thumbs.each do |it|
|
417
|
+
t = thumbnails.find_by_thumbnail(it[:label])
|
418
|
+
if t.blank?
|
419
|
+
needed_thumbs << it
|
420
|
+
end
|
421
|
+
end
|
422
|
+
needed_thumbs
|
423
|
+
end
|
424
|
+
|
425
|
+
def create_cloudhdr_job(params)
|
426
|
+
response = nil
|
427
|
+
tries = 0
|
428
|
+
max_tries = 3
|
429
|
+
sleeps = [2,4,8]
|
430
|
+
while response.blank? do
|
431
|
+
begin
|
432
|
+
response = Cloudhdr::Job.create(params)
|
433
|
+
rescue Exception => e
|
434
|
+
if tries < max_tries
|
435
|
+
sleep sleeps[tries]
|
436
|
+
tries += 1
|
437
|
+
response = nil
|
438
|
+
else
|
439
|
+
raise
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
response
|
444
|
+
end
|
445
|
+
|
446
|
+
def process(input_thumbs = self.parent_class.cloudhdr_thumbnails)
|
447
|
+
#puts " input_thumbs.count = #{input_thumbs.size}"
|
448
|
+
input_thumbs = dedupe_input_thumbs(input_thumbs)
|
449
|
+
#puts " after dedupe input_thumbs.count = #{input_thumbs.size}"
|
450
|
+
#if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size
|
451
|
+
# raise "This item already has thumbnails!"
|
452
|
+
# return
|
453
|
+
#end
|
454
|
+
|
455
|
+
return if input_thumbs.size == 0
|
456
|
+
# We do this because sometimes save will get called more than once
|
457
|
+
# during a single request
|
458
|
+
return if processing
|
459
|
+
processing = true
|
460
|
+
|
461
|
+
Rails.logger.debug "trying to process for #{Cloudhdr.base_url} "
|
462
|
+
Rails.logger.debug "callback url = #{callback_url}"
|
463
|
+
response = create_cloudhdr_job(cloudhdr_params(input_thumbs))
|
464
|
+
Rails.logger.debug "the process response = #{response.to_json}" if Rails.env != "test"
|
465
|
+
#puts "the process response = #{response.to_json}" if Rails.env != "test"
|
466
|
+
|
467
|
+
job = self.cloudhdr_jobs.new
|
468
|
+
job.tracking_mode = 'job'
|
469
|
+
job.cloudhdr_input_id = response.body["job"]["inputs"].first["id"]
|
470
|
+
job.cloudhdr_job_id = response.body["job"]["id"]
|
471
|
+
job.cloudhdr_status = "processing"
|
472
|
+
job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id)
|
473
|
+
self.cloudhdr_jobs << job
|
474
|
+
|
475
|
+
self.cloudhdr_status = "processing" unless self.cloudhdr_status == "ready" # the unless clause allows new thumbs to be created on the fly without jacking with the status
|
476
|
+
self.save #false need to do save(false) here if we're calling process on after_save
|
477
|
+
response_thumbs = response.body["job"]["thumbnails"]
|
478
|
+
Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}"
|
479
|
+
#puts "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}"
|
480
|
+
create_thumbnails_from_response(response_thumbs,response.body["job"]["id"])
|
481
|
+
end
|
482
|
+
|
483
|
+
def process_hdr
|
484
|
+
#if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size
|
485
|
+
# raise "This item already has thumbnails!"
|
486
|
+
# return
|
487
|
+
#end
|
488
|
+
|
489
|
+
# We do this because sometimes save will get called more than once
|
490
|
+
# during a single request
|
491
|
+
return if processing
|
492
|
+
processing = true
|
493
|
+
run_callbacks :process_hdr do
|
494
|
+
Rails.logger.debug "trying to process for #{Cloudhdr.base_url} "
|
495
|
+
Rails.logger.debug "callback url = #{callback_url}"
|
496
|
+
response = create_cloudhdr_job(cloudhdr_hdr_params)
|
497
|
+
Rails.logger.debug "the response from process_hdr = #{response.body.to_json}"
|
498
|
+
|
499
|
+
job = self.cloudhdr_jobs.new
|
500
|
+
job.tracking_mode = 'job'
|
501
|
+
job.cloudhdr_output_id = response.body["job"]["hdr"]["id"]
|
502
|
+
job.cloudhdr_job_id = response.body["job"]["id"]
|
503
|
+
job.cloudhdr_status = "processing"
|
504
|
+
job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id)
|
505
|
+
self.cloudhdr_jobs << job
|
506
|
+
|
507
|
+
self.cloudhdr_status = "processing"
|
508
|
+
self.save #false need to do save(false) here if we're calling process on after_save
|
509
|
+
end
|
510
|
+
|
511
|
+
end
|
512
|
+
|
513
|
+
|
514
|
+
def process_hdrhtml
|
515
|
+
#if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size
|
516
|
+
# raise "This item already has thumbnails!"
|
517
|
+
# return
|
518
|
+
#end
|
519
|
+
|
520
|
+
# We do this because sometimes save will get called more than once
|
521
|
+
# during a single request
|
522
|
+
return if processing
|
523
|
+
processing = true
|
524
|
+
run_callbacks :process_hdrhtml do
|
525
|
+
Rails.logger.debug "trying to process for #{Cloudhdr.base_url} "
|
526
|
+
Rails.logger.debug "callback url = #{callback_url}"
|
527
|
+
response = create_cloudhdr_job(cloudhdr_hdrhtml_params)
|
528
|
+
Rails.logger.debug "the response from process_hdrhtml = #{response.body.to_json}"
|
529
|
+
|
530
|
+
job = self.cloudhdr_jobs.new
|
531
|
+
job.tracking_mode = 'job'
|
532
|
+
job.cloudhdr_output_id = response.body["job"]["hdrhtml"]["id"]
|
533
|
+
job.cloudhdr_job_id = response.body["job"]["id"]
|
534
|
+
job.cloudhdr_status = "processing"
|
535
|
+
job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id)
|
536
|
+
self.cloudhdr_jobs << job
|
537
|
+
|
538
|
+
self.cloudhdr_status = "processing"
|
539
|
+
self.save #false need to do save(false) here if we're calling process on after_save
|
540
|
+
end
|
541
|
+
|
542
|
+
end
|
543
|
+
|
544
|
+
|
545
|
+
def process_tone_mapping
|
546
|
+
#if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size
|
547
|
+
# raise "This item already has thumbnails!"
|
548
|
+
# return
|
549
|
+
#end
|
550
|
+
|
551
|
+
# We do this because sometimes save will get called more than once
|
552
|
+
# during a single request
|
553
|
+
return if processing
|
554
|
+
processing = true
|
555
|
+
run_callbacks :process_tone_mapping do
|
556
|
+
destroy_thumbnails
|
557
|
+
Rails.logger.debug "trying to process for #{Cloudhdr.base_url} "
|
558
|
+
Rails.logger.debug "callback url = #{callback_url}"
|
559
|
+
response = create_cloudhdr_job(cloudhdr_tone_mapping_params)
|
560
|
+
Rails.logger.debug "tone_mapping response = #{response.body.to_json}"
|
561
|
+
#puts "tone_mapping response = #{response.body.to_json}"
|
562
|
+
|
563
|
+
job = self.cloudhdr_jobs.new
|
564
|
+
job.tracking_mode = 'job'
|
565
|
+
job.cloudhdr_output_id = response.body["job"]["tone_mapping"]["id"]
|
566
|
+
job.cloudhdr_job_id = response.body["job"]["id"]
|
567
|
+
job.cloudhdr_status = "processing"
|
568
|
+
job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id)
|
569
|
+
self.cloudhdr_jobs << job
|
570
|
+
|
571
|
+
self.cloudhdr_status = "processing"
|
572
|
+
self.save #false need to do save(false) here if we're calling process on after_save
|
573
|
+
response_thumbs = response.body["job"]["thumbnails"]
|
574
|
+
Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}"
|
575
|
+
create_thumbnails_from_response(response_thumbs,response.body["job"]["id"])
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
|
580
|
+
def process_composite
|
581
|
+
#if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size
|
582
|
+
# raise "This item already has thumbnails!"
|
583
|
+
# return
|
584
|
+
#end
|
585
|
+
|
586
|
+
# We do this because sometimes save will get called more than once
|
587
|
+
# during a single request
|
588
|
+
return if processing
|
589
|
+
processing = true
|
590
|
+
run_callbacks :process_composite do
|
591
|
+
destroy_thumbnails
|
592
|
+
Rails.logger.debug "trying to process for #{Cloudhdr.base_url} "
|
593
|
+
Rails.logger.debug "callback url = #{callback_url}"
|
594
|
+
response = create_cloudhdr_job(cloudhdr_composite_params)
|
595
|
+
Rails.logger.debug "composite response = #{response.body.to_json}"
|
596
|
+
#puts "composite response = #{response.body.to_json}"
|
597
|
+
|
598
|
+
job = self.cloudhdr_jobs.new
|
599
|
+
job.tracking_mode = 'job'
|
600
|
+
job.cloudhdr_output_id = response.body["job"]["composite"]["id"]
|
601
|
+
job.cloudhdr_job_id = response.body["job"]["id"]
|
602
|
+
job.cloudhdr_status = "processing"
|
603
|
+
job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id)
|
604
|
+
self.cloudhdr_jobs << job
|
605
|
+
|
606
|
+
self.cloudhdr_status = "processing"
|
607
|
+
self.save #false need to do save(false) here if we're calling process on after_save
|
608
|
+
response_thumbs = response.body["job"]["thumbnails"]
|
609
|
+
Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}"
|
610
|
+
#puts "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}"
|
611
|
+
create_thumbnails_from_response(response_thumbs,response.body["job"]["id"])
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
|
616
|
+
def cloudhdr_extension
|
617
|
+
if self.content_type.blank?
|
618
|
+
".jpg"
|
619
|
+
else
|
620
|
+
self.content_type.match(/png/) ? ".png" : ".jpg"
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
def cloudhdr_params(input_thumbs = self.parent_class.cloudhdr_thumbnails)
|
625
|
+
{:input => {:url => self.public_url, :notifications=>[{:url=>callback_url }] },
|
626
|
+
:thumbnails => cloudhdr_thumbnail_params(input_thumbs)
|
627
|
+
}
|
628
|
+
end
|
629
|
+
|
630
|
+
def cloudhdr_thumbnail_params(input_thumbs = self.parent_class.cloudhdr_thumbnails)
|
631
|
+
input_thumbs.map{|thumb|
|
632
|
+
thumb_filename = thumb[:label] + "_" + File.basename(self.filename,File.extname(self.filename)) + cloudhdr_extension
|
633
|
+
base_url = ActsAsCloudhdr.storeage_mode == "s3" ? "s3://#{self.s3_bucket_name}/#{self.thumbnail_resource_dir}/" : ""
|
634
|
+
th = thumb.clone
|
635
|
+
th[:base_url] = base_url if !base_url.blank?
|
636
|
+
th.merge({
|
637
|
+
:filename=>thumb_filename,
|
638
|
+
:notifications=>[{:url=>thumbnail_callback_url }]
|
639
|
+
})
|
640
|
+
}
|
641
|
+
end
|
642
|
+
|
643
|
+
|
644
|
+
def cloudhdr_hdr_params
|
645
|
+
{ }
|
646
|
+
end
|
647
|
+
|
648
|
+
def cloudhdr_hdrhtml_params
|
649
|
+
{ }
|
650
|
+
end
|
651
|
+
|
652
|
+
def cloudhdr_tone_mapping_params
|
653
|
+
{ }
|
654
|
+
end
|
655
|
+
|
656
|
+
def cloudhdr_composite_params
|
657
|
+
{ }
|
658
|
+
end
|
659
|
+
|
660
|
+
|
661
|
+
|
662
|
+
|
663
|
+
def cloudhdr_config
|
664
|
+
ActsAsCloudhdr.cloudhdr_config
|
665
|
+
end
|
666
|
+
|
667
|
+
def cloudhdr?
|
668
|
+
true
|
669
|
+
end
|
670
|
+
|
671
|
+
def save_url(url)
|
672
|
+
Rails.logger.debug "We are about to download : #{url} to #{local_dir} - #{local_path}"
|
673
|
+
FileUtils.mkdir_p(local_dir) if !File.exists?(local_dir)
|
674
|
+
FileUtils.touch local_path
|
675
|
+
writeOut = open(local_path, "wb")
|
676
|
+
writeOut.write(open(url).read)
|
677
|
+
writeOut.close
|
678
|
+
end
|
679
|
+
|
680
|
+
def destroy_thumbnails
|
681
|
+
if self.class.cloudhdr_thumbnails.size == 0
|
682
|
+
#puts "we're skipping destory_thumbnails since we don't do any processing "
|
683
|
+
return
|
684
|
+
end
|
685
|
+
#puts "calling destory thumbnails for #{self.thumbnails.count} - #{self.thumbnails.size}"
|
686
|
+
self.thumbnails.each do |thumb|
|
687
|
+
thumb.destroy
|
688
|
+
end
|
689
|
+
#puts "calling destory thumbnails for #{self.thumbnails.count}"
|
690
|
+
end
|
691
|
+
|
692
|
+
def create_atts_from_size_string(label_string)
|
693
|
+
self.class.create_atts_from_size_string(label_string)
|
694
|
+
end
|
695
|
+
|
696
|
+
def thumbnail_attributes_for(thumbnail_name)
|
697
|
+
self.class.thumbnail_attributes_for(thumbnail_name)
|
698
|
+
end
|
699
|
+
|
700
|
+
def thumbnail_for(thumbnail_hash_or_name)
|
701
|
+
thumbnail_name = thumbnail_hash_or_name.is_a?(Hash) ? thumbnail_hash_or_name[:label] : thumbnail_hash_or_name
|
702
|
+
if thumbnail_name and thumbnail_name.match ActsAsCloudhdr.size_string_regex
|
703
|
+
thumbnail_name = self.class.create_label_from_size_string(thumbnail_name)
|
704
|
+
end
|
705
|
+
if thumbnail_name.blank? and thumbnail_hash_or_name.is_a?(Hash)
|
706
|
+
thumbnail_name = "#{thumbnail_hash_or_name[:width]}x#{thumbnail_hash_or_name[:height]}"
|
707
|
+
#puts "thumbnail_name = #{thumbnail_name}"
|
708
|
+
thumbnail_hash_or_name[:label] = thumbnail_name
|
709
|
+
end
|
710
|
+
thumb = thumbnails.find_by_thumbnail(thumbnail_name)
|
711
|
+
if thumb.blank? and ActsAsCloudhdr.storeage_mode == "offline"
|
712
|
+
thumb = self
|
713
|
+
elsif thumb.blank? and thumbnail_hash_or_name.is_a? Hash
|
714
|
+
thumb = self.process([thumbnail_hash_or_name]).first
|
715
|
+
elsif thumb.blank? and thumbnail_hash_or_name.is_a?(String) and thumbnail_hash_or_name.match ActsAsCloudhdr.label_size_regex
|
716
|
+
atts = create_atts_from_size_string(thumbnail_name)
|
717
|
+
thumb = self.process([atts]).first
|
718
|
+
end
|
719
|
+
if thumb.blank?
|
720
|
+
raise ThumbnailNotFoundError.new("No thumbnail was found for label '#{thumbnail_name}'")
|
721
|
+
end
|
722
|
+
thumb
|
723
|
+
#a dirty hack for now to keep things working.
|
724
|
+
#Remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
725
|
+
#Go back to just returning the thumb
|
726
|
+
#thumb.blank? ? self : thumb
|
727
|
+
end
|
728
|
+
|
729
|
+
def get_thumbnail(thumbnail_name)
|
730
|
+
thumbnail_for(thumbnail_name)
|
731
|
+
end
|
732
|
+
|
733
|
+
def file=(new_file)
|
734
|
+
return if new_file.nil?
|
735
|
+
Rails.logger.debug "we got a new file of class = #{new_file.class}"
|
736
|
+
cleanup
|
737
|
+
if new_file.is_a? File
|
738
|
+
self.filename = File.basename new_file.path
|
739
|
+
self.content_type = MIME::Types.type_for(self.filename).first.content_type
|
740
|
+
self.file_size = new_file.size
|
741
|
+
else
|
742
|
+
self.filename = new_file.original_filename
|
743
|
+
self.content_type = new_file.content_type
|
744
|
+
self.file_size = new_file.size
|
745
|
+
end
|
746
|
+
self.content_type = File.mime_type?(self.filename) if (self.content_type.blank? || self.content_type == "[]")
|
747
|
+
if new_file.respond_to? :tempfile
|
748
|
+
@saved_file = new_file.tempfile
|
749
|
+
else
|
750
|
+
@saved_file = new_file
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
#compatability method for attachment_fu
|
755
|
+
def uploaded_data=(data)
|
756
|
+
self.file = data
|
757
|
+
end
|
758
|
+
|
759
|
+
def save_local_file
|
760
|
+
return if @saved_file.blank?
|
761
|
+
#puts "saving the local file!!!!!!"
|
762
|
+
Rails.logger.debug "==================================================================================================="
|
763
|
+
Rails.logger.debug "about to save the local file"
|
764
|
+
run_callbacks :file_saved do
|
765
|
+
run_callbacks :local_file_saved do
|
766
|
+
FileUtils.mkdir_p local_dir
|
767
|
+
FileUtils.cp @saved_file.path, local_path
|
768
|
+
FileUtils.chmod 0755, local_path
|
769
|
+
self.cloudhdr_status = "local"
|
770
|
+
if self.respond_to? :upload_host
|
771
|
+
self.upload_host = %x{hostname}.strip
|
772
|
+
end
|
773
|
+
@saved_file = nil
|
774
|
+
@saved_a_new_file = true
|
775
|
+
self.save
|
776
|
+
end
|
777
|
+
if ActsAsCloudhdr.storeage_mode == "s3" && ActsAsCloudhdr.processing_mode == "automatic"
|
778
|
+
self.save_s3_file
|
779
|
+
end
|
780
|
+
if ActsAsCloudhdr.storeage_mode == "local" && ActsAsCloudhdr.processing_mode == "automatic"
|
781
|
+
self.encode
|
782
|
+
end
|
783
|
+
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
def fire_ready_callback
|
788
|
+
run_callbacks :file_ready do
|
789
|
+
end
|
790
|
+
end
|
791
|
+
|
792
|
+
|
793
|
+
def cleanup
|
794
|
+
#puts "calling cleanup!"
|
795
|
+
destroy_thumbnails
|
796
|
+
remove_local_file
|
797
|
+
if ActsAsCloudhdr.storeage_mode == "s3"
|
798
|
+
remove_s3_file
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
def remove_local_file
|
803
|
+
if local_path and File.exists? local_path
|
804
|
+
FileUtils.rm local_path
|
805
|
+
if Dir.glob(File.join(local_dir,"*")).size == 0
|
806
|
+
FileUtils.rmdir local_dir
|
807
|
+
end
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
def path_id
|
812
|
+
|
813
|
+
#puts "parent_id = #{parent_id}"
|
814
|
+
#puts "parent = #{parent}"
|
815
|
+
if respond_to?(:parent_id)
|
816
|
+
parent_id.blank? ? id : parent.path_id
|
817
|
+
else
|
818
|
+
id
|
819
|
+
end
|
820
|
+
end
|
821
|
+
|
822
|
+
def resource_dir
|
823
|
+
File.join(self.class.table_name, path_id.to_s )
|
824
|
+
end
|
825
|
+
|
826
|
+
def thumbnail_resource_dir
|
827
|
+
File.join(self.thumbnail_class.table_name, path_id.to_s )
|
828
|
+
end
|
829
|
+
|
830
|
+
def local_dir
|
831
|
+
File.join(ActsAsCloudhdr.local_base_dir,resource_dir)
|
832
|
+
end
|
833
|
+
|
834
|
+
def local_path
|
835
|
+
filename.blank? ? nil : File.join(local_dir,filename)
|
836
|
+
end
|
837
|
+
|
838
|
+
def local_url
|
839
|
+
filename.blank? ? nil : File.join("/",resource_dir,filename)
|
840
|
+
end
|
841
|
+
|
842
|
+
# This should generate a fully qualified http://something-something
|
843
|
+
# type of a reference. Depending on storeage_mode/base_url settings.
|
844
|
+
def public_url
|
845
|
+
#puts "our base_url = #{base_url} and our local_url = #{local_url}"
|
846
|
+
if ActsAsCloudhdr.storeage_mode == "local" or ActsAsCloudhdr.storeage_mode == "offline"
|
847
|
+
base_url + local_url
|
848
|
+
else
|
849
|
+
self.class.cloudfront_host.present? ? cloudfront_url : s3_url
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
def public_filename
|
854
|
+
public_url
|
855
|
+
end
|
856
|
+
|
857
|
+
|
858
|
+
def callback_url
|
859
|
+
self.base_url + self.notification_callback_path
|
860
|
+
end
|
861
|
+
|
862
|
+
def thumbnail_callback_url
|
863
|
+
self.base_url + self.thumbnail_notification_callback_path
|
864
|
+
end
|
865
|
+
|
866
|
+
def notification_callback_path
|
867
|
+
"/cloudhdr/cloudhdr_notifications/#{self.class.name}/#{self.id}.json"
|
868
|
+
end
|
869
|
+
|
870
|
+
def thumbnail_notification_callback_path
|
871
|
+
"/cloudhdr/cloudhdr_notifications/#{self.thumbnail_class.name}/#{self.id}.json"
|
872
|
+
end
|
873
|
+
|
874
|
+
def base_url
|
875
|
+
self.class.base_url
|
876
|
+
end
|
877
|
+
|
878
|
+
def s3_key
|
879
|
+
filename.blank? ? nil : File.join(resource_dir,filename)
|
880
|
+
end
|
881
|
+
|
882
|
+
def s3_url
|
883
|
+
"http://#{s3_bucket_name}.s3.amazonaws.com/#{s3_key}"
|
884
|
+
end
|
885
|
+
|
886
|
+
def s3_bucket_name
|
887
|
+
self.class.s3_bucket_name
|
888
|
+
end
|
889
|
+
|
890
|
+
def cloudfront_base_host
|
891
|
+
host = self.class.cloudfront_host
|
892
|
+
host.instance_of?(Proc) ? host.call(s3_key) : host
|
893
|
+
end
|
894
|
+
|
895
|
+
def cloudfront_url
|
896
|
+
"#{cloudfront_base_host}/#{s3_key}"
|
897
|
+
end
|
898
|
+
|
899
|
+
def unused_s3_demo_stuff
|
900
|
+
s3 = AWS::S3.new
|
901
|
+
key,bucket = get_s3_key_and_bucket
|
902
|
+
obj = s3.buckets[bucket].objects[key]
|
903
|
+
obj.write(Pathname.new(tmpFile),{:acl=>:public_read,"Cache-Control"=>'max-age=315360000'})
|
904
|
+
end
|
905
|
+
|
906
|
+
def s3
|
907
|
+
@s3 ||= AWS::S3.new
|
908
|
+
end
|
909
|
+
|
910
|
+
def s3_obj
|
911
|
+
s3.buckets[s3_bucket_name].objects[s3_key]
|
912
|
+
end
|
913
|
+
|
914
|
+
def save_s3_file
|
915
|
+
#I don't think we need this return check anymore.
|
916
|
+
#return if !@saved_a_new_file
|
917
|
+
#@saved_a_new_file = false
|
918
|
+
#AWS::S3::S3Object.store(
|
919
|
+
#s3_key,
|
920
|
+
#open(local_path),
|
921
|
+
#s3_bucket_name,
|
922
|
+
#:access => :public_read,
|
923
|
+
#"Cache-Control" => 'max-age=315360000'
|
924
|
+
#)
|
925
|
+
s3_obj.write(Pathname.new(local_path),{:acl=>:public_read,"Cache-Control"=>'max-age=315360000'})
|
926
|
+
self.cloudhdr_status = "s3"
|
927
|
+
self.save
|
928
|
+
#obj_data = AWS::S3::S3Object.find(s3_key,s3_bucket_name)
|
929
|
+
Rails.logger.debug "----------------------------------------------------------------------------------------------------"
|
930
|
+
if s3_obj.content_length == file_size # it made it into s3 safely
|
931
|
+
Rails.logger.debug " we are about to remove local file!"
|
932
|
+
remove_local_file
|
933
|
+
else
|
934
|
+
msg = "The file was not saved to S3 sucessfully. Orig size: #{file_size} - S3 size: #{obj_data.size}"
|
935
|
+
Rails.logger.debug msg
|
936
|
+
raise ActsAsCloudhdr::Error.new msg
|
937
|
+
end
|
938
|
+
self.encode
|
939
|
+
end
|
940
|
+
|
941
|
+
|
942
|
+
def remove_s3_file
|
943
|
+
#puts "trying to delete #{s3_key} #{s3_bucket_name}"
|
944
|
+
#if ActsAsCloudhdr.storeage_mode == "s3"
|
945
|
+
#AWS::S3::S3Object.delete s3_key, s3_bucket_name
|
946
|
+
#end
|
947
|
+
s3_obj.delete
|
948
|
+
rescue Exception => e
|
949
|
+
#this probably means that the file never made it to S3
|
950
|
+
end
|
951
|
+
|
952
|
+
# Sanitizes a filename.
|
953
|
+
def filename=(new_name)
|
954
|
+
write_attribute :filename, sanitize_filename(new_name)
|
955
|
+
end
|
956
|
+
|
957
|
+
def sanitize_filename(filename)
|
958
|
+
return unless filename
|
959
|
+
filename.strip.tap do |name|
|
960
|
+
# NOTE: File.basename doesn't work right with Windows paths on Unix
|
961
|
+
# get only the filename, not the whole path
|
962
|
+
name.gsub! /^.*(\\|\/)/, ''
|
963
|
+
|
964
|
+
# Finally, replace all non alphanumeric, underscore or periods with underscore
|
965
|
+
name.gsub! /[^A-Za-z0-9\.\-]/, '_'
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
# Calculate the width for the target thumbnail atts
|
970
|
+
def calc_width(thumbnail_atts)
|
971
|
+
tw = thumbnail_atts[:width].blank? ? 100000 : thumbnail_atts[:width].to_f
|
972
|
+
th = thumbnail_atts[:height].blank? ? 100000 : thumbnail_atts[:height].to_f
|
973
|
+
w = width.to_f
|
974
|
+
h = height.to_f
|
975
|
+
if w <= tw and h <= th
|
976
|
+
w.round
|
977
|
+
elsif w > h
|
978
|
+
if (h * ( tw / w )).round < tw
|
979
|
+
tw .round
|
980
|
+
else
|
981
|
+
(h * ( tw / w )).round
|
982
|
+
end
|
983
|
+
else
|
984
|
+
if (w * ( th / h )).round < tw
|
985
|
+
(w * ( th / h )).round
|
986
|
+
else
|
987
|
+
tw.round
|
988
|
+
end
|
989
|
+
end
|
990
|
+
end #end calc_width
|
991
|
+
|
992
|
+
|
993
|
+
def calc_height(thumbnail_atts)
|
994
|
+
tw = thumbnail_atts[:width].blank? ? 100000 : thumbnail_atts[:width].to_f
|
995
|
+
th = thumbnail_atts[:height].blank? ? 100000 : thumbnail_atts[:height].to_f
|
996
|
+
w = width.to_f
|
997
|
+
h = height.to_f
|
998
|
+
if w <= tw and h <= th
|
999
|
+
h.round
|
1000
|
+
elsif w > h
|
1001
|
+
if (h * ( tw / w )).round < th
|
1002
|
+
(h * ( tw / w )).round
|
1003
|
+
else
|
1004
|
+
th.round
|
1005
|
+
end
|
1006
|
+
else
|
1007
|
+
if (w * ( th / h )).round < tw
|
1008
|
+
th.round
|
1009
|
+
else
|
1010
|
+
(h * ( tw / w )).round
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
end #end calc_height
|
1014
|
+
|
1015
|
+
|
1016
|
+
|
1017
|
+
end#module InstanceMethods
|
1018
|
+
|
1019
|
+
end
|
1020
|
+
ActiveRecord::Base.extend ActsAsCloudhdr
|