module ActsAsCloudhdr require 'safe_yaml' require 'cloudhdr' require 'open-uri' require 'aws-sdk' require 'mimetype_fu' # Storeage mode controls how uploads are handled. # Valid options are: # offline : For development mode with no net connection. No processing. # local : To store images locally but use Cloudhdr for processing. # s3 : Store image in S3 and use Cloudhdr for processing. # Set this options either in evnironment.rb or # in environments/development.rb etc... mattr_accessor :storeage_mode self.storeage_mode = "local" # Processing mode controls when images get sent to cloudhdr # Valid options are: # automatic : Send to cloudhdr as soon as the file is stored. # With 'local' storage mode, this submits the job # to cloudhdr while the user is still waiting. # delayed : Handle storage/processing in a background process. mattr_accessor :processing_mode self.processing_mode = "automatic" # This is used as the base address for cloudhdr notifications. # When storeage_mode == "local" this is also used to point # cloudhdr at the file. # It should only be the host.domain portion of the URL # no path components. mattr_accessor :base_url self.base_url = "http://your-domain.com" # The bucket for storing s3 files mattr_accessor :s3_bucket_name self.s3_bucket_name = "your-bucket" # The cloudfront host or a Proc that returns a cloud front host mattr_accessor :cloudfront_host self.cloudfront_host = nil # The javascript library to use for updates # either 'prototype' or 'jquery' mattr_accessor :javascript_library self.javascript_library = 'prototype' # The local directory where files should be stored mattr_accessor :local_base_dir self.local_base_dir = '/tmp' # The config file that tells cloudhdr where to find # config options. mattr_accessor :config_file self.config_file = "config/cloudhdr.yml" # The actual configuration parameters mattr_accessor :config self.config = nil def self.cloudhdr_config #puts "checking cloudhdr_config for #{self.config}" self.read_cloudhdr_configuration if self.config.nil? self.config end def self.read_cloudhdr_configuration config_path = File.join(::Rails.root.to_s, ActsAsCloudhdr.config_file) #puts "#{self.config} - looking for a config in #{config_path}" self.config = YAML.load(ERB.new(File.read(config_path)).result)[::Rails.env.to_s].symbolize_keys self.apply_cloudhdr_configuration end # The list of image content types that are considered web safe # These can be displayed directly, skipping processing if in offline mode mattr_accessor :web_safe_image_types self.web_safe_image_types = [ 'image/jpeg', 'image/jpg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg', 'application/png', 'application/x-png' ] # The list of image content types that are not considered web safe # These can not be displayed directly mattr_accessor :other_image_types self.other_image_types = [ 'image/pjpeg', 'image/x-ms-bmp', 'image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap', 'application/preview', 'image/jp_', 'application/jpg', 'application/x-jpg', 'image/pipeg', 'image/vnd.swiftview-jpeg', 'image/x-xbitmap', 'image/gi_', 'image/x-citrix-pjpeg', 'image/x-nikon-nef', 'image/tiff', 'image/x-olympus-orf', 'image/x-dcraw', 'image/x-adobe-dng' ] # The list of content types that will trigger image handling. def image_types web_safe_image_types + other_image_types end # TODO : This needs to be fixed. # It currently matches anything with an 'x' in it mattr_accessor :label_size_regex self.label_size_regex = /(\d*)x(\d*)(pad|crop|stretch|preserve)?/ # mattr_accessor :size_string_regex self.size_string_regex = /(\d*)x(\d*)([!>]?)/ def image?(content_type) image_types.include?(content_type) end def web_safe?(content_type) web_safe_image_types.include?(content_type) end #def self.storeage_mode # @@storeage_mode #end def acts_as_cloudhdr(options = { }) include InstanceMethods attr_reader :saved_file attr_accessor :processing after_save :save_local_file before_destroy :cleanup #:remove_local_file,:destroy_thumbnails,:remove_s3_file include ActiveSupport::Callbacks define_callbacks :local_file_saved, :file_saved, :file_ready, :process_hdr, :process_hdrhtml, :process_composite, :process_tone_mapping #cattr_accessor :cloudhdr_options #self.cloudhdr_options = options cattr_accessor :cloudhdr_thumbnails self.cloudhdr_thumbnails = options[:thumbnails] ||= [] cattr_accessor :thumbnail_class self.thumbnail_class = options[:thumbnail_class] ? options[:thumbnail_class].constantize : self has_many :thumbnails, :class_name => "::#{self.thumbnail_class.name}",:as => :parent belongs_to :parent, :polymorphic => true has_many :cloudhdr_jobs, :as => :image scope :top_level, -> { where({:parent_id=>nil}) if respond_to?(:parent_id) } scope :top_level, -> { where({}) if !respond_to?(:parent_id) } # we can't just call this next scope 'parents' because that is already # taken and returns an array of parent classes of the ruby object scope :parent_items, -> { where({:parent_id=>nil}) if respond_to?(:parent_id) } scope :parent_items, -> { where({}) if !respond_to?(:parent_id) } scope :thumbnails, -> { where("#{base_class.table_name}.parent_id is not null") } #just a writer, the reader is below #cattr_accessor :cloudhdr_configuration #read_cloudhdr_configuration end #def config #return cloudhdr_configuration if !cloudhdr_configuration.blank? #self.read_cloudhdr_configuration #end def validates_cloudhdr validates_presence_of :content_type, :filename, :if=>lambda{ parent_id.blank? } end def update_from_cloudhdr(params) Rails.logger.debug "tying to call update from cloudhdr for params = #{params.to_json}" if !params[:output].blank? Rails.logger.debug "find_by_cloudhdr_output_id #{params[:output][:id]}" iu = find_by_cloudhdr_output_id params[:output][:id] Rails.logger.debug "the item = #{iu}" img_params = params[:output] iu.filename = File.basename(params[:output][:url]) #if iu.filename.blank? if ActsAsCloudhdr.storeage_mode == "local" iu.save_url(params[:output][:url]) end else iu = find_by_cloudhdr_input_id params[:input][:id] img_params = params[:input] end [:file_size,:width,:height,:taken_at,:lat,:lng].each do |att| setter = att.to_s + "=" if iu.respond_to? setter and !img_params[att].blank? iu.send setter, img_params[att] end end #iu.file_size = img_params[:file_size] #iu.width = img_params[:width] #iu.height = img_params[:height] iu.cloudhdr_status = "ready" iu.save iu end def thumbnail_attributes_for(thumbnail_name = "small") atts = self.cloudhdr_thumbnails.select{|atts| atts[:label] == thumbnail_name }.first if atts.blank? atts = create_atts_from_size_string(thumbnail_name) end if atts.blank? raise ThumbnailAttributesNotFoundError.new("No thumbnail attributes were found for label '#{thumbnail_name}'") end atts end def create_label_from_size_string(size_string) if size_string.match ActsAsCloudhdr.size_string_regex size_string = size_string.gsub("!","crop") size_string = size_string.gsub(">","preserve") end size_string end def create_atts_from_size_string(label_string) match = label_string.match ActsAsCloudhdr.label_size_regex return nil if match.blank? atts = {} if !match[1].blank? atts[:width] = match[1] end if !match[2].blank? atts[:height] = match[2] end if !match[3].blank? atts[:aspect_mode] = match[3] end atts[:label] = label_string #atts[:label] = "#{atts[:width]}x#{atts[:height]}" #atts[:label] += "_#{atts[:aspect_mode]}" if atts[:aspect_mode] atts end #def read_cloudhdr_configuration ##raise "This method is going away!" ##puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ##puts "This method is going away!" ##puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #self.cloudhdr_configuration = ActsAsCloudhdr.cloudhdr_config #self.apply_cloudhdr_configuration #end def self.cloudhdr_configuration self.config end def self.apply_cloudhdr_configuration if self.cloudhdr_configuration[:base_url] ActsAsCloudhdr.base_url = cloudhdr_configuration[:base_url] end if self.cloudhdr_configuration[:storeage_mode] ActsAsCloudhdr.storeage_mode = cloudhdr_configuration[:storeage_mode] end if self.cloudhdr_configuration[:processing_mode] ActsAsCloudhdr.processing_mode = cloudhdr_configuration[:processing_mode] end if self.cloudhdr_configuration[:s3_bucket_name] ActsAsCloudhdr.s3_bucket_name = cloudhdr_configuration[:s3_bucket_name] end if self.cloudhdr_configuration[:javascript_library] ActsAsCloudhdr.javascript_library = cloudhdr_configuration[:javascript_library] end if self.cloudhdr_configuration[:local_base_dir] ActsAsCloudhdr.local_base_dir = cloudhdr_configuration[:local_base_dir] end if self.cloudhdr_configuration[:cloudhdr_url] ::Cloudhdr.base_url = cloudhdr_configuration[:cloudhdr_url] end if self.cloudhdr_configuration[:cloudhdr_api_key] ::Cloudhdr.api_key = cloudhdr_configuration[:cloudhdr_api_key] end end module InstanceMethods def image? self.class.image?(content_type) end def web_safe? self.class.web_safe?(content_type) end def encode if image? process end end def recode reload #make sure that we have current thumbs destroy_thumbnails reload encode end def ready? if ActsAsCloudhdr.storeage_mode == "offline" true #elsif image? # return cloudhdr_status=='ready' #else # return false else return cloudhdr_status == "ready" end end def error? if ActsAsCloudhdr.storeage_mode == "offline" false #elsif image? # return cloudhdr_status=='failed' #elsif video? # return zencoder_status=='failed' #else # true else return cloudhdr_status == "ready" end end def create_thumbnails_from_response(response_thumbs,job_id) new_thumbs = [] response_thumbs.each do |thumb_params| #puts "creating a thumb for #{thumb_params["label"]}" # we do this the long way around just in case some of these # atts are attr_protected thumb = nil if respond_to?(:parent_id) and !self.parent_id.blank? Rails.logger.debug "trying to create a thumb from the parent " thumb = self.parent.thumbnails.new() self.parent.thumbnails << thumb else Rails.logger.debug "trying to create a thumb from myself " thumb = self.thumbnails.new() self.thumbnails << thumb end if self.respond_to?(:user_id) && thumb.respond_to?(:user_id=) thumb.user_id = self.user_id end thumb.thumbnail = thumb_params["label"] thumb.filename = thumb_params["filename"] thumb.width = thumb_params["width"] thumb.height = thumb_params["height"] thumb.cloudhdr_status = "processing" thumb.save new_thumbs << thumb Rails.logger.debug " thumb.errors = #{thumb.errors.to_json}" #puts " thumb.errors = #{thumb.errors.to_json}" end new_thumbs end def clear_processing processing = false end def dedupe_input_thumbs(input_thumbs) needed_thumbs = [] input_thumbs.each do |it| t = thumbnails.find_by_thumbnail(it[:label]) if t.blank? needed_thumbs << it end end needed_thumbs end def create_cloudhdr_job(params) response = nil tries = 0 max_tries = 3 sleeps = [2,4,8] while response.blank? do begin response = Cloudhdr::Job.create(params) rescue Exception => e if tries < max_tries sleep sleeps[tries] tries += 1 response = nil else raise end end end response end def process(input_thumbs = self.cloudhdr_thumbnails) #puts " input_thumbs.count = #{input_thumbs.size}" input_thumbs = dedupe_input_thumbs(input_thumbs) #puts " after dedupe input_thumbs.count = #{input_thumbs.size}" #if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size # raise "This item already has thumbnails!" # return #end return if input_thumbs.size == 0 # We do this because sometimes save will get called more than once # during a single request return if processing processing = true Rails.logger.debug "trying to process for #{Cloudhdr.base_url} " Rails.logger.debug "callback url = #{callback_url}" response = create_cloudhdr_job(cloudhdr_params(input_thumbs)) Rails.logger.debug "the process response = #{response.to_json}" if Rails.env != "test" #puts "the process response = #{response.to_json}" if Rails.env != "test" job = self.cloudhdr_jobs.new job.tracking_mode = 'job' job.cloudhdr_input_id = response.body["job"]["inputs"].first["id"] job.cloudhdr_job_id = response.body["job"]["id"] job.cloudhdr_status = "processing" job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id) self.cloudhdr_jobs << job 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 self.save #false need to do save(false) here if we're calling process on after_save response_thumbs = response.body["job"]["thumbnails"] Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}" #puts "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}" create_thumbnails_from_response(response_thumbs,response.body["job"]["id"]) end def process_hdr #if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size # raise "This item already has thumbnails!" # return #end # We do this because sometimes save will get called more than once # during a single request return if processing processing = true run_callbacks :process_hdr do Rails.logger.debug "trying to process for #{Cloudhdr.base_url} " Rails.logger.debug "callback url = #{callback_url}" response = create_cloudhdr_job(cloudhdr_hdr_params) Rails.logger.debug "the response from process_hdr = #{response.body.to_json}" job = self.cloudhdr_jobs.new job.tracking_mode = 'job' job.cloudhdr_output_id = response.body["job"]["hdr"]["id"] job.cloudhdr_job_id = response.body["job"]["id"] job.cloudhdr_status = "processing" job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id) self.cloudhdr_jobs << job self.cloudhdr_status = "processing" self.save #false need to do save(false) here if we're calling process on after_save end end def process_hdrhtml #if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size # raise "This item already has thumbnails!" # return #end # We do this because sometimes save will get called more than once # during a single request return if processing processing = true run_callbacks :process_hdrhtml do Rails.logger.debug "trying to process for #{Cloudhdr.base_url} " Rails.logger.debug "callback url = #{callback_url}" response = create_cloudhdr_job(cloudhdr_hdrhtml_params) Rails.logger.debug "the response from process_hdrhtml = #{response.body.to_json}" job = self.cloudhdr_jobs.new job.tracking_mode = 'job' job.cloudhdr_output_id = response.body["job"]["hdrhtml"]["id"] job.cloudhdr_job_id = response.body["job"]["id"] job.cloudhdr_status = "processing" job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id) self.cloudhdr_jobs << job self.cloudhdr_status = "processing" self.save #false need to do save(false) here if we're calling process on after_save end end def process_tone_mapping #if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size # raise "This item already has thumbnails!" # return #end # We do this because sometimes save will get called more than once # during a single request return if processing processing = true run_callbacks :process_tone_mapping do destroy_thumbnails Rails.logger.debug "trying to process for #{Cloudhdr.base_url} " Rails.logger.debug "callback url = #{callback_url}" response = create_cloudhdr_job(cloudhdr_tone_mapping_params) Rails.logger.debug "tone_mapping response = #{response.body.to_json}" #puts "tone_mapping response = #{response.body.to_json}" job = self.cloudhdr_jobs.new job.tracking_mode = 'job' job.cloudhdr_output_id = response.body["job"]["tone_mapping"]["id"] job.cloudhdr_job_id = response.body["job"]["id"] job.cloudhdr_status = "processing" job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id) self.cloudhdr_jobs << job self.cloudhdr_status = "processing" self.save #false need to do save(false) here if we're calling process on after_save response_thumbs = response.body["job"]["thumbnails"] Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}" create_thumbnails_from_response(response_thumbs,response.body["job"]["id"]) end end def process_composite #if self.thumbnails.count >= self.class.cloudhdr_thumbnails.size # raise "This item already has thumbnails!" # return #end # We do this because sometimes save will get called more than once # during a single request return if processing processing = true run_callbacks :process_composite do destroy_thumbnails Rails.logger.debug "trying to process for #{Cloudhdr.base_url} " Rails.logger.debug "callback url = #{callback_url}" response = create_cloudhdr_job(cloudhdr_composite_params) Rails.logger.debug "composite response = #{response.body.to_json}" #puts "composite response = #{response.body.to_json}" job = self.cloudhdr_jobs.new job.tracking_mode = 'job' job.cloudhdr_output_id = response.body["job"]["composite"]["id"] job.cloudhdr_job_id = response.body["job"]["id"] job.cloudhdr_status = "processing" job.user_id = self.user_id if (self.respond_to?(:user_id) && self.user_id) self.cloudhdr_jobs << job self.cloudhdr_status = "processing" self.save #false need to do save(false) here if we're calling process on after_save response_thumbs = response.body["job"]["thumbnails"] Rails.logger.debug "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}" #puts "trying to decode #{response_thumbs.size} response_thumbs = #{response_thumbs.to_json}" create_thumbnails_from_response(response_thumbs,response.body["job"]["id"]) end end def cloudhdr_extension if self.content_type.blank? ".jpg" else self.content_type.match(/png/) ? ".png" : ".jpg" end end def cloudhdr_params(input_thumbs = self.cloudhdr_thumbnails) {:input => {:url => self.public_url, :notifications=>[{:url=>callback_url }] }, :thumbnails => cloudhdr_thumbnail_params(input_thumbs) } end def cloudhdr_thumbnail_params(input_thumbs = self.cloudhdr_thumbnails) input_thumbs.map{|thumb| thumb_filename = thumb[:label] + "_" + File.basename(self.filename,File.extname(self.filename)) + cloudhdr_extension base_url = ActsAsCloudhdr.storeage_mode == "s3" ? "s3://#{self.s3_bucket_name}/#{self.thumbnail_resource_dir}/" : "" th = thumb.clone th[:base_url] = base_url if !base_url.blank? th.merge({ :filename=>thumb_filename, :notifications=>[{:url=>thumbnail_callback_url }] }) } end def cloudhdr_hdr_params { } end def cloudhdr_hdrhtml_params { } end def cloudhdr_tone_mapping_params { } end def cloudhdr_composite_params { } end def cloudhdr_config ActsAsCloudhdr.cloudhdr_config end def cloudhdr? true end def save_url(url) Rails.logger.debug "We are about to download : #{url} to #{local_dir} - #{local_path}" FileUtils.mkdir_p(local_dir) if !File.exists?(local_dir) FileUtils.touch local_path writeOut = open(local_path, "wb") writeOut.write(open(url).read) writeOut.close end def destroy_thumbnails if self.class.cloudhdr_thumbnails.size == 0 #puts "we're skipping destory_thumbnails since we don't do any processing " return end #puts "calling destory thumbnails for #{self.thumbnails.count} - #{self.thumbnails.size}" self.thumbnails.each do |thumb| thumb.destroy end #puts "calling destory thumbnails for #{self.thumbnails.count}" end def create_atts_from_size_string(label_string) self.class.create_atts_from_size_string(label_string) end def thumbnail_attributes_for(thumbnail_name) self.class.thumbnail_attributes_for(thumbnail_name) end def thumbnail_for(thumbnail_hash_or_name) thumbnail_name = thumbnail_hash_or_name.is_a?(Hash) ? thumbnail_hash_or_name[:label] : thumbnail_hash_or_name if thumbnail_name and thumbnail_name.match ActsAsCloudhdr.size_string_regex thumbnail_name = self.class.create_label_from_size_string(thumbnail_name) end if thumbnail_name.blank? and thumbnail_hash_or_name.is_a?(Hash) thumbnail_name = "#{thumbnail_hash_or_name[:width]}x#{thumbnail_hash_or_name[:height]}" #puts "thumbnail_name = #{thumbnail_name}" thumbnail_hash_or_name[:label] = thumbnail_name end thumb = thumbnails.find_by_thumbnail(thumbnail_name) if thumb.blank? and ActsAsCloudhdr.storeage_mode == "offline" thumb = self elsif thumb.blank? and thumbnail_hash_or_name.is_a? Hash thumb = self.process([thumbnail_hash_or_name]).first elsif thumb.blank? and thumbnail_hash_or_name.is_a?(String) and thumbnail_hash_or_name.match ActsAsCloudhdr.label_size_regex atts = create_atts_from_size_string(thumbnail_name) thumb = self.process([atts]).first end if thumb.blank? raise ThumbnailNotFoundError.new("No thumbnail was found for label '#{thumbnail_name}'") end thumb #a dirty hack for now to keep things working. #Remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!! #Go back to just returning the thumb #thumb.blank? ? self : thumb end def get_thumbnail(thumbnail_name) thumbnail_for(thumbnail_name) end def file=(new_file) return if new_file.nil? Rails.logger.debug "we got a new file of class = #{new_file.class}" cleanup if new_file.is_a? File self.filename = File.basename new_file.path self.content_type = MIME::Types.type_for(self.filename).first.content_type self.file_size = new_file.size else self.filename = new_file.original_filename self.content_type = new_file.content_type self.file_size = new_file.size end self.content_type = File.mime_type?(self.filename) if (self.content_type.blank? || self.content_type == "[]") if new_file.respond_to? :tempfile @saved_file = new_file.tempfile else @saved_file = new_file end end #compatability method for attachment_fu def uploaded_data=(data) self.file = data end def save_local_file return if @saved_file.blank? #puts "saving the local file!!!!!!" Rails.logger.debug "===================================================================================================" Rails.logger.debug "about to save the local file" run_callbacks :file_saved do run_callbacks :local_file_saved do FileUtils.mkdir_p local_dir FileUtils.cp @saved_file.path, local_path FileUtils.chmod 0755, local_path self.cloudhdr_status = "local" if self.respond_to? :upload_host self.upload_host = %x{hostname}.strip end @saved_file = nil @saved_a_new_file = true self.save end if ActsAsCloudhdr.storeage_mode == "s3" && ActsAsCloudhdr.processing_mode == "automatic" self.save_s3_file end if ActsAsCloudhdr.storeage_mode == "local" && ActsAsCloudhdr.processing_mode == "automatic" self.encode end end end def fire_ready_callback run_callbacks :file_ready do end end def cleanup #puts "calling cleanup!" destroy_thumbnails remove_local_file if ActsAsCloudhdr.storeage_mode == "s3" remove_s3_file end end def remove_local_file if local_path and File.exists? local_path FileUtils.rm local_path if Dir.glob(File.join(local_dir,"*")).size == 0 FileUtils.rmdir local_dir end end end def path_id #puts "parent_id = #{parent_id}" #puts "parent = #{parent}" if respond_to?(:parent_id) parent_id.blank? ? id : parent.path_id else id end end def resource_dir File.join(self.class.table_name, path_id.to_s ) end def thumbnail_resource_dir File.join(self.thumbnail_class.table_name, path_id.to_s ) end def local_dir File.join(ActsAsCloudhdr.local_base_dir,resource_dir) end def local_path filename.blank? ? nil : File.join(local_dir,filename) end def local_url filename.blank? ? nil : File.join("/",resource_dir,filename) end # This should generate a fully qualified http://something-something # type of a reference. Depending on storeage_mode/base_url settings. def public_url #puts "our base_url = #{base_url} and our local_url = #{local_url}" if ActsAsCloudhdr.storeage_mode == "local" or ActsAsCloudhdr.storeage_mode == "offline" base_url + local_url else self.class.cloudfront_host.present? ? cloudfront_url : s3_url end end def public_filename public_url end def callback_url self.base_url + self.notification_callback_path end def thumbnail_callback_url self.base_url + self.thumbnail_notification_callback_path end def notification_callback_path "/cloudhdr/cloudhdr_notifications/#{self.class.name}/#{self.id}.json" end def thumbnail_notification_callback_path "/cloudhdr/cloudhdr_notifications/#{self.thumbnail_class.name}/#{self.id}.json" end def base_url self.class.base_url end def s3_key filename.blank? ? nil : File.join(resource_dir,filename) end def s3_url "http://#{s3_bucket_name}.s3.amazonaws.com/#{s3_key}" end def signed_s3_url options s3_obj.url_for(:read, :expires => 10*60).to_s end def s3_bucket_name self.class.s3_bucket_name end def cloudfront_base_host host = self.class.cloudfront_host host.instance_of?(Proc) ? host.call(s3_key) : host end def cloudfront_url "#{cloudfront_base_host}/#{s3_key}" end def unused_s3_demo_stuff s3 = AWS::S3.new key,bucket = get_s3_key_and_bucket obj = s3.buckets[bucket].objects[key] obj.write(Pathname.new(tmpFile),{:acl=>:public_read,:cache_control=>'max-age=315360000'}) end def s3 @s3 ||= AWS::S3.new end def s3_obj s3.buckets[s3_bucket_name].objects[s3_key] end def save_s3_file #I don't think we need this return check anymore. #return if !@saved_a_new_file #@saved_a_new_file = false #AWS::S3::S3Object.store( #s3_key, #open(local_path), #s3_bucket_name, #:access => :public_read, #"Cache-Control" => 'max-age=315360000' #) s3_obj.write(Pathname.new(local_path),{:acl=>:public_read,:cache_control=>'max-age=315360000'}) self.cloudhdr_status = "s3" self.save #obj_data = AWS::S3::S3Object.find(s3_key,s3_bucket_name) Rails.logger.debug "----------------------------------------------------------------------------------------------------" if s3_obj.content_length == file_size # it made it into s3 safely Rails.logger.debug " we are about to remove local file!" remove_local_file else msg = "The file was not saved to S3 sucessfully. Orig size: #{file_size} - S3 size: #{obj_data.size}" Rails.logger.debug msg raise ActsAsCloudhdr::Error.new msg end self.encode end def remove_s3_file #puts "trying to delete #{s3_key} #{s3_bucket_name}" #if ActsAsCloudhdr.storeage_mode == "s3" #AWS::S3::S3Object.delete s3_key, s3_bucket_name #end s3_obj.delete rescue Exception => e #this probably means that the file never made it to S3 end # Sanitizes a filename. def filename=(new_name) write_attribute :filename, sanitize_filename(new_name) end def sanitize_filename(filename) return unless filename filename.strip.tap do |name| # NOTE: File.basename doesn't work right with Windows paths on Unix # get only the filename, not the whole path name.gsub! /^.*(\\|\/)/, '' # Finally, replace all non alphanumeric, underscore or periods with underscore name.gsub! /[^A-Za-z0-9\.\-]/, '_' end end # Calculate the width for the target thumbnail atts def calc_width(thumbnail_atts) tw = thumbnail_atts[:width].blank? ? 100000 : thumbnail_atts[:width].to_f th = thumbnail_atts[:height].blank? ? 100000 : thumbnail_atts[:height].to_f w = width.to_f h = height.to_f if w <= tw and h <= th w.round elsif w > h if (h * ( tw / w )).round < tw tw .round else (h * ( tw / w )).round end else if (w * ( th / h )).round < tw (w * ( th / h )).round else tw.round end end end #end calc_width def calc_height(thumbnail_atts) tw = thumbnail_atts[:width].blank? ? 100000 : thumbnail_atts[:width].to_f th = thumbnail_atts[:height].blank? ? 100000 : thumbnail_atts[:height].to_f w = width.to_f h = height.to_f if w <= tw and h <= th h.round elsif w > h if (h * ( tw / w )).round < th (h * ( tw / w )).round else th.round end else if (w * ( th / h )).round < tw th.round else (h * ( tw / w )).round end end end #end calc_height end#module InstanceMethods end ActiveRecord::Base.extend ActsAsCloudhdr