paperclip 4.3.7 → 5.0.0.beta1
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.
- checksums.yaml +4 -4
- data/.travis.yml +13 -9
- data/Appraisals +22 -6
- data/CONTRIBUTING.md +6 -1
- data/Gemfile +2 -8
- data/LICENSE +1 -1
- data/NEWS +28 -37
- data/README.md +81 -63
- data/UPGRADING +9 -9
- data/features/basic_integration.feature +1 -0
- data/features/step_definitions/s3_steps.rb +6 -2
- data/gemfiles/{4.1.gemfile → 4.2.awsv2.0.gemfile} +4 -6
- data/gemfiles/4.2.awsv2.1.gemfile +17 -0
- data/gemfiles/{4.2.gemfile → 4.2.awsv2.gemfile} +1 -0
- data/gemfiles/5.0.awsv2.0.gemfile +17 -0
- data/gemfiles/5.0.awsv2.1.gemfile +17 -0
- data/gemfiles/{3.2.gemfile → 5.0.awsv2.gemfile} +7 -1
- data/lib/paperclip.rb +0 -2
- data/lib/paperclip/attachment.rb +9 -8
- data/lib/paperclip/attachment_registry.rb +2 -1
- data/lib/paperclip/callbacks.rb +8 -6
- data/lib/paperclip/glue.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +7 -1
- data/lib/paperclip/io_adapters/uri_adapter.rb +11 -30
- data/lib/paperclip/schema.rb +1 -2
- data/lib/paperclip/storage/s3.rb +59 -35
- data/lib/paperclip/version.rb +1 -1
- data/paperclip.gemspec +11 -7
- data/spec/paperclip/attachment_registry_spec.rb +28 -0
- data/spec/paperclip/attachment_spec.rb +32 -6
- data/spec/paperclip/has_attached_file_spec.rb +24 -8
- data/spec/paperclip/integration_spec.rb +4 -3
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +5 -8
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +6 -31
- data/spec/paperclip/media_type_spoof_detector_spec.rb +3 -12
- data/spec/paperclip/paperclip_spec.rb +0 -32
- data/spec/paperclip/storage/s3_live_spec.rb +8 -4
- data/spec/paperclip/storage/s3_spec.rb +345 -165
- data/spec/paperclip/validators_spec.rb +2 -3
- data/spec/spec_helper.rb +3 -1
- data/spec/support/assertions.rb +7 -0
- data/spec/support/model_reconstruction.rb +9 -1
- data/spec/support/reporting.rb +11 -0
- metadata +45 -40
- data/lib/paperclip/deprecations.rb +0 -42
- data/lib/paperclip/locales/de.yml +0 -18
- data/lib/paperclip/locales/es.yml +0 -18
- data/lib/paperclip/locales/ja.yml +0 -18
- data/lib/paperclip/locales/pt-BR.yml +0 -18
- data/lib/paperclip/locales/zh-CN.yml +0 -18
- data/lib/paperclip/locales/zh-HK.yml +0 -18
- data/lib/paperclip/locales/zh-TW.yml +0 -18
- data/spec/paperclip/deprecations_spec.rb +0 -65
- data/spec/support/deprecations.rb +0 -9
- data/spec/support/rails_helpers.rb +0 -7
data/UPGRADING
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
##################################################
|
2
|
-
# NOTE FOR UPGRADING FROM
|
2
|
+
# NOTE FOR UPGRADING FROM 4.3.0 OR EARLIER #
|
3
3
|
##################################################
|
4
4
|
|
5
|
-
Paperclip
|
6
|
-
path. This will help to prevent attachment name clashes when you have
|
7
|
-
multiple attachments with the same name. If you didn't alter your
|
8
|
-
attachment's path and are using Paperclip's default, you'll have to add
|
9
|
-
`:path` and `:url` to your `has_attached_file` definition. For example:
|
5
|
+
Paperclip is now compatible with aws-sdk >= 2.0.0.
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
:url => "/system/:attachment/:id/:style/:filename"
|
7
|
+
If you are using S3 storage, aws-sdk >= 2.0.0 requires you to make a few small
|
8
|
+
changes:
|
14
9
|
|
10
|
+
* You must set the `s3_region`
|
11
|
+
* If you are explicitly setting permissions anywhere, such as in an initializer,
|
12
|
+
note that the format of the permissions changed from using an underscore to
|
13
|
+
using a hyphen. For example, `:public_read` needs to be changed to
|
14
|
+
`public-read`.
|
@@ -1,11 +1,15 @@
|
|
1
1
|
When /^I attach the file "([^"]*)" to "([^"]*)" on S3$/ do |file_path, field|
|
2
2
|
definition = Paperclip::AttachmentRegistry.definitions_for(User)[field.downcase.to_sym]
|
3
|
-
path =
|
3
|
+
path = if defined?(::AWS)
|
4
|
+
"https://paperclip.s3.amazonaws.com#{definition[:path]}"
|
5
|
+
else
|
6
|
+
"https://paperclip.s3-us-west-2.amazonaws.com#{definition[:path]}"
|
7
|
+
end
|
4
8
|
path.gsub!(':filename', File.basename(file_path))
|
5
9
|
path.gsub!(/:([^\/\.]+)/) do |match|
|
6
10
|
"([^\/\.]+)"
|
7
11
|
end
|
8
|
-
FakeWeb.register_uri(:put, Regexp.new(path), :body => "OK")
|
12
|
+
FakeWeb.register_uri(:put, Regexp.new(path), :body => defined?(::AWS) ? "OK" : "<xml></xml>")
|
9
13
|
step "I attach the file \"#{file_path}\" to \"#{field}\""
|
10
14
|
end
|
11
15
|
|
@@ -3,15 +3,13 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
5
|
gem "sqlite3", "~> 1.3.8", :platforms => :ruby
|
6
|
-
gem "jruby-openssl", :platforms => :jruby
|
7
|
-
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
8
|
-
gem "rubysl", :platforms => :rbx
|
9
|
-
gem "racc", :platforms => :rbx
|
10
6
|
gem "pry"
|
11
|
-
gem "rails", "~> 4.
|
7
|
+
gem "rails", "~> 4.2.0"
|
8
|
+
gem "aws-sdk", "~> 2.0.0"
|
12
9
|
|
13
10
|
group :development, :test do
|
14
|
-
gem "
|
11
|
+
gem "activerecord-import"
|
12
|
+
gem "mime-types"
|
15
13
|
gem "builder"
|
16
14
|
gem "rubocop", :require => false
|
17
15
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "sqlite3", "~> 1.3.8", :platforms => :ruby
|
6
|
+
gem "pry"
|
7
|
+
gem "rails", "~> 4.2.0"
|
8
|
+
gem "aws-sdk", "~> 2.1.0"
|
9
|
+
|
10
|
+
group :development, :test do
|
11
|
+
gem "activerecord-import"
|
12
|
+
gem "mime-types", ">= 1.16", "< 4"
|
13
|
+
gem "builder"
|
14
|
+
gem "rubocop", :require => false
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec :path => "../"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "sqlite3", "~> 1.3.8", :platforms => :ruby
|
6
|
+
gem "pry"
|
7
|
+
gem "rails", "5.0.0.beta3"
|
8
|
+
gem "aws-sdk", "~> 2.0.0"
|
9
|
+
|
10
|
+
group :development, :test do
|
11
|
+
gem "activerecord-import"
|
12
|
+
gem "mime-types", ">= 1.16", "< 4"
|
13
|
+
gem "builder"
|
14
|
+
gem "rubocop", :require => false
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec :path => "../"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "sqlite3", "~> 1.3.8", :platforms => :ruby
|
6
|
+
gem "pry"
|
7
|
+
gem "rails", "5.0.0.beta3"
|
8
|
+
gem "aws-sdk", "~> 2.1.0"
|
9
|
+
|
10
|
+
group :development, :test do
|
11
|
+
gem "activerecord-import"
|
12
|
+
gem "mime-types"
|
13
|
+
gem "builder"
|
14
|
+
gem "rubocop", :require => false
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec :path => "../"
|
@@ -8,7 +8,13 @@ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
8
8
|
gem "rubysl", :platforms => :rbx
|
9
9
|
gem "racc", :platforms => :rbx
|
10
10
|
gem "pry"
|
11
|
-
gem "rails",
|
11
|
+
gem "rails", :github => "rails/rails"
|
12
|
+
gem "sprockets-rails", :github => "rails/sprockets-rails"
|
13
|
+
gem "sprockets", :github => "rails/sprockets"
|
14
|
+
gem "sass-rails", :github => "rails/sass-rails"
|
15
|
+
gem "arel", :github => "rails/arel"
|
16
|
+
gem "rack", :github => "rack/rack"
|
17
|
+
gem "aws-sdk", "~> 2.0"
|
12
18
|
|
13
19
|
group :development, :test do
|
14
20
|
gem "mime-types", "~> 1.16"
|
data/lib/paperclip.rb
CHANGED
@@ -56,7 +56,6 @@ require 'paperclip/has_attached_file'
|
|
56
56
|
require 'paperclip/attachment_registry'
|
57
57
|
require 'paperclip/filename_cleaner'
|
58
58
|
require 'paperclip/rails_environment'
|
59
|
-
require "paperclip/deprecations"
|
60
59
|
|
61
60
|
begin
|
62
61
|
# Use mime/types/columnar if available, for reduced memory usage
|
@@ -192,7 +191,6 @@ module Paperclip
|
|
192
191
|
# end
|
193
192
|
# end
|
194
193
|
def has_attached_file(name, options = {})
|
195
|
-
Paperclip::Deprecations.check
|
196
194
|
HasAttachedFile.define_on(self, name, options)
|
197
195
|
end
|
198
196
|
end
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'uri'
|
3
3
|
require 'paperclip/url_generator'
|
4
4
|
require 'active_support/deprecation'
|
5
|
+
require 'active_support/core_ext/string/inflections'
|
5
6
|
|
6
7
|
module Paperclip
|
7
8
|
# The Attachment class manages the files for a given attachment. It saves
|
@@ -322,7 +323,7 @@ module Paperclip
|
|
322
323
|
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@options[:hash_digest]).new, @options[:hash_secret], data)
|
323
324
|
end
|
324
325
|
|
325
|
-
# This method really shouldn't be called that often.
|
326
|
+
# This method really shouldn't be called that often. Its expected use is
|
326
327
|
# in the paperclip:refresh rake task and that's it. It will regenerate all
|
327
328
|
# thumbnails forcefully, by reobtaining the original file and going through
|
328
329
|
# the post-process again.
|
@@ -426,7 +427,7 @@ module Paperclip
|
|
426
427
|
def assign_attributes
|
427
428
|
@queued_for_write[:original] = @file
|
428
429
|
assign_file_information
|
429
|
-
assign_fingerprint
|
430
|
+
assign_fingerprint { @file.fingerprint }
|
430
431
|
assign_timestamps
|
431
432
|
end
|
432
433
|
|
@@ -436,9 +437,9 @@ module Paperclip
|
|
436
437
|
instance_write(:file_size, @file.size)
|
437
438
|
end
|
438
439
|
|
439
|
-
def assign_fingerprint
|
440
|
+
def assign_fingerprint
|
440
441
|
if instance_respond_to?(:fingerprint)
|
441
|
-
instance_write(:fingerprint,
|
442
|
+
instance_write(:fingerprint, yield)
|
442
443
|
end
|
443
444
|
end
|
444
445
|
|
@@ -464,7 +465,7 @@ module Paperclip
|
|
464
465
|
|
465
466
|
def reset_file_if_original_reprocessed
|
466
467
|
instance_write(:file_size, @queued_for_write[:original].size)
|
467
|
-
assign_fingerprint
|
468
|
+
assign_fingerprint { @queued_for_write[:original].fingerprint }
|
468
469
|
reset_updater
|
469
470
|
end
|
470
471
|
|
@@ -500,7 +501,7 @@ module Paperclip
|
|
500
501
|
|
501
502
|
instance.run_paperclip_callbacks(:post_process) do
|
502
503
|
instance.run_paperclip_callbacks(:"#{name}_post_process") do
|
503
|
-
|
504
|
+
if !@options[:check_validity_before_processing] || !instance.errors.any?
|
504
505
|
post_process_styles(*style_args)
|
505
506
|
end
|
506
507
|
end
|
@@ -521,7 +522,7 @@ module Paperclip
|
|
521
522
|
|
522
523
|
@queued_for_write[name] = style.processors.inject(@queued_for_write[:original]) do |file, processor|
|
523
524
|
file = Paperclip.processor(processor).make(file, style.processor_options, self)
|
524
|
-
intermediate_files << file
|
525
|
+
intermediate_files << file unless file == @queued_for_write[:original]
|
525
526
|
file
|
526
527
|
end
|
527
528
|
|
@@ -586,7 +587,7 @@ module Paperclip
|
|
586
587
|
|
587
588
|
# You can either specifiy :restricted_characters or you can define your own
|
588
589
|
# :filename_cleaner object. This object needs to respond to #call and takes
|
589
|
-
# the filename that will be cleaned. It should return the cleaned
|
590
|
+
# the filename that will be cleaned. It should return the cleaned filename.
|
590
591
|
def filename_cleaner
|
591
592
|
@options[:filename_cleaner] || FilenameCleaner.new(@options[:restricted_characters])
|
592
593
|
end
|
@@ -51,7 +51,8 @@ module Paperclip
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def definitions_for(klass)
|
54
|
-
klass.ancestors.
|
54
|
+
parent_classes = klass.ancestors.reverse
|
55
|
+
parent_classes.each_with_object({}) do |ancestor, inherited_definitions|
|
55
56
|
inherited_definitions.deep_merge! @attachments[ancestor]
|
56
57
|
end
|
57
58
|
end
|
data/lib/paperclip/callbacks.rb
CHANGED
@@ -7,7 +7,7 @@ module Paperclip
|
|
7
7
|
|
8
8
|
module Defining
|
9
9
|
def define_paperclip_callbacks(*callbacks)
|
10
|
-
define_callbacks(*[callbacks, {:
|
10
|
+
define_callbacks(*[callbacks, { terminator: hasta_la_vista_baby }].flatten)
|
11
11
|
callbacks.each do |callback|
|
12
12
|
eval <<-end_callbacks
|
13
13
|
def before_#{callback}(*args, &blk)
|
@@ -22,11 +22,13 @@ module Paperclip
|
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def hasta_la_vista_baby
|
26
|
+
lambda do |_, result|
|
27
|
+
if result.respond_to?(:call)
|
28
|
+
result.call == false
|
29
|
+
else
|
30
|
+
result == false
|
31
|
+
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/paperclip/glue.rb
CHANGED
@@ -8,7 +8,7 @@ module Paperclip
|
|
8
8
|
base.extend ClassMethods
|
9
9
|
base.send :include, Callbacks
|
10
10
|
base.send :include, Validators
|
11
|
-
base.send :include, Schema if defined? ActiveRecord
|
11
|
+
base.send :include, Schema if defined? ActiveRecord::Base
|
12
12
|
|
13
13
|
locale_path = Dir.glob(File.dirname(__FILE__) + "/locales/*.{rb,yml}")
|
14
14
|
I18n.load_path += locale_path unless I18n.load_path.include?(locale_path)
|
@@ -91,7 +91,13 @@ module Paperclip
|
|
91
91
|
name = @name
|
92
92
|
@klass.send(:after_save) { send(name).send(:save) }
|
93
93
|
@klass.send(:before_destroy) { send(name).send(:queue_all_for_delete) }
|
94
|
-
@klass.
|
94
|
+
if @klass.respond_to?(:after_commit)
|
95
|
+
@klass.send(:after_commit, on: :destroy) do
|
96
|
+
send(name).send(:flush_deletes)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
@klass.send(:after_destroy) { send(name).send(:flush_deletes) }
|
100
|
+
end
|
95
101
|
end
|
96
102
|
|
97
103
|
def add_paperclip_callbacks
|
@@ -2,8 +2,6 @@ require 'open-uri'
|
|
2
2
|
|
3
3
|
module Paperclip
|
4
4
|
class UriAdapter < AbstractAdapter
|
5
|
-
attr_writer :content_type
|
6
|
-
|
7
5
|
def initialize(target)
|
8
6
|
@target = target
|
9
7
|
@content = download_content
|
@@ -11,40 +9,23 @@ module Paperclip
|
|
11
9
|
@tempfile = copy_to_tempfile(@content)
|
12
10
|
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
def cache_current_values
|
17
|
-
self.content_type = content_type_from_content || "text/html"
|
18
|
-
|
19
|
-
self.original_filename = filename_from_content_disposition ||
|
20
|
-
filename_from_path ||
|
21
|
-
default_filename
|
22
|
-
@size = @content.size
|
23
|
-
end
|
12
|
+
attr_writer :content_type
|
24
13
|
|
25
|
-
|
26
|
-
if @content.respond_to?(:content_type)
|
27
|
-
@content.content_type
|
28
|
-
end
|
29
|
-
end
|
14
|
+
private
|
30
15
|
|
31
|
-
def
|
32
|
-
|
33
|
-
@content.meta["content-disposition"].
|
34
|
-
match(/filename="([^"]*)"/)[1]
|
35
|
-
end
|
16
|
+
def download_content
|
17
|
+
open(@target)
|
36
18
|
end
|
37
19
|
|
38
|
-
def
|
39
|
-
@target.path.split("/").last
|
40
|
-
|
20
|
+
def cache_current_values
|
21
|
+
@original_filename = @target.path.split("/").last
|
22
|
+
@original_filename ||= "index.html"
|
23
|
+
self.original_filename = @original_filename.strip
|
41
24
|
|
42
|
-
|
43
|
-
"
|
44
|
-
end
|
25
|
+
@content_type = @content.content_type if @content.respond_to?(:content_type)
|
26
|
+
@content_type ||= "text/html"
|
45
27
|
|
46
|
-
|
47
|
-
open(@target)
|
28
|
+
@size = @content.size
|
48
29
|
end
|
49
30
|
|
50
31
|
def copy_to_tempfile(src)
|
data/lib/paperclip/schema.rb
CHANGED
@@ -38,8 +38,7 @@ module Paperclip
|
|
38
38
|
options = attachment_names.extract_options!
|
39
39
|
|
40
40
|
attachment_names.each do |attachment_name|
|
41
|
-
COLUMNS.
|
42
|
-
column_options = options.merge(options[column_name.to_sym] || {})
|
41
|
+
COLUMNS.keys.each do |column_name|
|
43
42
|
remove_column(table_name, "#{attachment_name}_#{column_name}")
|
44
43
|
end
|
45
44
|
end
|
data/lib/paperclip/storage/s3.rb
CHANGED
@@ -4,7 +4,7 @@ module Paperclip
|
|
4
4
|
# distribution. You can find out more about it at http://aws.amazon.com/s3
|
5
5
|
#
|
6
6
|
# To use Paperclip with S3, include the +aws-sdk+ gem in your Gemfile:
|
7
|
-
# gem 'aws-sdk'
|
7
|
+
# gem 'aws-sdk'
|
8
8
|
# There are a few S3-specific options for has_attached_file:
|
9
9
|
# * +s3_credentials+: Takes a path, a File, a Hash or a Proc. The path (or File) must point
|
10
10
|
# to a YAML file containing the +access_key_id+ and +secret_access_key+ that Amazon
|
@@ -41,7 +41,7 @@ module Paperclip
|
|
41
41
|
# * +s3_permissions+: This is a String that should be one of the "canned" access
|
42
42
|
# policies that S3 provides (more information can be found here:
|
43
43
|
# http://docs.aws.amazon.com/AmazonS3/latest/dev/ACLOverview.html)
|
44
|
-
# The default for Paperclip is
|
44
|
+
# The default for Paperclip is public-read.
|
45
45
|
#
|
46
46
|
# You can set permission on a per style bases by doing the following:
|
47
47
|
# :s3_permissions => {
|
@@ -61,7 +61,7 @@ module Paperclip
|
|
61
61
|
# * +bucket+: This is the name of the S3 bucket that will store your files. Remember
|
62
62
|
# that the bucket must be unique across all of Amazon S3. If the bucket does not exist
|
63
63
|
# Paperclip will attempt to create it. The bucket name will not be interpolated.
|
64
|
-
# You can define the bucket as a Proc if you want to determine
|
64
|
+
# You can define the bucket as a Proc if you want to determine its name at runtime.
|
65
65
|
# Paperclip will call that Proc with attachment as the only argument.
|
66
66
|
# * +s3_host_alias+: The fully-qualified domain name (FQDN) that is the alias to the
|
67
67
|
# S3 domain of your bucket. Used with the :s3_alias_url url interpolation. See the
|
@@ -93,6 +93,7 @@ module Paperclip
|
|
93
93
|
# S3 (strictly speaking) does not support directories, you can still use a / to
|
94
94
|
# separate parts of your file name.
|
95
95
|
# * +s3_host_name+: If you are using your bucket in Tokyo region etc, write host_name.
|
96
|
+
# * +s3_region+: For aws-sdk v2, s3_region is required.
|
96
97
|
# * +s3_metadata+: These key/value pairs will be stored with the
|
97
98
|
# object. This option works by prefixing each key with
|
98
99
|
# "x-amz-meta-" before sending it as a header on the object
|
@@ -112,22 +113,33 @@ module Paperclip
|
|
112
113
|
|
113
114
|
module S3
|
114
115
|
def self.extended base
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
116
|
+
unless defined?(AWS_CLASS)
|
117
|
+
begin
|
118
|
+
require 'aws-sdk'
|
119
|
+
const_set('AWS_CLASS', defined?(::Aws) ? ::Aws : ::AWS)
|
120
|
+
const_set('AWS_BASE_ERROR',
|
121
|
+
defined?(::Aws) ? Aws::Errors::ServiceError : AWS::Errors::Base)
|
122
|
+
const_set('DEFAULT_PERMISSION',
|
123
|
+
defined?(::AWS) ? :public_read : :'public-read')
|
124
|
+
|
125
|
+
rescue LoadError => e
|
126
|
+
e.message << " (You may need to install the aws-sdk gem)"
|
127
|
+
raise e
|
128
|
+
end
|
129
|
+
if Gem::Version.new(AWS_CLASS::VERSION) >= Gem::Version.new(2) && Gem::Version.new(AWS_CLASS::VERSION) <= Gem::Version.new("2.0.33")
|
130
|
+
raise LoadError, "paperclip does not support aws-sdk versions 2.0.0 - 2.0.33. Please upgrade aws-sdk to a newer version."
|
131
|
+
end
|
132
|
+
end
|
121
133
|
|
122
134
|
# Overriding log formatter to make sure it return a UTF-8 string
|
123
|
-
if defined?(
|
124
|
-
|
135
|
+
if defined?(AWS_CLASS::Core::LogFormatter)
|
136
|
+
AWS_CLASS::Core::LogFormatter.class_eval do
|
125
137
|
def summarize_hash(hash)
|
126
138
|
hash.map { |key, value| ":#{key}=>#{summarize_value(value)}".force_encoding('UTF-8') }.sort.join(',')
|
127
139
|
end
|
128
140
|
end
|
129
|
-
elsif defined?(
|
130
|
-
|
141
|
+
elsif defined?(AWS_CLASS::Core::ClientLogging)
|
142
|
+
AWS_CLASS::Core::ClientLogging.class_eval do
|
131
143
|
def sanitize_hash(hash)
|
132
144
|
hash.map { |key, value| "#{sanitize_value(key)}=>#{sanitize_value(value)}".force_encoding('UTF-8') }.sort.join(',')
|
133
145
|
end
|
@@ -141,7 +153,7 @@ module Paperclip
|
|
141
153
|
Proc.new do |style, attachment|
|
142
154
|
permission = (@s3_permissions[style.to_s.to_sym] || @s3_permissions[:default])
|
143
155
|
permission = permission.call(attachment, style) if permission.respond_to?(:call)
|
144
|
-
(permission ==
|
156
|
+
(permission == DEFAULT_PERMISSION) ? 'http'.freeze : 'https'.freeze
|
145
157
|
end
|
146
158
|
@s3_metadata = @options[:s3_metadata] || {}
|
147
159
|
@s3_headers = {}
|
@@ -149,7 +161,7 @@ module Paperclip
|
|
149
161
|
|
150
162
|
@s3_storage_class = set_storage_class(@options[:s3_storage_class])
|
151
163
|
|
152
|
-
@s3_server_side_encryption =
|
164
|
+
@s3_server_side_encryption = "AES256"
|
153
165
|
if @options[:s3_server_side_encryption].blank?
|
154
166
|
@s3_server_side_encryption = false
|
155
167
|
end
|
@@ -182,8 +194,11 @@ module Paperclip
|
|
182
194
|
|
183
195
|
def expiring_url(time = 3600, style_name = default_style)
|
184
196
|
if path(style_name)
|
185
|
-
base_options = { :
|
186
|
-
s3_object(style_name).
|
197
|
+
base_options = { expires_in: time }
|
198
|
+
s3_object(style_name).presigned_url(
|
199
|
+
:get,
|
200
|
+
base_options.merge(s3_url_options),
|
201
|
+
).to_s
|
187
202
|
else
|
188
203
|
url(style_name)
|
189
204
|
end
|
@@ -200,6 +215,13 @@ module Paperclip
|
|
200
215
|
host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com".freeze
|
201
216
|
end
|
202
217
|
|
218
|
+
def s3_region
|
219
|
+
region = @options[:s3_region]
|
220
|
+
region = region.call(self) if region.is_a?(Proc)
|
221
|
+
|
222
|
+
region || s3_credentials[:s3_region]
|
223
|
+
end
|
224
|
+
|
203
225
|
def s3_host_alias
|
204
226
|
@s3_host_alias = @options[:s3_host_alias]
|
205
227
|
@s3_host_alias = @s3_host_alias.call(self) if @s3_host_alias.respond_to?(:call)
|
@@ -220,7 +242,7 @@ module Paperclip
|
|
220
242
|
|
221
243
|
def s3_interface
|
222
244
|
@s3_interface ||= begin
|
223
|
-
config = { :
|
245
|
+
config = { region: s3_region }
|
224
246
|
|
225
247
|
if using_http_proxy?
|
226
248
|
|
@@ -234,7 +256,7 @@ module Paperclip
|
|
234
256
|
config[:proxy_uri] = URI::HTTP.build(proxy_opts)
|
235
257
|
end
|
236
258
|
|
237
|
-
[:access_key_id, :secret_access_key, :credential_provider].each do |opt|
|
259
|
+
[:access_key_id, :secret_access_key, :credential_provider, :credentials].each do |opt|
|
238
260
|
config[opt] = s3_credentials[opt] if s3_credentials[opt]
|
239
261
|
end
|
240
262
|
|
@@ -244,15 +266,19 @@ module Paperclip
|
|
244
266
|
|
245
267
|
def obtain_s3_instance_for(options)
|
246
268
|
instances = (Thread.current[:paperclip_s3_instances] ||= {})
|
247
|
-
instances[options] ||=
|
269
|
+
instances[options] ||= AWS_CLASS::S3::Resource.new(options)
|
248
270
|
end
|
249
271
|
|
250
272
|
def s3_bucket
|
251
|
-
@s3_bucket ||= s3_interface.
|
273
|
+
@s3_bucket ||= s3_interface.bucket(bucket_name)
|
274
|
+
end
|
275
|
+
|
276
|
+
def style_name_as_path(style_name)
|
277
|
+
path(style_name).sub(%r{\A/},'')
|
252
278
|
end
|
253
279
|
|
254
280
|
def s3_object style_name = default_style
|
255
|
-
s3_bucket.
|
281
|
+
s3_bucket.object style_name_as_path(style_name)
|
256
282
|
end
|
257
283
|
|
258
284
|
def using_http_proxy?
|
@@ -277,7 +303,7 @@ module Paperclip
|
|
277
303
|
|
278
304
|
def set_permissions permissions
|
279
305
|
permissions = { :default => permissions } unless permissions.respond_to?(:merge)
|
280
|
-
permissions.merge :default => (permissions[:default] ||
|
306
|
+
permissions.merge :default => (permissions[:default] || DEFAULT_PERMISSION)
|
281
307
|
end
|
282
308
|
|
283
309
|
def set_storage_class(storage_class)
|
@@ -297,7 +323,7 @@ module Paperclip
|
|
297
323
|
else
|
298
324
|
false
|
299
325
|
end
|
300
|
-
rescue
|
326
|
+
rescue AWS_BASE_ERROR => e
|
301
327
|
false
|
302
328
|
end
|
303
329
|
|
@@ -323,7 +349,7 @@ module Paperclip
|
|
323
349
|
end
|
324
350
|
|
325
351
|
def create_bucket
|
326
|
-
s3_interface.
|
352
|
+
s3_interface.bucket(bucket_name).create
|
327
353
|
end
|
328
354
|
|
329
355
|
def flush_writes #:nodoc:
|
@@ -331,11 +357,9 @@ module Paperclip
|
|
331
357
|
retries = 0
|
332
358
|
begin
|
333
359
|
log("saving #{path(style)}")
|
334
|
-
acl = @s3_permissions[style] || @s3_permissions[:default]
|
335
|
-
acl = acl.call(self, style) if acl.respond_to?(:call)
|
336
360
|
write_options = {
|
337
361
|
:content_type => file.content_type,
|
338
|
-
:acl =>
|
362
|
+
:acl => s3_permissions(style)
|
339
363
|
}
|
340
364
|
|
341
365
|
# add storage class for this style if defined
|
@@ -356,11 +380,11 @@ module Paperclip
|
|
356
380
|
write_options[:metadata] = @s3_metadata unless @s3_metadata.empty?
|
357
381
|
write_options.merge!(@s3_headers)
|
358
382
|
|
359
|
-
s3_object(style).
|
360
|
-
rescue
|
383
|
+
s3_object(style).upload_file(file.path, write_options)
|
384
|
+
rescue AWS_CLASS::S3::Errors::NoSuchBucket
|
361
385
|
create_bucket
|
362
386
|
retry
|
363
|
-
rescue
|
387
|
+
rescue AWS_CLASS::S3::Errors::SlowDown
|
364
388
|
retries += 1
|
365
389
|
if retries <= 5
|
366
390
|
sleep((2 ** retries) * 0.5)
|
@@ -382,8 +406,8 @@ module Paperclip
|
|
382
406
|
@queued_for_delete.each do |path|
|
383
407
|
begin
|
384
408
|
log("deleting #{path}")
|
385
|
-
s3_bucket.
|
386
|
-
rescue
|
409
|
+
s3_bucket.object(path.sub(%r{\A/}, "")).delete
|
410
|
+
rescue AWS_BASE_ERROR => e
|
387
411
|
# Ignore this.
|
388
412
|
end
|
389
413
|
end
|
@@ -393,11 +417,11 @@ module Paperclip
|
|
393
417
|
def copy_to_local_file(style, local_dest_path)
|
394
418
|
log("copying #{path(style)} to local file #{local_dest_path}")
|
395
419
|
::File.open(local_dest_path, 'wb') do |local_file|
|
396
|
-
s3_object(style).
|
420
|
+
s3_object(style).get do |chunk|
|
397
421
|
local_file.write(chunk)
|
398
422
|
end
|
399
423
|
end
|
400
|
-
rescue
|
424
|
+
rescue AWS_BASE_ERROR => e
|
401
425
|
warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}")
|
402
426
|
false
|
403
427
|
end
|