jeremyboles-graffic 0.2.7 → 0.3.0
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/lib/graffic.rb +80 -87
- data/lib/graffic/view_helpers.rb +1 -1
- metadata +1 -1
    
        data/lib/graffic.rb
    CHANGED
    
    | @@ -11,21 +11,26 @@ require 'graffic/view_helpers' | |
| 11 11 | 
             
            # A Graffic record progresses through four states: received, moved, uploaded and processed.
         | 
| 12 12 | 
             
            # Graffic is designed in a way to let slow operating states out of the request cycle, if desired.
         | 
| 13 13 | 
             
            #
         | 
| 14 | 
            +
            # TODO: Figure out how to make this read-only
         | 
| 15 | 
            +
            #
         | 
| 14 16 | 
             
            class Graffic < ActiveRecord::Base  
         | 
| 17 | 
            +
              after_create :move
         | 
| 15 18 | 
             
              after_destroy :delete_s3_file
         | 
| 16 19 |  | 
| 17 | 
            -
              attr_writer :file, :processor
         | 
| 18 | 
            -
              
         | 
| 19 20 | 
             
              before_validation_on_create :set_initial_state
         | 
| 20 21 |  | 
| 21 22 | 
             
              belongs_to :resource, :polymorphic => true
         | 
| 22 23 |  | 
| 23 | 
            -
              class_inheritable_accessor :bucket_name | 
| 24 | 
            +
              class_inheritable_accessor :bucket_name
         | 
| 24 25 | 
             
              class_inheritable_accessor :format, :default => 'png'
         | 
| 25 26 | 
             
              class_inheritable_accessor :process_queue_name, :default => 'graffic_process'
         | 
| 26 27 | 
             
              class_inheritable_accessor :upload_queue_name, :default => 'graffic_upload'
         | 
| 28 | 
            +
              class_inheritable_accessor :should_process_versions, :use_queue, :default => true
         | 
| 27 29 | 
             
              class_inheritable_accessor :tmp_dir, :default => RAILS_ROOT + '/tmp/graffics'
         | 
| 28 | 
            -
               | 
| 30 | 
            +
              class_inheritable_accessor :processors, :default => []
         | 
| 31 | 
            +
              class_inheritable_accessor :versions, :default => {}
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              attr_writer :file, :processors
         | 
| 29 34 |  | 
| 30 35 | 
             
              validate_on_create :file_was_given
         | 
| 31 36 |  | 
| @@ -35,6 +40,7 @@ class Graffic < ActiveRecord::Base | |
| 35 40 | 
             
                  @bucket ||= Graffic::Aws.s3.bucket(bucket_name, true, 'public-read')
         | 
| 36 41 | 
             
                end
         | 
| 37 42 |  | 
| 43 | 
            +
                # Create the tmp dir to store files until we upload them
         | 
| 38 44 | 
             
                def create_tmp_dir
         | 
| 39 45 | 
             
                  FileUtils.mkdir(tmp_dir) unless File.exists?(tmp_dir)
         | 
| 40 46 | 
             
                end
         | 
| @@ -45,7 +51,7 @@ class Graffic < ActiveRecord::Base | |
| 45 51 | 
             
                    data = YAML.load(message.to_s)
         | 
| 46 52 | 
             
                    begin
         | 
| 47 53 | 
             
                      record = find(data[:id])
         | 
| 48 | 
            -
                      record.process | 
| 54 | 
            +
                      record.process
         | 
| 49 55 | 
             
                    rescue ActiveRecord::RecordNotFound
         | 
| 50 56 | 
             
                      return 'Not found'
         | 
| 51 57 | 
             
                    ensure
         | 
| @@ -55,13 +61,14 @@ class Graffic < ActiveRecord::Base | |
| 55 61 | 
             
                end
         | 
| 56 62 |  | 
| 57 63 | 
             
                # Handles the first message in the upload queue
         | 
| 64 | 
            +
                # TODO: Figure out a better way to handle messages when records aren't there
         | 
| 58 65 | 
             
                def handle_top_in_upload_queue!
         | 
| 59 66 | 
             
                  if message = upload_queue.receive
         | 
| 60 67 | 
             
                    data = YAML.load(message.to_s)
         | 
| 61 68 | 
             
                    return if data[:hostname] != `hostname`.strip
         | 
| 62 69 | 
             
                    begin 
         | 
| 63 70 | 
             
                      record = find(data[:id])
         | 
| 64 | 
            -
                      record.upload | 
| 71 | 
            +
                      record.upload
         | 
| 65 72 | 
             
                    rescue ActiveRecord::RecordNotFound
         | 
| 66 73 | 
             
                      return 'Not found'
         | 
| 67 74 | 
             
                    ensure
         | 
| @@ -70,10 +77,13 @@ class Graffic < ActiveRecord::Base | |
| 70 77 | 
             
                  end
         | 
| 71 78 | 
             
                end
         | 
| 72 79 |  | 
| 80 | 
            +
                # DSL method for processing images
         | 
| 73 81 | 
             
                def process(&block)
         | 
| 74 | 
            -
                  self. | 
| 82 | 
            +
                  self.processors ||= []
         | 
| 83 | 
            +
                  self.processors << block if block_given?
         | 
| 75 84 | 
             
                end
         | 
| 76 85 |  | 
| 86 | 
            +
                # When we create a new type of Graffic, make sure we save the original
         | 
| 77 87 | 
             
                def inherited(subclass)
         | 
| 78 88 | 
             
                  subclass.has_one(:original, :class_name => 'Graffic', :as => :resource, :dependent => :destroy, :conditions => { :name => 'original' })
         | 
| 79 89 | 
             
                  super
         | 
| @@ -84,12 +94,10 @@ class Graffic < ActiveRecord::Base | |
| 84 94 | 
             
                  @process_queue ||= Graffic::Aws.sqs.queue(process_queue_name, true)
         | 
| 85 95 | 
             
                end
         | 
| 86 96 |  | 
| 97 | 
            +
                # DSL method for making thumbnails
         | 
| 87 98 | 
             
                def size(name, size = {})
         | 
| 88 99 | 
             
                  size.assert_valid_keys(:width, :height)
         | 
| 89 | 
            -
                  version(name)  | 
| 90 | 
            -
                    img = img.first if img.respond_to?(:first)
         | 
| 91 | 
            -
                    img.crop_resized(size[:width], size[:height])
         | 
| 92 | 
            -
                  end
         | 
| 100 | 
            +
                  version(name) { |img| img.crop_resized(size[:width], size[:height]) }
         | 
| 93 101 | 
             
                end
         | 
| 94 102 |  | 
| 95 103 | 
             
                # The queue for uploading images
         | 
| @@ -97,12 +105,11 @@ class Graffic < ActiveRecord::Base | |
| 97 105 | 
             
                  @upload_queue ||= Graffic::Aws.sqs.queue(upload_queue_name, true)
         | 
| 98 106 | 
             
                end
         | 
| 99 107 |  | 
| 108 | 
            +
                # DSL method for declaring a version of an image
         | 
| 100 109 | 
             
                def version(name, &block)
         | 
| 101 | 
            -
                  self.versions ||=  | 
| 102 | 
            -
                  if block_given?
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                    has_one(name, :class_name => 'Graffic', :as => :resource, :dependent => :destroy, :conditions => { :name => name.to_s })
         | 
| 105 | 
            -
                  end
         | 
| 110 | 
            +
                  self.versions[name] ||= []
         | 
| 111 | 
            +
                  self.versions[name] << block if block_given?
         | 
| 112 | 
            +
                  has_one(name, :class_name => 'Graffic', :as => :resource, :dependent => :destroy, :conditions => { :name => name.to_s })
         | 
| 106 113 | 
             
                end
         | 
| 107 114 | 
             
              end
         | 
| 108 115 |  | 
| @@ -111,6 +118,7 @@ class Graffic < ActiveRecord::Base | |
| 111 118 | 
             
                attributes['format'] || self.class.format
         | 
| 112 119 | 
             
              end
         | 
| 113 120 |  | 
| 121 | 
            +
              # Return an RMagick image, based on the state of image
         | 
| 114 122 | 
             
              def image
         | 
| 115 123 | 
             
                @image ||= case self.state
         | 
| 116 124 | 
             
                  when 'moved': Magick::Image.read(tmp_file_path).first
         | 
| @@ -119,70 +127,51 @@ class Graffic < ActiveRecord::Base | |
| 119 127 | 
             
              end
         | 
| 120 128 |  | 
| 121 129 | 
             
              # Move the file to the temporary directory
         | 
| 122 | 
            -
              def move | 
| 123 | 
            -
                 | 
| 124 | 
            -
                 | 
| 125 | 
            -
              end
         | 
| 126 | 
            -
              
         | 
| 127 | 
            -
              # Move the file to the temporary directory
         | 
| 128 | 
            -
              def move_without_queue!
         | 
| 130 | 
            +
              def move
         | 
| 131 | 
            +
                logger.debug("***** Moving? #{self.state}")
         | 
| 132 | 
            +
                return unless self.state == 'received'
         | 
| 129 133 | 
             
                logger.debug("***** Graffic[#{self.id}](#{self.name})#move!")
         | 
| 130 | 
            -
                 | 
| 131 | 
            -
             | 
| 132 | 
            -
                   | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
                   | 
| 136 | 
            -
             | 
| 134 | 
            +
                logger.debug("***** File type: #{@file.class.name}")
         | 
| 135 | 
            +
                if @file.is_a?(Tempfile) # Uploaded File
         | 
| 136 | 
            +
                  FileUtils.cp(@file.path, tmp_file_path)
         | 
| 137 | 
            +
                  logger.debug("***** Moving file: #{@file.path}, #{tmp_file_path}")
         | 
| 138 | 
            +
                elsif @file.is_a?(String) # String representing a file's location
         | 
| 139 | 
            +
                  FileUtils.cp(@file.strip, tmp_file_path)
         | 
| 140 | 
            +
                  logger.debug("***** Moving file: #{@file.strip}, #{tmp_file_path}")
         | 
| 141 | 
            +
                elsif @file.is_a?(Magick::Image) # An actually RMagick file
         | 
| 137 142 | 
             
                  @image = @file
         | 
| 138 | 
            -
                   | 
| 143 | 
            +
                  self.use_queue = false
         | 
| 139 144 | 
             
                  change_state('uploaded')
         | 
| 145 | 
            +
                  process
         | 
| 146 | 
            +
                  return
         | 
| 147 | 
            +
                else
         | 
| 148 | 
            +
                  raise "Don't know how to handle file type #{@file.class.name}"
         | 
| 140 149 | 
             
                end
         | 
| 150 | 
            +
                
         | 
| 151 | 
            +
                change_state('moved')
         | 
| 152 | 
            +
                use_queue? ? queue_for_upload : upload
         | 
| 141 153 | 
             
              end
         | 
| 142 154 |  | 
| 143 | 
            -
               | 
| 144 | 
            -
              def  | 
| 145 | 
            -
                 | 
| 146 | 
            -
                process_versions
         | 
| 155 | 
            +
              attr_accessor :should_process_versions
         | 
| 156 | 
            +
              def should_process_versions?
         | 
| 157 | 
            +
                should_process_versions.nil? ? self.class.should_process_versions : should_process_versions
         | 
| 147 158 | 
             
              end
         | 
| 148 159 |  | 
| 149 | 
            -
              # Process the image | 
| 150 | 
            -
              def  | 
| 160 | 
            +
              # Process the image
         | 
| 161 | 
            +
              def process
         | 
| 162 | 
            +
                return unless self.state == 'uploaded'
         | 
| 151 163 | 
             
                logger.debug("***** Graffic[#{self.id}](#{self.name})#process!")
         | 
| 152 164 | 
             
                run_processors
         | 
| 153 165 | 
             
                record_image_dimensions_and_format
         | 
| 154 166 | 
             
                upload_image
         | 
| 155 167 | 
             
                change_state('processed')
         | 
| 168 | 
            +
                
         | 
| 169 | 
            +
                process_versions if should_process_versions?
         | 
| 156 170 | 
             
              end
         | 
| 157 | 
            -
             | 
| 171 | 
            +
             | 
| 158 172 | 
             
              # Returns the processor for the instance
         | 
| 159 | 
            -
              def  | 
| 160 | 
            -
                @ | 
| 161 | 
            -
              end
         | 
| 162 | 
            -
              
         | 
| 163 | 
            -
              # Move the file if it saved successfully
         | 
| 164 | 
            -
              def save_and_move
         | 
| 165 | 
            -
                move! if status = save
         | 
| 166 | 
            -
                status
         | 
| 167 | 
            -
              end
         | 
| 168 | 
            -
              
         | 
| 169 | 
            -
              # Save the file and process it immediately. Does to use queues.
         | 
| 170 | 
            -
              def save_and_process
         | 
| 171 | 
            -
                if status = save
         | 
| 172 | 
            -
                  move_without_queue!
         | 
| 173 | 
            -
                  upload_without_queue!
         | 
| 174 | 
            -
                  process!
         | 
| 175 | 
            -
                end
         | 
| 176 | 
            -
                status
         | 
| 177 | 
            -
              end
         | 
| 178 | 
            -
              
         | 
| 179 | 
            -
              def save_and_process_without_versions
         | 
| 180 | 
            -
                if status = save
         | 
| 181 | 
            -
                  move_without_queue!
         | 
| 182 | 
            -
                  upload_without_queue!
         | 
| 183 | 
            -
                  process_without_verions!
         | 
| 184 | 
            -
                end
         | 
| 185 | 
            -
                status
         | 
| 173 | 
            +
              def processors
         | 
| 174 | 
            +
                @processors || self.class.processors
         | 
| 186 175 | 
             
              end
         | 
| 187 176 |  | 
| 188 177 | 
             
              # Returns a size string.  Good for RMagick and image_tag :size
         | 
| @@ -191,18 +180,15 @@ class Graffic < ActiveRecord::Base | |
| 191 180 | 
             
              end
         | 
| 192 181 |  | 
| 193 182 | 
             
              # Upload the file
         | 
| 194 | 
            -
              def upload | 
| 195 | 
            -
                 | 
| 196 | 
            -
                queue_for_processing
         | 
| 197 | 
            -
              end
         | 
| 198 | 
            -
              
         | 
| 199 | 
            -
              # Upload the file
         | 
| 200 | 
            -
              def upload_without_queue!
         | 
| 183 | 
            +
              def upload
         | 
| 184 | 
            +
                return unless self.state == 'moved'
         | 
| 201 185 | 
             
                logger.debug("***** Graffic[#{self.id}](#{self.name})#upload!")
         | 
| 202 186 | 
             
                upload_image
         | 
| 203 187 | 
             
                save_original
         | 
| 204 188 | 
             
                remove_tmp_file
         | 
| 189 | 
            +
                
         | 
| 205 190 | 
             
                change_state('uploaded')
         | 
| 191 | 
            +
                use_queue? ? queue_for_processing : process
         | 
| 206 192 | 
             
              end
         | 
| 207 193 |  | 
| 208 194 | 
             
              # Return the url for displaying the image
         | 
| @@ -210,6 +196,11 @@ class Graffic < ActiveRecord::Base | |
| 210 196 | 
             
                self.s3_key.public_link
         | 
| 211 197 | 
             
              end
         | 
| 212 198 |  | 
| 199 | 
            +
              attr_accessor :use_queue
         | 
| 200 | 
            +
              def use_queue?
         | 
| 201 | 
            +
                use_queue.nil? ? self.class.use_queue : use_queue
         | 
| 202 | 
            +
              end
         | 
| 203 | 
            +
              
         | 
| 213 204 | 
             
            protected
         | 
| 214 205 |  | 
| 215 206 | 
             
              # Connivence method for getting the bucket
         | 
| @@ -243,15 +234,12 @@ protected | |
| 243 234 | 
             
              end
         | 
| 244 235 |  | 
| 245 236 | 
             
              def process_versions
         | 
| 246 | 
            -
                 | 
| 247 | 
            -
                  self. | 
| 248 | 
            -
             | 
| 249 | 
            -
             | 
| 250 | 
            -
             | 
| 251 | 
            -
             | 
| 252 | 
            -
                    self.update_attribute(version, g)
         | 
| 253 | 
            -
                  end
         | 
| 254 | 
            -
                end
         | 
| 237 | 
            +
                self.versions.each do |version, processors|
         | 
| 238 | 
            +
                  logger.debug("***** Graffic[#{self.id}](#{self.name}): Processing version: #{version} (#{processors.size} processors)")
         | 
| 239 | 
            +
                  g = Graffic.new(:file => self.image, :name => version.to_s, :use_queue => false)
         | 
| 240 | 
            +
                  g.processors += processors unless processors.nil?
         | 
| 241 | 
            +
                  self.update_attribute(version, g)
         | 
| 242 | 
            +
                end unless self.versions.blank?
         | 
| 255 243 | 
             
              end
         | 
| 256 244 |  | 
| 257 245 | 
             
              def queue_for_upload
         | 
| @@ -281,11 +269,17 @@ protected | |
| 281 269 | 
             
              end
         | 
| 282 270 |  | 
| 283 271 | 
             
              def run_processors
         | 
| 284 | 
            -
                logger.debug("***** Graffic[#{self.id}](#{self.name}): Running processor")
         | 
| 285 | 
            -
                 | 
| 286 | 
            -
                   | 
| 272 | 
            +
                logger.debug("***** Graffic[#{self.id}](#{self.name}): Running processor (#{self.processors.try(:size)} processors)")
         | 
| 273 | 
            +
                self.processors.each do |processor|
         | 
| 274 | 
            +
                  img = self.image
         | 
| 275 | 
            +
                  img = img.first if img.respond_to?(:first)
         | 
| 276 | 
            +
                  @image =  case processor.arity # Pass in the record itself, if the block wants it
         | 
| 277 | 
            +
                    when 1: processor.call(img)
         | 
| 278 | 
            +
                    when 2: processor.call(img, self)
         | 
| 279 | 
            +
                  end
         | 
| 287 280 | 
             
                  raise 'You need to return an image' unless @image.is_a?(Magick::Image)
         | 
| 288 | 
            -
             | 
| 281 | 
            +
                  logger.debug("Returned Image Size: #{@image.columns}x#{@image.rows}")
         | 
| 282 | 
            +
                end unless self.processors.blank?
         | 
| 289 283 | 
             
              end
         | 
| 290 284 |  | 
| 291 285 | 
             
              def s3_key
         | 
| @@ -295,8 +289,7 @@ protected | |
| 295 289 | 
             
              def save_original
         | 
| 296 290 | 
             
                if respond_to?(:original)
         | 
| 297 291 | 
             
                  logger.debug("***** Graffic[#{self.id}](#{self.name}): Saving Original")
         | 
| 298 | 
            -
                  g = Graffic.new(:file => tmp_file_path, :name => 'original')
         | 
| 299 | 
            -
                  g.save_and_process
         | 
| 292 | 
            +
                  g = Graffic.new(:file => tmp_file_path, :name => 'original', :use_queue => false)
         | 
| 300 293 | 
             
                  self.update_attribute(:original, g)
         | 
| 301 294 | 
             
                end
         | 
| 302 295 | 
             
              end
         | 
    
        data/lib/graffic/view_helpers.rb
    CHANGED