paperclip 2.4.2 → 2.4.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- data/Rakefile +1 -1
- data/lib/paperclip.rb +5 -2
- data/lib/paperclip/attachment.rb +38 -56
- data/lib/paperclip/geometry.rb +6 -4
- data/lib/paperclip/missing_attachment_styles.rb +2 -1
- data/lib/paperclip/options.rb +78 -0
- data/lib/paperclip/storage/fog.rb +21 -15
- data/lib/paperclip/storage/s3.rb +28 -25
- data/lib/paperclip/style.rb +3 -3
- data/lib/paperclip/version.rb +1 -1
- data/test/attachment_test.rb +16 -29
- data/test/fog_test.rb +4 -4
- data/test/geometry_test.rb +1 -1
- data/test/helper.rb +1 -0
- data/test/options_test.rb +68 -0
- data/test/paperclip_missing_attachment_styles_test.rb +1 -1
- data/test/storage/s3_test.rb +12 -4
- data/test/style_test.rb +22 -28
- metadata +111 -164
data/Rakefile
CHANGED
data/lib/paperclip.rb
CHANGED
@@ -28,6 +28,7 @@
|
|
28
28
|
require 'erb'
|
29
29
|
require 'digest'
|
30
30
|
require 'tempfile'
|
31
|
+
require 'paperclip/options'
|
31
32
|
require 'paperclip/version'
|
32
33
|
require 'paperclip/upfile'
|
33
34
|
require 'paperclip/iostream'
|
@@ -137,8 +138,10 @@ module Paperclip
|
|
137
138
|
@known_processors[name.to_s] = processor
|
138
139
|
end
|
139
140
|
|
141
|
+
# Find all instances of the given Active Record model +klass+ with attachment +name+.
|
142
|
+
# This method is used by the refresh rake tasks.
|
140
143
|
def each_instance_with_attachment(klass, name)
|
141
|
-
class_for(klass).all.each do |instance|
|
144
|
+
class_for(klass).find(:all, :order => 'id').each do |instance|
|
142
145
|
yield(instance) if instance.send(:"#{name}?")
|
143
146
|
end
|
144
147
|
end
|
@@ -317,7 +320,7 @@ module Paperclip
|
|
317
320
|
end
|
318
321
|
|
319
322
|
attachment_definitions[name] = {:validations => []}.merge(options)
|
320
|
-
Paperclip.classes_with_attachments << self
|
323
|
+
Paperclip.classes_with_attachments << self.name
|
321
324
|
Paperclip.check_for_url_clash(name,attachment_definitions[name][:url],self.name)
|
322
325
|
|
323
326
|
after_save :save_attached_files
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -29,7 +29,7 @@ module Paperclip
|
|
29
29
|
}
|
30
30
|
end
|
31
31
|
|
32
|
-
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options, :
|
32
|
+
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options, :interpolator
|
33
33
|
attr_accessor :post_processing
|
34
34
|
|
35
35
|
# Creates an Attachment object. +name+ is the name of the attachment,
|
@@ -62,27 +62,7 @@ module Paperclip
|
|
62
62
|
|
63
63
|
options = self.class.default_options.merge(options)
|
64
64
|
|
65
|
-
@
|
66
|
-
@url = @url.call(self) if @url.is_a?(Proc)
|
67
|
-
@path = options[:path]
|
68
|
-
@path = @path.call(self) if @path.is_a?(Proc)
|
69
|
-
@styles = options[:styles]
|
70
|
-
@only_process = options[:only_process]
|
71
|
-
@normalized_styles = nil
|
72
|
-
@default_url = options[:default_url]
|
73
|
-
@default_style = options[:default_style]
|
74
|
-
@storage = options[:storage]
|
75
|
-
@use_timestamp = options[:use_timestamp]
|
76
|
-
@whiny = options[:whiny_thumbnails] || options[:whiny]
|
77
|
-
@use_default_time_zone = options[:use_default_time_zone]
|
78
|
-
@hash_digest = options[:hash_digest]
|
79
|
-
@hash_data = options[:hash_data]
|
80
|
-
@hash_secret = options[:hash_secret]
|
81
|
-
@convert_options = options[:convert_options]
|
82
|
-
@source_file_options = options[:source_file_options]
|
83
|
-
@processors = options[:processors]
|
84
|
-
@preserve_files = options[:preserve_files]
|
85
|
-
@options = options
|
65
|
+
@options = Paperclip::Options.new(self, options)
|
86
66
|
@post_processing = true
|
87
67
|
@queued_for_delete = []
|
88
68
|
@queued_for_write = {}
|
@@ -93,19 +73,13 @@ module Paperclip
|
|
93
73
|
initialize_storage
|
94
74
|
end
|
95
75
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@normalized_styles
|
104
|
-
end
|
105
|
-
|
106
|
-
def processors
|
107
|
-
@processors.respond_to?(:call) ? @processors.call(instance) : @processors
|
108
|
-
end
|
76
|
+
# [:url, :path, :only_process, :normalized_styles, :default_url, :default_style,
|
77
|
+
# :storage, :use_timestamp, :whiny, :use_default_time_zone, :hash_digest, :hash_secret,
|
78
|
+
# :convert_options, :preserve_files].each do |field|
|
79
|
+
# define_method field do
|
80
|
+
# @options.send(field)
|
81
|
+
# end
|
82
|
+
# end
|
109
83
|
|
110
84
|
# What gets called when you call instance.attachment = File. It clears
|
111
85
|
# errors, assigns attributes, and processes the file. It
|
@@ -139,7 +113,7 @@ module Paperclip
|
|
139
113
|
|
140
114
|
@dirty = true
|
141
115
|
|
142
|
-
post_process(*@only_process) if post_processing
|
116
|
+
post_process(*@options.only_process) if post_processing
|
143
117
|
|
144
118
|
# Reset the file size if the original file was reprocessed.
|
145
119
|
instance_write(:file_size, @queued_for_write[:original].size.to_i)
|
@@ -154,9 +128,9 @@ module Paperclip
|
|
154
128
|
# grained security. This is not recommended if you don't need the
|
155
129
|
# security, however, for performance reasons. Set use_timestamp to false
|
156
130
|
# if you want to stop the attachment update time appended to the url
|
157
|
-
def url(style_name = default_style, use_timestamp = @use_timestamp)
|
158
|
-
default_url = @default_url.is_a?(Proc) ? @default_url.call(self) : @default_url
|
159
|
-
url = original_filename.nil? ? interpolate(default_url, style_name) : interpolate(@url, style_name)
|
131
|
+
def url(style_name = default_style, use_timestamp = @options.use_timestamp)
|
132
|
+
default_url = @options.default_url.is_a?(Proc) ? @options.default_url.call(self) : @options.default_url
|
133
|
+
url = original_filename.nil? ? interpolate(default_url, style_name) : interpolate(@options.url, style_name)
|
160
134
|
URI.escape(use_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url)
|
161
135
|
end
|
162
136
|
|
@@ -165,7 +139,7 @@ module Paperclip
|
|
165
139
|
# on disk. If the file is stored in S3, the path is the "key" part of the
|
166
140
|
# URL, and the :bucket option refers to the S3 bucket.
|
167
141
|
def path(style_name = default_style)
|
168
|
-
original_filename.nil? ? nil : interpolate(@path, style_name)
|
142
|
+
original_filename.nil? ? nil : interpolate(@options.path, style_name)
|
169
143
|
end
|
170
144
|
|
171
145
|
# Alias to +url+
|
@@ -173,6 +147,14 @@ module Paperclip
|
|
173
147
|
url(style_name)
|
174
148
|
end
|
175
149
|
|
150
|
+
def default_style
|
151
|
+
@options.default_style
|
152
|
+
end
|
153
|
+
|
154
|
+
def styles
|
155
|
+
@options.styles
|
156
|
+
end
|
157
|
+
|
176
158
|
# Returns an array containing the errors on this attachment.
|
177
159
|
def errors
|
178
160
|
@errors
|
@@ -205,7 +187,7 @@ module Paperclip
|
|
205
187
|
# nil to the attachment *and saving*. This is permanent. If you wish to
|
206
188
|
# wipe out the existing attachment but not save, use #clear.
|
207
189
|
def destroy
|
208
|
-
unless @preserve_files
|
190
|
+
unless @options.preserve_files
|
209
191
|
clear
|
210
192
|
save
|
211
193
|
end
|
@@ -245,16 +227,16 @@ module Paperclip
|
|
245
227
|
# The time zone to use for timestamp interpolation. Using the default
|
246
228
|
# time zone ensures that results are consistent across all threads.
|
247
229
|
def time_zone
|
248
|
-
@use_default_time_zone ? Time.zone_default : Time.zone
|
230
|
+
@options.use_default_time_zone ? Time.zone_default : Time.zone
|
249
231
|
end
|
250
232
|
|
251
233
|
# Returns a unique hash suitable for obfuscating the URL of an otherwise
|
252
234
|
# publicly viewable attachment.
|
253
235
|
def hash(style_name = default_style)
|
254
|
-
raise ArgumentError, "Unable to generate hash without :hash_secret" unless @hash_secret
|
236
|
+
raise ArgumentError, "Unable to generate hash without :hash_secret" unless @options.hash_secret
|
255
237
|
require 'openssl' unless defined?(OpenSSL)
|
256
|
-
data = interpolate(@hash_data, style_name)
|
257
|
-
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@hash_digest).new, @hash_secret, data)
|
238
|
+
data = interpolate(@options.hash_data, style_name)
|
239
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@options.hash_digest).new, @options.hash_secret, data)
|
258
240
|
end
|
259
241
|
|
260
242
|
def generate_fingerprint(source)
|
@@ -352,28 +334,28 @@ module Paperclip
|
|
352
334
|
end
|
353
335
|
|
354
336
|
def initialize_storage #:nodoc:
|
355
|
-
storage_class_name = @storage.to_s.downcase.camelize
|
337
|
+
storage_class_name = @options.storage.to_s.downcase.camelize
|
356
338
|
begin
|
357
|
-
|
339
|
+
storage_module = Paperclip::Storage.const_get(storage_class_name)
|
358
340
|
rescue NameError
|
359
341
|
raise StorageMethodNotFound, "Cannot load storage module '#{storage_class_name}'"
|
360
342
|
end
|
361
|
-
self.extend(
|
343
|
+
self.extend(storage_module)
|
362
344
|
end
|
363
345
|
|
364
346
|
def extra_options_for(style) #:nodoc:
|
365
|
-
all_options = convert_options[:all]
|
347
|
+
all_options = @options.convert_options[:all]
|
366
348
|
all_options = all_options.call(instance) if all_options.respond_to?(:call)
|
367
|
-
style_options = convert_options[style]
|
349
|
+
style_options = @options.convert_options[style]
|
368
350
|
style_options = style_options.call(instance) if style_options.respond_to?(:call)
|
369
351
|
|
370
352
|
[ style_options, all_options ].compact.join(" ")
|
371
353
|
end
|
372
354
|
|
373
355
|
def extra_source_file_options_for(style) #:nodoc:
|
374
|
-
all_options = source_file_options[:all]
|
356
|
+
all_options = @options.source_file_options[:all]
|
375
357
|
all_options = all_options.call(instance) if all_options.respond_to?(:call)
|
376
|
-
style_options = source_file_options[style]
|
358
|
+
style_options = @options.source_file_options[style]
|
377
359
|
style_options = style_options.call(instance) if style_options.respond_to?(:call)
|
378
360
|
|
379
361
|
[ style_options, all_options ].compact.join(" ")
|
@@ -389,7 +371,7 @@ module Paperclip
|
|
389
371
|
end
|
390
372
|
|
391
373
|
def post_process_styles(*style_args) #:nodoc:
|
392
|
-
styles.each do |name, style|
|
374
|
+
@options.styles.each do |name, style|
|
393
375
|
begin
|
394
376
|
if style_args.empty? || style_args.include?(name)
|
395
377
|
raise RuntimeError.new("Style #{name} has no processors defined.") if style.processors.blank?
|
@@ -399,7 +381,7 @@ module Paperclip
|
|
399
381
|
end
|
400
382
|
rescue PaperclipError => e
|
401
383
|
log("An error was received while processing: #{e.inspect}")
|
402
|
-
(@errors[:processing] ||= []) << e.message if @whiny
|
384
|
+
(@errors[:processing] ||= []) << e.message if @options.whiny
|
403
385
|
end
|
404
386
|
end
|
405
387
|
end
|
@@ -409,8 +391,8 @@ module Paperclip
|
|
409
391
|
end
|
410
392
|
|
411
393
|
def queue_existing_for_delete #:nodoc:
|
412
|
-
return
|
413
|
-
@queued_for_delete += [:original,
|
394
|
+
return if @options.preserve_files || !file?
|
395
|
+
@queued_for_delete += [:original, *@options.styles.keys].uniq.map do |style|
|
414
396
|
path(style) if exists?(style)
|
415
397
|
end.compact
|
416
398
|
instance_write(:file_name, nil)
|
data/lib/paperclip/geometry.rb
CHANGED
@@ -13,18 +13,20 @@ module Paperclip
|
|
13
13
|
|
14
14
|
# Uses ImageMagick to determing the dimensions of a file, passed in as either a
|
15
15
|
# File or path.
|
16
|
+
# NOTE: (race cond) Do not reassign the 'file' variable inside this method as it is likely to be
|
17
|
+
# a Tempfile object, which would be eligible for file deletion when no longer referenced.
|
16
18
|
def self.from_file file
|
17
|
-
|
18
|
-
raise(Paperclip::NotIdentifiedByImageMagickError.new("Cannot find the geometry of a file with a blank name")) if
|
19
|
+
file_path = file.respond_to?(:path) ? file.path : file
|
20
|
+
raise(Paperclip::NotIdentifiedByImageMagickError.new("Cannot find the geometry of a file with a blank name")) if file_path.blank?
|
19
21
|
geometry = begin
|
20
|
-
Paperclip.run("identify", "-format %wx%h :file", :file => "#{
|
22
|
+
Paperclip.run("identify", "-format %wx%h :file", :file => "#{file_path}[0]")
|
21
23
|
rescue Cocaine::ExitStatusError
|
22
24
|
""
|
23
25
|
rescue Cocaine::CommandNotFoundError => e
|
24
26
|
raise Paperclip::CommandNotFoundError.new("Could not run the `identify` command. Please install ImageMagick.")
|
25
27
|
end
|
26
28
|
parse(geometry) ||
|
27
|
-
raise(NotIdentifiedByImageMagickError.new("#{
|
29
|
+
raise(NotIdentifiedByImageMagickError.new("#{file_path} is not recognized by the 'identify' command."))
|
28
30
|
end
|
29
31
|
|
30
32
|
# Parses a "WxH" formatted string, where W is the width and H is the height.
|
@@ -38,7 +38,8 @@ module Paperclip
|
|
38
38
|
# }
|
39
39
|
def self.current_attachments_styles
|
40
40
|
Hash.new.tap do |current_styles|
|
41
|
-
Paperclip.classes_with_attachments.each do |
|
41
|
+
Paperclip.classes_with_attachments.each do |klass_name|
|
42
|
+
klass = Paperclip.class_for(klass_name)
|
42
43
|
klass.attachment_definitions.each do |attachment_name, attachment_attributes|
|
43
44
|
# TODO: is it even possible to take into account Procs?
|
44
45
|
next if attachment_attributes[:styles].kind_of?(Proc)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Paperclip
|
2
|
+
class Options
|
3
|
+
|
4
|
+
attr_accessor :url, :path, :only_process, :normalized_styles, :default_url, :default_style,
|
5
|
+
:storage, :use_timestamp, :whiny, :use_default_time_zone, :hash_digest, :hash_secret,
|
6
|
+
:convert_options, :source_file_options, :preserve_files, :http_proxy
|
7
|
+
|
8
|
+
attr_accessor :s3_credentials, :s3_host_name, :s3_options, :s3_permissions, :s3_protocol,
|
9
|
+
:s3_headers, :s3_host_alias, :bucket
|
10
|
+
|
11
|
+
attr_accessor :fog_directory, :fog_credentials, :fog_host, :fog_public, :fog_file
|
12
|
+
|
13
|
+
def initialize(attachment, hash)
|
14
|
+
@attachment = attachment
|
15
|
+
|
16
|
+
@url = hash[:url]
|
17
|
+
@url = @url.call(@attachment) if @url.is_a?(Proc)
|
18
|
+
@path = hash[:path]
|
19
|
+
@path = @path.call(@attachment) if @path.is_a?(Proc)
|
20
|
+
@styles = hash[:styles]
|
21
|
+
@only_process = hash[:only_process]
|
22
|
+
@normalized_styles = nil
|
23
|
+
@default_url = hash[:default_url]
|
24
|
+
@default_style = hash[:default_style]
|
25
|
+
@storage = hash[:storage]
|
26
|
+
@use_timestamp = hash[:use_timestamp]
|
27
|
+
@whiny = hash[:whiny_thumbnails] || hash[:whiny]
|
28
|
+
@use_default_time_zone = hash[:use_default_time_zone]
|
29
|
+
@hash_digest = hash[:hash_digest]
|
30
|
+
@hash_data = hash[:hash_data]
|
31
|
+
@hash_secret = hash[:hash_secret]
|
32
|
+
@convert_options = hash[:convert_options]
|
33
|
+
@source_file_options = hash[:source_file_options]
|
34
|
+
@processors = hash[:processors]
|
35
|
+
@preserve_files = hash[:preserve_files]
|
36
|
+
@http_proxy = hash[:http_proxy]
|
37
|
+
|
38
|
+
#s3 options
|
39
|
+
@s3_credentials = hash[:s3_credentials]
|
40
|
+
@s3_host_name = hash[:s3_host_name]
|
41
|
+
@bucket = hash[:bucket]
|
42
|
+
@s3_options = hash[:s3_options]
|
43
|
+
@s3_permissions = hash[:s3_permissions]
|
44
|
+
@s3_protocol = hash[:s3_protocol]
|
45
|
+
@s3_headers = hash[:s3_headers]
|
46
|
+
@s3_host_alias = hash[:s3_host_alias]
|
47
|
+
|
48
|
+
#fog options
|
49
|
+
@fog_directory = hash[:fog_directory]
|
50
|
+
@fog_credentials = hash[:fog_credentials]
|
51
|
+
@fog_host = hash[:fog_host]
|
52
|
+
@fog_public = hash[:fog_public]
|
53
|
+
@fog_file = hash[:fog_file]
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method, *args, &blk)
|
57
|
+
if method.to_s[-1] == "="
|
58
|
+
instance_variable_set("@#{method[0..-2]}", args[0])
|
59
|
+
else
|
60
|
+
instance_variable_get("@#{method}")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def processors
|
65
|
+
@processors.respond_to?(:call) ? @processors.call(@attachment.instance) : @processors
|
66
|
+
end
|
67
|
+
|
68
|
+
def styles
|
69
|
+
if @styles.respond_to?(:call) || !@normalized_styles
|
70
|
+
@normalized_styles = ActiveSupport::OrderedHash.new
|
71
|
+
(@styles.respond_to?(:call) ? @styles.call(@attachment) : @styles).each do |name, args|
|
72
|
+
normalized_styles[name] = Paperclip::Style.new(name, args.dup, @attachment)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@normalized_styles
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -41,15 +41,9 @@ module Paperclip
|
|
41
41
|
end unless defined?(Fog)
|
42
42
|
|
43
43
|
base.instance_eval do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
@fog_public = @options.key?(:fog_public) ? @options[:fog_public] : true
|
48
|
-
@fog_file = @options[:fog_file] || {}
|
49
|
-
|
50
|
-
unless @url.to_s.match(/^:fog.*url$/)
|
51
|
-
@path = @path.gsub(/:url/, @url)
|
52
|
-
@url = ':fog_public_url'
|
44
|
+
unless @options.url.to_s.match(/^:fog.*url$/)
|
45
|
+
@options.path = @options.path.gsub(/:url/, @options.url)
|
46
|
+
@options.url = ':fog_public_url'
|
53
47
|
end
|
54
48
|
Paperclip.interpolates(:fog_public_url) do |attachment, style|
|
55
49
|
attachment.public_url(style)
|
@@ -65,15 +59,27 @@ module Paperclip
|
|
65
59
|
end
|
66
60
|
end
|
67
61
|
|
62
|
+
def fog_credentials
|
63
|
+
@fog_credentials ||= parse_credentials(@options.fog_credentials)
|
64
|
+
end
|
65
|
+
|
66
|
+
def fog_file
|
67
|
+
@fog_file ||= @options.fog_file || {}
|
68
|
+
end
|
69
|
+
|
70
|
+
def fog_public
|
71
|
+
@fog_public ||= @options.fog_public || true
|
72
|
+
end
|
73
|
+
|
68
74
|
def flush_writes
|
69
75
|
for style, file in @queued_for_write do
|
70
76
|
log("saving #{path(style)}")
|
71
77
|
retried = false
|
72
78
|
begin
|
73
|
-
directory.files.create(
|
79
|
+
directory.files.create(fog_file.merge(
|
74
80
|
:body => file,
|
75
81
|
:key => path(style),
|
76
|
-
:public =>
|
82
|
+
:public => fog_public
|
77
83
|
))
|
78
84
|
rescue Excon::Errors::NotFound
|
79
85
|
raise if retried
|
@@ -115,8 +121,8 @@ module Paperclip
|
|
115
121
|
end
|
116
122
|
|
117
123
|
def public_url(style = default_style)
|
118
|
-
if @fog_host
|
119
|
-
host = (@fog_host =~ /%d/) ? @fog_host % (path(style).hash % 4) : @fog_host
|
124
|
+
if @options.fog_host
|
125
|
+
host = (@options.fog_host =~ /%d/) ? @options.fog_host % (path(style).hash % 4) : @options.fog_host
|
120
126
|
"#{host}/#{path(style)}"
|
121
127
|
else
|
122
128
|
directory.files.new(:key => path(style)).public_url
|
@@ -145,11 +151,11 @@ module Paperclip
|
|
145
151
|
end
|
146
152
|
|
147
153
|
def connection
|
148
|
-
@connection ||= ::Fog::Storage.new(
|
154
|
+
@connection ||= ::Fog::Storage.new(fog_credentials)
|
149
155
|
end
|
150
156
|
|
151
157
|
def directory
|
152
|
-
@directory ||= connection.directories.new(:key => @fog_directory)
|
158
|
+
@directory ||= connection.directories.new(:key => @options.fog_directory)
|
153
159
|
end
|
154
160
|
end
|
155
161
|
end
|
data/lib/paperclip/storage/s3.rb
CHANGED
@@ -77,33 +77,28 @@ module Paperclip
|
|
77
77
|
end unless defined?(AWS::S3)
|
78
78
|
|
79
79
|
base.instance_eval do
|
80
|
-
@
|
81
|
-
@
|
82
|
-
@
|
83
|
-
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
|
84
|
-
@s3_options = @options[:s3_options] || {}
|
85
|
-
@s3_permissions = set_permissions(@options[:s3_permissions])
|
86
|
-
@s3_protocol = @options[:s3_protocol] ||
|
80
|
+
@s3_options = @options.s3_options || {}
|
81
|
+
@s3_permissions = set_permissions(@options.s3_permissions)
|
82
|
+
@s3_protocol = @options.s3_protocol ||
|
87
83
|
Proc.new do |style|
|
88
84
|
(@s3_permissions[style.to_sym] || @s3_permissions[:default]) == :public_read ? 'http' : 'https'
|
89
85
|
end
|
90
|
-
@s3_headers = @options
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@
|
95
|
-
@url = ":s3_path_url"
|
86
|
+
@s3_headers = @options.s3_headers || {}
|
87
|
+
|
88
|
+
unless @options.url.to_s.match(/^:s3.*url$/) || @options.url == ":asset_host"
|
89
|
+
@options.path = @options.path.gsub(/:url/, @options.url)
|
90
|
+
@options.url = ":s3_path_url"
|
96
91
|
end
|
97
|
-
@url
|
92
|
+
@options.url = @options.url.inspect if @options.url.is_a?(Symbol)
|
98
93
|
|
99
|
-
@http_proxy = @options
|
94
|
+
@http_proxy = @options.http_proxy || nil
|
100
95
|
if @http_proxy
|
101
96
|
@s3_options.merge!({:proxy => @http_proxy})
|
102
97
|
end
|
103
98
|
|
104
99
|
AWS::S3::Base.establish_connection!( @s3_options.merge(
|
105
|
-
:access_key_id =>
|
106
|
-
:secret_access_key =>
|
100
|
+
:access_key_id => s3_credentials[:access_key_id],
|
101
|
+
:secret_access_key => s3_credentials[:secret_access_key]
|
107
102
|
))
|
108
103
|
end
|
109
104
|
Paperclip.interpolates(:s3_alias_url) do |attachment, style|
|
@@ -124,7 +119,23 @@ module Paperclip
|
|
124
119
|
AWS::S3::S3Object.url_for(path(style_name), bucket_name, :expires_in => time, :use_ssl => (s3_protocol(style_name) == 'https'))
|
125
120
|
end
|
126
121
|
|
122
|
+
def s3_credentials
|
123
|
+
@s3_credentials ||= parse_credentials(@options.s3_credentials)
|
124
|
+
end
|
125
|
+
|
126
|
+
def s3_host_name
|
127
|
+
@options.s3_host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com"
|
128
|
+
end
|
129
|
+
|
130
|
+
def s3_host_alias
|
131
|
+
@s3_host_alias = @options.s3_host_alias
|
132
|
+
@s3_host_alias = @s3_host_alias.call(self) if @s3_host_alias.is_a?(Proc)
|
133
|
+
@s3_host_alias
|
134
|
+
end
|
135
|
+
|
127
136
|
def bucket_name
|
137
|
+
@bucket = @options.bucket || s3_credentials[:bucket]
|
138
|
+
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
|
128
139
|
@bucket
|
129
140
|
end
|
130
141
|
|
@@ -148,10 +159,6 @@ module Paperclip
|
|
148
159
|
using_http_proxy? ? @http_proxy[:password] : nil
|
149
160
|
end
|
150
161
|
|
151
|
-
def s3_host_name
|
152
|
-
@s3_host_name || "s3.amazonaws.com"
|
153
|
-
end
|
154
|
-
|
155
162
|
def set_permissions permissions
|
156
163
|
if permissions.is_a?(Hash)
|
157
164
|
permissions[:default] = permissions[:default] || :public_read
|
@@ -161,10 +168,6 @@ module Paperclip
|
|
161
168
|
permissions
|
162
169
|
end
|
163
170
|
|
164
|
-
def s3_host_alias
|
165
|
-
@s3_host_alias
|
166
|
-
end
|
167
|
-
|
168
171
|
def parse_credentials creds
|
169
172
|
creds = find_credentials(creds).stringify_keys
|
170
173
|
env = Object.const_defined?(:Rails) ? Rails.env : nil
|