lib/attached/attachment.rb in attached-0.0.9 vs lib/attached/attachment.rb in attached-0.1.0
- old
+ new
@@ -1,25 +1,42 @@
require 'guid'
require 'attached/storage'
+require 'attached/processor'
+require 'attached/image'
module Attached
class Attachment
attr_reader :file
attr_reader :name
attr_reader :instance
attr_reader :options
+ attr_reader :queue
+ attr_reader :path
+ attr_reader :styles
+ attr_reader :default
+ attr_reader :medium
+ attr_reader :credentials
+ attr_reader :processors
+ attr_reader :processor
+ # A default set of options that can be extended to customize the path, storage or credentials.
+ #
+ # Usage:
+ #
+ # Attached::Attachment.options = { :storage => :fs, :path => "/:name/:style/:identifier:extension" }
+
def self.options
@options ||= {
- :storage => :s3,
- :path => "/:name/:style/:identifier:extension",
- :styles => {},
+ :path => "/:name/:style/:identifier:extension",
+ :default => :original,
+ :styles => {},
+ :processors => [],
}
end
# Initialize a new attachment by providing a name and the instance the attachment is associated with.
@@ -32,76 +49,103 @@
# Options:
#
# * :path - The location where the attachment is stored
# * :storage - The storage medium represented as a symbol such as ':s3'
# * :credentials - A file, hash, or path used to authenticate with the specified storage medium
+ # * :styles - A hash containing optional parameters including extension and identifier
def initialize(name, instance, options = {})
- @name = name
- @instance = instance
+ @name = name
+ @instance = instance
+ @options = self.class.options.merge(options)
- @options = self.class.options.merge(options)
+ @queue = {}
+
+ @path = @options[:path]
+ @styles = @options[:styles]
+ @default = @options[:default]
+ @medium = @options[:medium]
+ @credentials = @options[:credentials]
+ @processors = @options[:processors]
+ @processor = @options[:processor]
+
+ @processors << @processor if @processor
end
- #
+ # Check if an attachment has been modified.
#
# Usage:
#
# @object.avatar.changed?
def changed?
instance.changed.include? "#{name}_identifier"
end
+ # Assign an attachment to a file.
+ #
# Usage:
#
# @object.avatar.assign(...)
def assign(file, identifier = Guid.new)
@file = file.tempfile
extension = File.extname(file.original_filename)
-
+
instance_set :size, file.size
instance_set :extension, extension
instance_set :identifier, identifier
+
+ self.queue[self.default] = self.file
+
+ process
end
+ # Save an attachment.
+ #
# Usage:
#
# @object.avatar.save
def save
- @storage ||= Attached::Storage.medium(options[:storage], options[:credentials])
+ @storage ||= Attached::Storage.storage(self.medium, self.credentials)
- @storage.save(self.file, self.path) if self.file and self.path
+ @queue.each do |style, file|
+ @storage.save(file, self.path(style)) if file and self.path(style)
+ end
+
+ @queue = {}
end
+ # Destroy an attachment.
+ #
# Usage:
#
# @object.avatar.destroy
def destroy
- @storage ||= Attached::Storage.medium(options[:storage], options[:credentials])
+ @storage ||= Attached::Storage.storage(self.medium, self.credentials)
@storage.destroy(self.path) if self.path
end
+
# Acesss the URL for an attachment.
#
# Usage:
#
# @object.avatar.url
# @object.avatar.url(:small)
# @object.avatar.url(:large)
- def url(style = :original)
- @storage ||= Attached::Storage.medium(options[:storage], options[:credentials])
+ def url(style = self.default)
+ @storage ||= Attached::Storage.storage(self.medium, self.credentials)
return "#{@storage.host}#{path(style)}"
end
@@ -111,21 +155,22 @@
#
# @object.avatar.url
# @object.avatar.url(:small)
# @object.avatar.url(:large)
- def path(style = :original)
- path = options[:path].clone
+ def path(style = self.default)
+ path = @path.clone
path.gsub!(/:name/, name.to_s)
path.gsub!(/:style/, style.to_s)
path.gsub!(/:extension/, extension(style).to_s)
path.gsub!(/:identifier/, identifier(style).to_s)
return path
end
+
# Access the size for an attachment.
#
# Usage:
#
# @object.avatar.size
@@ -142,28 +187,29 @@
#
# @object.avatar.extension
def extension(style = nil)
style and
- options[:styles] and
- options[:styles][style] and
- options[:styles][style][:extension] or
+ self.styles and
+ self.styles[style] and
+ self.styles[style][:extension] or
instance_get(:extension)
end
+
# Access the identifier for an attachment. It will first check the styles
# to see if one is specified before checking the instance.
#
# Usage:
#
# @object.avatar.identifier
def identifier(style = nil)
style and
- options[:styles] and
- options[:styles][style] and
- options[:styles][style][:identifier] or
+ self.styles and
+ self.styles[style] and
+ self.styles[style][:identifier] or
instance_get(:identifier)
end
# Set the extension for an attachment. It will act independently of the
@@ -189,20 +235,36 @@
end
private
+ # Helper function for calling processors.
+ #
+ # Usage:
+ #
+ # self.process
+
+ def process
+ @processors.each do |processor|
+ self.styles.each do |style, options|
+ case processor
+ when :image then self.queue[style] = Attached::Image.process(self.queue[style] || self.file, options, self)
+ end
+ end
+ end
+ end
+
# Helper function for setting instance variables.
#
# Usage:
#
# self.instance_set(size, 12345)
def instance_set(attribute, value)
setter = :"#{self.name}_#{attribute}="
- self.instance.send(setter, value)
+ self.instance.send(setter, value) if instance.respond_to?(setter)
end
# Helper function for getting instance variables.
#
@@ -210,10 +272,10 @@
#
# self.instance_get(size)
def instance_get(attribute)
getter = :"#{self.name}_#{attribute}"
- self.instance.send(getter)
+ self.instance.send(getter) if instance.respond_to?(getter)
end
end
\ No newline at end of file