· 8 years ago · Feb 28, 2018, 09:17 PM
1require 'ContentTranscoding/image_hash.rb'
2
3# This class represents a set of frames at a particular size and format for the film
4# strip notion. It has many frame_contents which it uses to store individual frames.
5class FrameSet < ActiveRecord::Base
6 include SonicImageHash
7 belongs_to :video_clip
8# belongs_to :content_dimensions, :foreign_key => 'content_dimensions_id'
9# belongs_to :format
10 has_many :frame_contents, :as => 'contentable', :order => 'frame', :dependent => :destroy
11 validates_presence_of :hash_code, :if => Proc.new{|fs| !fs.frame_contents.empty? }
12 validates_uniqueness_of(:video_clip_id,
13 :scope => [:hash_code],
14 :message => 'already has a frameset of this image specifications..')
15
16 @@log = Log4r::Logger.get 'dblog::model'
17
18 # Used to specify what max_file_class a file is defined as.
19 attr_reader :image_hash
20 attr_accessor :max_size_class
21
22
23 # This is a set callback that the model Content calls when loading a record, or when
24 # a new record sets it contentable type. Its used to define singleton methods on these
25 # objects so that the parent object can impose more validation routines ont the object.
26 def additional_content_procs(content)
27 @@log.debug "START FrameSet#additional_content_procs()"
28 @@log.debug "additional_content_procs() >> PARAMTERS: content #{content.id}"
29 efp = Proc.new {|content, frame_set|
30 return nil if frame_set.nil?
31 generic_filename = frame_set.generic_expected_filename
32 @@log.debug "FrameSet#EFP Proc >> generic_filename: #{generic_filename}"
33 return nil if generic_filename.nil?
34 return nil if content.frame.nil?
35 generic_filename.gsub(/#/, content.frame.to_s)
36# frame_set.image_hash.inspect
37 }
38
39 vp = Proc.new {|content|
40 if !content.expected_filename.nil? && content.expected_filename != content.filename
41 content.errors.add :file, "is not the correct file. File expected: #{content.expected_filename}"
42 end
43 }
44
45 content.set_expected_filename_proc(&efp);
46 content.set_additional_validations_proc(&vp);
47 @@log.debug "END FrameSet#additional_content_procs()"
48 end
49
50
51 # The Generic filename for all frames.
52 def generic_expected_filename
53 @@log.debug "START FrameSet#generic_expected_filename()"
54 return nil if self.video_clip.nil? || self.video_clip.content_files.nil? || self.video_clip.media_type.nil?
55# return nil if self.format.nil? || self.content_dimensions.nil?
56 expected_filename = ""
57 expected_filename += self.video_clip.content_files
58 expected_filename += "_" + self.video_clip.media_type.file_identifier
59 expected_filename += "_#"
60# expected_filename += "_" + self.content_dimensions.width.to_s
61 expected_filename += "." + self.format.file_extension if !format.nil?
62 @@log.debug "generic_expected_filename() >> RETURN #{expected_filename}"
63 @@log.debug "END FrameSet#generic_expected_filename()"
64 expected_filename
65
66 end
67
68 # Expects an Integer and an IOStream of some type to upload a file into the system. Finds of creates
69 # a FrameContent object at frame number and loads file into the frame content.
70 def set_frame_content(frame, incoming_file)
71 @@log.debug "START FrameSet#set_frame_content()"
72 @@log.debug "set_frame_content() >> PARAMETER frame: #{frame} incoming_file: #{incoming_file}"
73 f_content = self.frame_contents.find(:first, :conditions => "frame = #{frame}")
74 if f_content.nil?
75 f_content = self.frame_contents.build(:frame => frame)
76 self.additional_content_procs(f_content)
77 end
78 f_content.file = incoming_file
79 @@log.debug "set_frame_content() >> RETURN content frame: #{f_content.frame}"
80 @@log.debug "END FrameSet#set_frame_content()"
81 f_content
82 end
83
84
85 def method_missing(symbol, *args)
86 if /^frame_file_\d+=$/ =~ symbol.to_s && args.length == 1
87 number = /\d+/.match(symbol.to_s).to_s.to_i
88 self.set_frame_content(number, args[0])
89 elsif !@image_hash.nil?
90 begin
91 @image_hash.method_missing method, args
92 self.hash_code = @image_hash.code
93 rescue
94 super
95 end
96 else
97 super
98 end
99 end
100
101 # This function is used to pull out the errors from FrameContents and
102 # add more helpful error messages.
103 def validate(*methods, &block)
104 @@log.debug "START FrameSet#validate()"
105 super
106 if !self.errors.empty?
107# self.frame_contents[0].data = nil
108 for fc in self.frame_contents
109 fc.data = nil
110 fc.errors.each do |fc_attr, msg|
111 attr = "frame_file_#{fc.frame}".to_sym
112 self.errors.add(attr, ">> #{fc_attr.titleize} #{msg}")
113 end
114 end
115 end
116 @@log.debug "validate() >> has_errors? #{!self.errors.empty?}"
117 @@log.debug "END FrameSet#validate()"
118 end
119
120 # Used to clear all frame_contents of any procedures.
121 def clear_frame_content_procs
122 for fc in self.frame_contents
123 fc.data = nil
124 fc.clear_all_procs
125 end
126 self
127 end
128
129 # This function will choose which frames to return if the number of frames stored is too much.
130 def sample_frames(frames_supported)
131 raise ArgumentError, "Paramter 'frames_supported' expects type Fixnum." if frames_supported.class != Fixnum
132 total_frames = self.frame_contents.count
133
134 if frames_supported >= total_frames
135 return self.frame_contents
136 else
137 return [self.frame_contents[0], self.frame_contents[2]]
138 end
139 end
140
141 # Loads up the image_hash of attributes from code.
142 def after_find
143 if self.hash_code.nil?
144 @image_hash = ImageHash.new
145 else
146 @image_hash = ImageHash.new(:code => self.hash_code)
147 end
148 end
149
150 def initialize(attributes = nil)
151 @image_hash = ImageHash.new
152 super
153 end
154
155 # This loads the 'assumed' ImageHash code into
156 # FrameContent and standarizes the max_file_size
157 # of all the items.
158 def before_validation
159 @@log.debug "START FrameSet#before_validation()"
160 if !self.frame_contents.empty?
161 mfs = @max_size_class.nil? ? 0 : @max_size_class
162 self.frame_contents.each do |fc|
163 mfs = fc.max_file_size if (!fc.max_file_size.nil? && mfs < fc.max_file_size)
164 end
165 self.frame_contents.each do |fc|
166 fc.max_file_size = mfs
167 end
168 if frame_contents[0].image_hash.code.nil?
169 @image_hash.clear_attributes
170 else
171 @image_hash.code = self.frame_contents[0].image_hash.code
172 end
173 self.hash_code = @image_hash.code
174 else
175 self.hash_code = nil
176 end
177 @@log.debug "before_validation() >> hash_code: #{self.hash_code}, image_hash: #{self.image_hash.inspect}"
178 @@log.debug "END FrameSet#before_validation()"
179 end
180
181 # Used to create connection between RMagick and the current Formats
182 # table.
183 # TODO: Change when universal formats have been implemented.
184 def format
185 @@log.debug "START FrameSet#format()"
186 @@log.debug "format() >> @image_hash: #{@image_hash.inspect}"
187 if !@image_hash.nil? && !@image_hash.file_format.nil?
188 @@log.debug "format() >> Looking for format"
189 val = Format.find_by_rmagick_key(@image_hash.file_format)
190 else
191 val = nil
192 end
193 @@log.debug "format() >> RETURN #{val.inspect}"
194 @@log.debug "END FrameSet#format()"
195 return val
196 end
197
198 # String dimensions of image.
199 def dimensions
200 if !@image_hash.nil? && !@image_hash.width.nil? && !@image_hash.height.nil?
201 "#{@image_hash.width} x #{@image_hash.height}"
202 else
203 nil
204 end
205 end
206
207end
208
209----
210
211require 'ContentTranscoding/image_hash.rb'
212
213class FrameContent < Content
214 include SonicImageHash
215# belongs_to :content_dimensions, :foreign_key => 'content_dimensions_id'
216# belongs_to :format
217# validates_presence_of :format_id, :content_dimensions_id
218 validates_presence_of :contentable_id, :contentable_type, :frame
219# validates_each :format do |record, attr, value|
220# record.errors.add attr, "is not an image format." if value.nil? || value.content_type != 'image'
221# end
222# This ensures that two clips for identical sizes and formats are not uploaded.
223 validates_uniqueness_of(:frame,
224 :scope => [:contentable_id, :contentable_type],
225 :message => 'already exists for this item.')
226
227
228 # Used to specify what max_file_class a file is defined as.
229 attr_reader :image_hash
230 attr_accessor :max_size_class
231
232 # Reads an incoming file. This function first calls
233 # its parent method, and then uses the RIL library to
234 # gather all image specifications.
235 def file=(incoming_file)
236 @@log.debug "START FrameContent#file=()"
237 super
238 @good_image_file = true
239 begin
240 self.image_hash.inspect_image(self.data) if self.data.length <= ServerRoleEnv::MAX_BLOB_DATA_SIZE
241 rescue
242 @good_image_file = false
243 end
244 @@log.debug "END FrameContent#file=()"
245 end
246
247 # Loads up the image_hash of attributes from code.
248 def after_find
249 if self.hash_code.nil?
250 @image_hash = ImageHash.new
251 else
252 @image_hash = ImageHash.new(:code => self.hash_code)
253 end
254 super
255 end
256
257
258 def initialize(attributes = nil)
259 @image_hash = ImageHash.new
260 super
261 end
262
263 def before_validation
264 self.hash_code = @image_hash.code
265 end
266
267 # Used to temporarily integrate ImageHash Attributes into
268 # the attributes of the ImageContent.
269 def method_missing(method, *args, &block)
270 if !@image_hash.nil?
271 begin
272 result = @image_hash.method_missing method, args
273 self.hash_code = @image_hash.code
274 result
275 rescue
276 super
277 end
278 else
279 super
280 end
281 end
282
283 # Used to create connection between RMagick and the current Formats
284 # table.
285 # TODO: Change when universal formats have been implemented.
286 def format
287 if !@image_hash.nil? && !@image_hash.file_format.nil?
288 Format.find_by_rmagick_key(@image_hash.file_format)
289 else
290 nil
291 end
292 end
293
294 # String dimensions of image.
295 def dimensions
296 if !@image_hash.nil? && !@image_hash.width.nil? && !@image_hash.height.nil?
297 "#{@image_hash.width} x #{@image_hash.height}"
298 else
299 nil
300 end
301 end
302
303 # This function is used to check on the file upload
304 # of an image.
305 def validate(*methods, &block)
306 @@log.debug "START FrameContent#validate()"
307 super
308 if !@good_image_file.nil? && !@good_image_file
309 self.errors.add(:file, "is not a proper image file.")
310 end
311 @@log.debug "validate() >> has_errors? #{!self.errors.empty?}"
312 @@log.debug "END FrameContent#validate()"
313 end
314
315end
316
317
318
319
320---
321
322def test_frame_file_upload
323 build_content_dimensions
324 f_set = frame_sets(:dracula_frameset)
325# f_set.content_dimensions = ContentDimensions.find(:first, :conditions => "width = 176 AND height = 144")
326# f_set.save!
327
328 f_set.frame_file_1 = uploaded_png("#{File.expand_path(RAILS_ROOT)}/test/fixtures/top_senkai.jpg", "Dracula_2_VID_1.jpg")
329# f_set.frame_file_2 = uploaded_png("#{File.expand_path(RAILS_ROOT)}/test/fixtures/top_senkai.jpg", "Dracula_2_VID_2.jpg")
330# f_set.frame_file_3 = uploaded_png("#{File.expand_path(RAILS_ROOT)}/test/fixtures/top_senkai.jpg", "Dracula_2_VID_3.jpg")
331# f_set.frame_file_4 = uploaded_png("#{File.expand_path(RAILS_ROOT)}/test/fixtures/top_senkai.jpg", "Dracula_2_VID_4.jpg")
332
333 assert f_set.save, "Frame Set did not properly save. #{f_set.errors.full_messages.inspect}. Fset: #{f_set.generic_expected_filename}"
334 assert_equal 4, f_set.frame_contents(true).count, "Frame Contents did not properly save to db."
335 end
336
337-------
338
339
340
341
342
343C:/Ruby/InstantRails/rails_apps/ntmv/config/../app/controllers/application.rb:5:
344 warning: already initialized constant Logger
345C:/Ruby/InstantRails/rails_apps/ntmv/config/../app/models/content.rb:3: warning:
346 already initialized constant Logger
347Loaded suite test/unit/frame_set_test
348Started
349[20070116:16:27:27] (DEBUG) |model|: START FrameSet#set_frame_content()
350[20070116:16:27:27] (DEBUG) |model|: set_frame_content() >> PARAMETER frame: 1 i
351ncoming_file: #<File:0x70b37d0>
352[20070116:16:27:27] (DEBUG) |model|: START FrameSet#additional_content_procs()
353[20070116:16:27:27] (DEBUG) |model|: additional_content_procs() >> PARAMTERS: co
354ntent
355[20070116:16:27:27] (DEBUG) |model|: END FrameSet#additional_content_procs()
356[20070116:16:27:27] (DEBUG) |model|: START FrameContent#file=()
357[20070116:16:27:27] (DEBUG) |model|: START Content#file=()
358[20070116:16:27:27] (DEBUG) |model|: file=() >> original_filename: Dracula_2_VID
359_1.jpg
360[20070116:16:27:27] (DEBUG) |model|: End Content#file=()
361[20070116:16:27:27] (DEBUG) |model|: END FrameContent#file=()
362[20070116:16:27:27] (DEBUG) |model|: set_frame_content() >> RETURN content frame
363: 1
364[20070116:16:27:27] (DEBUG) |model|: END FrameSet#set_frame_content()
365[20070116:16:27:27] (DEBUG) |model|: START FrameSet#before_validation()
366[20070116:16:27:27] (DEBUG) |model|: before_validation() >> hash_code: v2:JPEG:4
36700:199:8:81264, image_hash: #<SonicImageHash::ImageHash:59185888 @attributes={"m
368ime_type"=>nil, "bit_depth"=>8, "height"=>199, "file_format"=>"JPEG", "max_file_
369size"=>81264, "width"=>400}>
370[20070116:16:27:27] (DEBUG) |model|: END FrameSet#before_validation()
371[20070116:16:27:27] (DEBUG) |model|: START FrameContent#validate()
372[20070116:16:27:27] (DEBUG) |model|: START Content#validate()
373[20070116:16:27:27] (DEBUG) |model|: validate() >> Calling @validation_proc
374[20070116:16:27:27] (DEBUG) |model|: START FrameSet#generic_expected_filename()
375[20070116:16:27:27] (DEBUG) |model|: START FrameSet#format()
376[20070116:16:27:27] (DEBUG) |model|: format() >> @image_hash: #<SonicImageHash::
377ImageHash:58996432 @attributes={"mime_type"=>nil, "bit_depth"=>nil, "height"=>ni
378l, "file_format"=>nil, "max_file_size"=>nil, "width"=>nil}>
379[20070116:16:27:27] (DEBUG) |model|: format() >> RETURN nil
380[20070116:16:27:27] (DEBUG) |model|: END FrameSet#format()
381[20070116:16:27:27] (DEBUG) |model|: generic_expected_filename() >> RETURN Dracu
382la_2_VID_#
383[20070116:16:27:27] (DEBUG) |model|: END FrameSet#generic_expected_filename()
384[20070116:16:27:27] (DEBUG) |model|: FrameSet#EFP Proc >> generic_filename: Drac
385ula_2_VID_#
386[20070116:16:27:27] (DEBUG) |model|: START FrameSet#generic_expected_filename()
387[20070116:16:27:27] (DEBUG) |model|: START FrameSet#format()
388[20070116:16:27:27] (DEBUG) |model|: format() >> @image_hash: #<SonicImageHash::
389ImageHash:58996432 @attributes={"mime_type"=>nil, "bit_depth"=>nil, "height"=>ni
390l, "file_format"=>nil, "max_file_size"=>nil, "width"=>nil}>
391[20070116:16:27:27] (DEBUG) |model|: format() >> RETURN nil
392[20070116:16:27:27] (DEBUG) |model|: END FrameSet#format()
393[20070116:16:27:27] (DEBUG) |model|: generic_expected_filename() >> RETURN Dracu
394la_2_VID_#
395[20070116:16:27:27] (DEBUG) |model|: END FrameSet#generic_expected_filename()
396[20070116:16:27:27] (DEBUG) |model|: FrameSet#EFP Proc >> generic_filename: Drac
397ula_2_VID_#
398[20070116:16:27:27] (DEBUG) |model|: START FrameSet#generic_expected_filename()
399[20070116:16:27:27] (DEBUG) |model|: START FrameSet#format()
400[20070116:16:27:27] (DEBUG) |model|: format() >> @image_hash: #<SonicImageHash::
401ImageHash:58996432 @attributes={"mime_type"=>nil, "bit_depth"=>nil, "height"=>ni
402l, "file_format"=>nil, "max_file_size"=>nil, "width"=>nil}>
403[20070116:16:27:27] (DEBUG) |model|: format() >> RETURN nil
404[20070116:16:27:27] (DEBUG) |model|: END FrameSet#format()
405[20070116:16:27:27] (DEBUG) |model|: generic_expected_filename() >> RETURN Dracu
406la_2_VID_#
407[20070116:16:27:27] (DEBUG) |model|: END FrameSet#generic_expected_filename()
408[20070116:16:27:27] (DEBUG) |model|: FrameSet#EFP Proc >> generic_filename: Drac
409ula_2_VID_#
410[20070116:16:27:27] (DEBUG) |model|: validate(): >> calling super
411[20070116:16:27:27] (DEBUG) |model|: END Content#validate()
412[20070116:16:27:27] (DEBUG) |model|: validate() >> has_errors? true
413[20070116:16:27:27] (DEBUG) |model|: END FrameContent#validate()
414[20070116:16:27:27] (DEBUG) |model|: START FrameSet#validate()
415[20070116:16:27:27] (DEBUG) |model|: validate() >> has_errors? true
416[20070116:16:27:27] (DEBUG) |model|: END FrameSet#validate()
417[20070116:16:27:27] (DEBUG) |model|: START FrameSet#generic_expected_filename()
418[20070116:16:27:27] (DEBUG) |model|: START FrameSet#format()
419[20070116:16:27:27] (DEBUG) |model|: format() >> @image_hash: #<SonicImageHash::
420ImageHash:59185888 @attributes={"mime_type"=>nil, "bit_depth"=>8, "height"=>199,
421 "file_format"=>"JPEG", "max_file_size"=>81264, "width"=>400}>
422[20070116:16:27:27] (DEBUG) |model|: format() >> Looking for format
423[20070116:16:27:27] (DEBUG) |model|: format() >> RETURN #<Format:0x6ded970 @attr
424ibutes={"content_type"=>"image", "name"=>"JPEG", "rmagick_key"=>"JPEG", "mime_ty
425pe"=>"image/jpeg", "id"=>"3", "file_extension"=>"jpeg"}>
426[20070116:16:27:27] (DEBUG) |model|: END FrameSet#format()
427[20070116:16:27:27] (DEBUG) |model|: START FrameSet#format()
428[20070116:16:27:27] (DEBUG) |model|: format() >> @image_hash: #<SonicImageHash::
429ImageHash:59185888 @attributes={"mime_type"=>nil, "bit_depth"=>8, "height"=>199,
430 "file_format"=>"JPEG", "max_file_size"=>81264, "width"=>400}>
431[20070116:16:27:27] (DEBUG) |model|: format() >> Looking for format
432[20070116:16:27:27] (DEBUG) |model|: format() >> RETURN #<Format:0x6dea508 @attr
433ibutes={"content_type"=>"image", "name"=>"JPEG", "rmagick_key"=>"JPEG", "mime_ty
434pe"=>"image/jpeg", "id"=>"3", "file_extension"=>"jpeg"}>
435[20070116:16:27:27] (DEBUG) |model|: END FrameSet#format()
436[20070116:16:27:27] (DEBUG) |model|: generic_expected_filename() >> RETURN Dracu
437la_2_VID_#.jpeg
438[20070116:16:27:27] (DEBUG) |model|: END FrameSet#generic_expected_filename()
439F
440Finished in 5.672 seconds.
441
442 1) Failure:
443test_frame_file_upload(FrameSetTest) [test/unit/frame_set_test.rb:36]:
444Frame Set did not properly save. ["Frame file 1 >> File is not the correct file.
445 File expected: Dracula_2_VID_1", "Frame contents is invalid"]. Fset: Dracula_2_
446VID_#.jpeg.
447<false> is not true.
448
4491 tests, 1 assertions, 1 failures, 0 errors
450
451C:\Ruby\InstantRails\rails_apps\ntmv>