Permalink
Browse files

Extract options into a new class, so they can be toyed with

  • Loading branch information...
1 parent 9edeb01 commit b948f968c494478da5dd18dcbae4f588a5a81eb5 @jyurek jyurek committed Sep 16, 2011
View
@@ -18,5 +18,4 @@ gem "shoulda"
gem "sqlite3", "~>1.3.4"
gem "fakeweb", :require => false
-# gem "ruby-debug", :platform => :ruby_18
-# gem "ruby-debug19", :platform => :ruby_19
+gem 'pry'
View
@@ -1,6 +1,6 @@
require 'rubygems'
-require 'appraisal'
require 'bundler/setup'
+require 'appraisal'
require 'rake'
require 'rake/testtask'
View
@@ -19,6 +19,7 @@ gem "cucumber", "~> 1.0.0"
gem "shoulda"
gem "sqlite3", "~>1.3.4"
gem "fakeweb", :require=>false
+gem "pry"
gem "rails", "~> 2.3.14"
gem "paperclip", :path=>"../"
View
@@ -19,6 +19,7 @@ gem "cucumber", "~> 1.0.0"
gem "shoulda"
gem "sqlite3", "~>1.3.4"
gem "fakeweb", :require=>false
+gem "pry"
gem "rails", "~> 3.0.10"
gem "paperclip", :path=>"../"
@@ -19,6 +19,7 @@ gem "cucumber", "~> 1.0.0"
gem "shoulda"
gem "sqlite3", "~>1.3.4"
gem "fakeweb", :require=>false
+gem "pry"
gem "rails", "~> 3.1.0"
gem "paperclip", :path=>"../"
View
@@ -28,6 +28,7 @@
require 'erb'
require 'digest'
require 'tempfile'
+require 'paperclip/options'
require 'paperclip/version'
require 'paperclip/upfile'
require 'paperclip/iostream'
@@ -29,7 +29,7 @@ def self.default_options
}
end
- attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options, :source_file_options, :interpolator
+ attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options, :interpolator
attr_accessor :post_processing
# Creates an Attachment object. +name+ is the name of the attachment,
@@ -62,27 +62,7 @@ def initialize name, instance, options = {}
options = self.class.default_options.merge(options)
- @url = options[:url]
- @url = @url.call(self) if @url.is_a?(Proc)
- @path = options[:path]
- @path = @path.call(self) if @path.is_a?(Proc)
- @styles = options[:styles]
- @only_process = options[:only_process]
- @normalized_styles = nil
- @default_url = options[:default_url]
- @default_style = options[:default_style]
- @storage = options[:storage]
- @use_timestamp = options[:use_timestamp]
- @whiny = options[:whiny_thumbnails] || options[:whiny]
- @use_default_time_zone = options[:use_default_time_zone]
- @hash_digest = options[:hash_digest]
- @hash_data = options[:hash_data]
- @hash_secret = options[:hash_secret]
- @convert_options = options[:convert_options]
- @source_file_options = options[:source_file_options]
- @processors = options[:processors]
- @preserve_files = options[:preserve_files]
- @options = options
+ @options = Paperclip::Options.new(self, options)
@post_processing = true
@queued_for_delete = []
@queued_for_write = {}
@@ -93,19 +73,13 @@ def initialize name, instance, options = {}
initialize_storage
end
- def styles
- if @styles.respond_to?(:call) || !@normalized_styles
- @normalized_styles = ActiveSupport::OrderedHash.new
- (@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
- @normalized_styles[name] = Paperclip::Style.new(name, args.dup, self)
- end
- end
- @normalized_styles
- end
-
- def processors
- @processors.respond_to?(:call) ? @processors.call(instance) : @processors
- end
+ # [:url, :path, :only_process, :normalized_styles, :default_url, :default_style,
+ # :storage, :use_timestamp, :whiny, :use_default_time_zone, :hash_digest, :hash_secret,
+ # :convert_options, :preserve_files].each do |field|
+ # define_method field do
+ # @options.send(field)
+ # end
+ # end
# What gets called when you call instance.attachment = File. It clears
# errors, assigns attributes, and processes the file. It
@@ -139,7 +113,7 @@ def assign uploaded_file
@dirty = true
- post_process(*@only_process) if post_processing
+ post_process(*@options.only_process) if post_processing
# Reset the file size if the original file was reprocessed.
instance_write(:file_size, @queued_for_write[:original].size.to_i)
@@ -154,9 +128,9 @@ def assign uploaded_file
# grained security. This is not recommended if you don't need the
# security, however, for performance reasons. Set use_timestamp to false
# if you want to stop the attachment update time appended to the url
- def url(style_name = default_style, use_timestamp = @use_timestamp)
- default_url = @default_url.is_a?(Proc) ? @default_url.call(self) : @default_url
- url = original_filename.nil? ? interpolate(default_url, style_name) : interpolate(@url, style_name)
+ def url(style_name = default_style, use_timestamp = @options.use_timestamp)
+ default_url = @options.default_url.is_a?(Proc) ? @options.default_url.call(self) : @options.default_url
+ url = original_filename.nil? ? interpolate(default_url, style_name) : interpolate(@options.url, style_name)
URI.escape(use_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url)
end
@@ -165,14 +139,22 @@ def url(style_name = default_style, use_timestamp = @use_timestamp)
# on disk. If the file is stored in S3, the path is the "key" part of the
# URL, and the :bucket option refers to the S3 bucket.
def path(style_name = default_style)
- original_filename.nil? ? nil : interpolate(@path, style_name)
+ original_filename.nil? ? nil : interpolate(@options.path, style_name)
end
# Alias to +url+
def to_s style_name = default_style
url(style_name)
end
+ def default_style
+ @options.default_style
+ end
+
+ def styles
+ @options.styles
+ end
+
# Returns an array containing the errors on this attachment.
def errors
@errors
@@ -205,7 +187,7 @@ def clear
# nil to the attachment *and saving*. This is permanent. If you wish to
# wipe out the existing attachment but not save, use #clear.
def destroy
- unless @preserve_files
+ unless @options.preserve_files
clear
save
end
@@ -245,16 +227,16 @@ def updated_at
# The time zone to use for timestamp interpolation. Using the default
# time zone ensures that results are consistent across all threads.
def time_zone
- @use_default_time_zone ? Time.zone_default : Time.zone
+ @options.use_default_time_zone ? Time.zone_default : Time.zone
end
# Returns a unique hash suitable for obfuscating the URL of an otherwise
# publicly viewable attachment.
def hash(style_name = default_style)
- raise ArgumentError, "Unable to generate hash without :hash_secret" unless @hash_secret
+ raise ArgumentError, "Unable to generate hash without :hash_secret" unless @options.hash_secret
require 'openssl' unless defined?(OpenSSL)
- data = interpolate(@hash_data, style_name)
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@hash_digest).new, @hash_secret, data)
+ data = interpolate(@options.hash_data, style_name)
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@options.hash_digest).new, @options.hash_secret, data)
end
def generate_fingerprint(source)
@@ -352,28 +334,28 @@ def valid_assignment? file #:nodoc:
end
def initialize_storage #:nodoc:
- storage_class_name = @storage.to_s.downcase.camelize
+ storage_class_name = @options.storage.to_s.downcase.camelize
begin
- @storage_module = Paperclip::Storage.const_get(storage_class_name)
+ storage_module = Paperclip::Storage.const_get(storage_class_name)
rescue NameError
raise StorageMethodNotFound, "Cannot load storage module '#{storage_class_name}'"
end
- self.extend(@storage_module)
+ self.extend(storage_module)
end
def extra_options_for(style) #:nodoc:
- all_options = convert_options[:all]
+ all_options = @options.convert_options[:all]
all_options = all_options.call(instance) if all_options.respond_to?(:call)
- style_options = convert_options[style]
+ style_options = @options.convert_options[style]
style_options = style_options.call(instance) if style_options.respond_to?(:call)
[ style_options, all_options ].compact.join(" ")
end
def extra_source_file_options_for(style) #:nodoc:
- all_options = source_file_options[:all]
+ all_options = @options.source_file_options[:all]
all_options = all_options.call(instance) if all_options.respond_to?(:call)
- style_options = source_file_options[style]
+ style_options = @options.source_file_options[style]
style_options = style_options.call(instance) if style_options.respond_to?(:call)
[ style_options, all_options ].compact.join(" ")
@@ -389,7 +371,7 @@ def post_process(*style_args) #:nodoc:
end
def post_process_styles(*style_args) #:nodoc:
- styles.each do |name, style|
+ @options.styles.each do |name, style|
begin
if style_args.empty? || style_args.include?(name)
raise RuntimeError.new("Style #{name} has no processors defined.") if style.processors.blank?
@@ -399,7 +381,7 @@ def post_process_styles(*style_args) #:nodoc:
end
rescue PaperclipError => e
log("An error was received while processing: #{e.inspect}")
- (@errors[:processing] ||= []) << e.message if @whiny
+ (@errors[:processing] ||= []) << e.message if @options.whiny
end
end
end
@@ -409,8 +391,8 @@ def interpolate(pattern, style_name = default_style) #:nodoc:
end
def queue_existing_for_delete #:nodoc:
- return unless (file? && @preserve_files==false)
- @queued_for_delete += [:original, *styles.keys].uniq.map do |style|
+ return if @options.preserve_files || !file?
+ @queued_for_delete += [:original, *@options.styles.keys].uniq.map do |style|
path(style) if exists?(style)
end.compact
instance_write(:file_name, nil)
View
@@ -0,0 +1,78 @@
+module Paperclip
+ class Options
+
+ attr_accessor :url, :path, :only_process, :normalized_styles, :default_url, :default_style,
+ :storage, :use_timestamp, :whiny, :use_default_time_zone, :hash_digest, :hash_secret,
+ :convert_options, :source_file_options, :preserve_files, :http_proxy
+
+ attr_accessor :s3_credentials, :s3_host_name, :s3_options, :s3_permissions, :s3_protocol,
+ :s3_headers, :s3_host_alias, :bucket
+
+ attr_accessor :fog_directory, :fog_credentials, :fog_host, :fog_public, :fog_file
+
+ def initialize(attachment, hash)
+ @attachment = attachment
+
+ @url = hash[:url]
+ @url = @url.call(@attachment) if @url.is_a?(Proc)
+ @path = hash[:path]
+ @path = @path.call(@attachment) if @path.is_a?(Proc)
+ @styles = hash[:styles]
+ @only_process = hash[:only_process]
+ @normalized_styles = nil
+ @default_url = hash[:default_url]
+ @default_style = hash[:default_style]
+ @storage = hash[:storage]
+ @use_timestamp = hash[:use_timestamp]
+ @whiny = hash[:whiny_thumbnails] || hash[:whiny]
+ @use_default_time_zone = hash[:use_default_time_zone]
+ @hash_digest = hash[:hash_digest]
+ @hash_data = hash[:hash_data]
+ @hash_secret = hash[:hash_secret]
+ @convert_options = hash[:convert_options]
+ @source_file_options = hash[:source_file_options]
+ @processors = hash[:processors]
+ @preserve_files = hash[:preserve_files]
+ @http_proxy = hash[:http_proxy]
+
+ #s3 options
+ @s3_credentials = hash[:s3_credentials]
+ @s3_host_name = hash[:s3_host_name]
+ @bucket = hash[:bucket]
+ @s3_options = hash[:s3_options]
+ @s3_permissions = hash[:s3_permissions]
+ @s3_protocol = hash[:s3_protocol]
+ @s3_headers = hash[:s3_headers]
+ @s3_host_alias = hash[:s3_host_alias]
+
+ #fog options
+ @fog_directory = hash[:fog_directory]
+ @fog_credentials = hash[:fog_credentials]
+ @fog_host = hash[:fog_host]
+ @fog_public = hash[:fog_public]
+ @fog_file = hash[:fog_file]
+ end
+
+ def method_missing(method, *args, &blk)
+ if method[-1] == "="
+ instance_variable_set("@#{method[0..-2]}", args[0])
+ else
+ instance_variable_get("@#{method}")
+ end
+ end
+
+ def processors
+ @processors.respond_to?(:call) ? @processors.call(instance) : @processors
+ end
+
+ def styles
+ if @styles.respond_to?(:call) || !@normalized_styles
+ normalized_styles = ActiveSupport::OrderedHash.new
+ (@styles.respond_to?(:call) ? @styles.call(@attachment) : @styles).each do |name, args|
+ normalized_styles[name] = Paperclip::Style.new(name, args.dup, @attachment)
+ end
+ end
+ normalized_styles
+ end
+ end
+end
Oops, something went wrong.

1 comment on commit b948f96

Contributor

monde commented on b948f96 Oct 21, 2011

I like pulling options out into the object Paperclip::Options. Perhaps the options instance variables could be mixed in our sub-classed based on the storage strategy instead filesystem, fog, and s3 variables on the base class. For instance, such as how Paperclip::Storage::S3 is extended onto attachment when it is initialized and storage is set to s3.

Please sign in to comment.