kt-paperclip 5.4.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.github/issue_template.md +3 -0
  3. data/.hound.yml +27 -32
  4. data/.travis.yml +23 -2
  5. data/Appraisals +17 -0
  6. data/Gemfile +9 -7
  7. data/NEWS +21 -0
  8. data/README.md +27 -37
  9. data/Rakefile +29 -21
  10. data/UPGRADING +3 -3
  11. data/features/basic_integration.feature +4 -0
  12. data/features/migration.feature +10 -51
  13. data/features/step_definitions/attachment_steps.rb +12 -12
  14. data/features/step_definitions/html_steps.rb +5 -5
  15. data/features/step_definitions/rails_steps.rb +29 -9
  16. data/features/step_definitions/s3_steps.rb +3 -3
  17. data/features/step_definitions/web_steps.rb +5 -6
  18. data/features/support/env.rb +4 -4
  19. data/features/support/fakeweb.rb +3 -5
  20. data/features/support/file_helpers.rb +2 -2
  21. data/features/support/paths.rb +4 -4
  22. data/features/support/rails.rb +7 -7
  23. data/features/support/selectors.rb +1 -1
  24. data/gemfiles/4.2.gemfile +7 -4
  25. data/gemfiles/5.0.gemfile +7 -4
  26. data/gemfiles/5.1.gemfile +20 -0
  27. data/gemfiles/5.2.gemfile +20 -0
  28. data/gemfiles/6.0.gemfile +20 -0
  29. data/lib/generators/paperclip/paperclip_generator.rb +6 -8
  30. data/lib/paperclip/attachment.rb +102 -104
  31. data/lib/paperclip/attachment_registry.rb +2 -2
  32. data/lib/paperclip/file_command_content_type_detector.rb +1 -3
  33. data/lib/paperclip/filename_cleaner.rb +0 -1
  34. data/lib/paperclip/geometry.rb +18 -19
  35. data/lib/paperclip/geometry_detector_factory.rb +13 -16
  36. data/lib/paperclip/geometry_parser_factory.rb +5 -5
  37. data/lib/paperclip/glue.rb +3 -3
  38. data/lib/paperclip/has_attached_file.rb +5 -4
  39. data/lib/paperclip/helpers.rb +3 -3
  40. data/lib/paperclip/interpolations.rb +42 -38
  41. data/lib/paperclip/io_adapters/abstract_adapter.rb +16 -14
  42. data/lib/paperclip/io_adapters/attachment_adapter.rb +12 -6
  43. data/lib/paperclip/io_adapters/data_uri_adapter.rb +1 -1
  44. data/lib/paperclip/io_adapters/file_adapter.rb +1 -3
  45. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +3 -3
  46. data/lib/paperclip/io_adapters/identity_adapter.rb +1 -2
  47. data/lib/paperclip/io_adapters/registry.rb +1 -1
  48. data/lib/paperclip/io_adapters/stringio_adapter.rb +1 -1
  49. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +6 -8
  50. data/lib/paperclip/io_adapters/uri_adapter.rb +9 -7
  51. data/lib/paperclip/logger.rb +1 -1
  52. data/lib/paperclip/matchers/have_attached_file_matcher.rb +4 -4
  53. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +19 -18
  54. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +4 -4
  55. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +11 -10
  56. data/lib/paperclip/matchers.rb +4 -4
  57. data/lib/paperclip/media_type_spoof_detector.rb +13 -13
  58. data/lib/paperclip/missing_attachment_styles.rb +11 -6
  59. data/lib/paperclip/processor.rb +13 -6
  60. data/lib/paperclip/processor_helpers.rb +3 -1
  61. data/lib/paperclip/rails_environment.rb +1 -5
  62. data/lib/paperclip/railtie.rb +5 -5
  63. data/lib/paperclip/schema.rb +18 -14
  64. data/lib/paperclip/storage/filesystem.rb +5 -7
  65. data/lib/paperclip/storage/fog.rb +36 -32
  66. data/lib/paperclip/storage/s3.rb +67 -75
  67. data/lib/paperclip/style.rb +3 -6
  68. data/lib/paperclip/tempfile.rb +4 -5
  69. data/lib/paperclip/tempfile_factory.rb +0 -1
  70. data/lib/paperclip/thumbnail.rb +11 -11
  71. data/lib/paperclip/url_generator.rb +5 -12
  72. data/lib/paperclip/validators/attachment_content_type_validator.rb +3 -3
  73. data/lib/paperclip/validators/attachment_file_name_validator.rb +5 -10
  74. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +1 -2
  75. data/lib/paperclip/validators/attachment_presence_validator.rb +3 -5
  76. data/lib/paperclip/validators/attachment_size_validator.rb +8 -8
  77. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +3 -1
  78. data/lib/paperclip/validators.rb +12 -13
  79. data/lib/paperclip/version.rb +1 -3
  80. data/lib/paperclip.rb +49 -48
  81. data/lib/tasks/paperclip.rake +23 -24
  82. data/paperclip.gemspec +29 -33
  83. data/shoulda_macros/paperclip.rb +16 -16
  84. data/spec/paperclip/attachment_definitions_spec.rb +5 -5
  85. data/spec/paperclip/attachment_processing_spec.rb +22 -23
  86. data/spec/paperclip/attachment_registry_spec.rb +15 -15
  87. data/spec/paperclip/attachment_spec.rb +238 -196
  88. data/spec/paperclip/content_type_detector_spec.rb +11 -12
  89. data/spec/paperclip/file_command_content_type_detector_spec.rb +10 -10
  90. data/spec/paperclip/filename_cleaner_spec.rb +3 -4
  91. data/spec/paperclip/geometry_detector_spec.rb +7 -8
  92. data/spec/paperclip/geometry_parser_spec.rb +31 -31
  93. data/spec/paperclip/geometry_spec.rb +24 -24
  94. data/spec/paperclip/glue_spec.rb +3 -5
  95. data/spec/paperclip/has_attached_file_spec.rb +46 -126
  96. data/spec/paperclip/integration_spec.rb +111 -77
  97. data/spec/paperclip/interpolations_spec.rb +101 -93
  98. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +41 -13
  99. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +8 -10
  100. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +13 -14
  101. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +4 -4
  102. data/spec/paperclip/io_adapters/file_adapter_spec.rb +12 -12
  103. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +42 -26
  104. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  105. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +2 -2
  106. data/spec/paperclip/io_adapters/registry_spec.rb +4 -4
  107. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +10 -10
  108. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +6 -6
  109. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +80 -31
  110. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +3 -3
  111. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +4 -5
  112. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +4 -4
  113. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +4 -4
  114. data/spec/paperclip/media_type_spoof_detector_spec.rb +50 -24
  115. data/spec/paperclip/meta_class_spec.rb +3 -3
  116. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +28 -24
  117. data/spec/paperclip/paperclip_spec.rb +15 -11
  118. data/spec/paperclip/plural_cache_spec.rb +8 -8
  119. data/spec/paperclip/processor_helpers_spec.rb +35 -35
  120. data/spec/paperclip/processor_spec.rb +8 -8
  121. data/spec/paperclip/rails_environment_spec.rb +7 -10
  122. data/spec/paperclip/rake_spec.rb +39 -39
  123. data/spec/paperclip/schema_spec.rb +57 -53
  124. data/spec/paperclip/storage/filesystem_spec.rb +6 -6
  125. data/spec/paperclip/storage/fog_spec.rb +76 -82
  126. data/spec/paperclip/storage/s3_live_spec.rb +22 -22
  127. data/spec/paperclip/storage/s3_spec.rb +585 -583
  128. data/spec/paperclip/style_spec.rb +67 -71
  129. data/spec/paperclip/tempfile_factory_spec.rb +5 -5
  130. data/spec/paperclip/thumbnail_spec.rb +68 -67
  131. data/spec/paperclip/url_generator_spec.rb +18 -29
  132. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +27 -27
  133. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +15 -16
  134. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +5 -5
  135. data/spec/paperclip/validators/attachment_size_validator_spec.rb +21 -21
  136. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +9 -13
  137. data/spec/paperclip/validators_spec.rb +40 -40
  138. data/spec/spec_helper.rb +21 -23
  139. data/spec/support/assertions.rb +8 -6
  140. data/spec/support/fake_model.rb +1 -2
  141. data/spec/support/fake_rails.rb +1 -1
  142. data/spec/support/matchers/exist.rb +1 -1
  143. data/spec/support/matchers/have_column.rb +1 -1
  144. data/spec/support/mock_url_generator_builder.rb +2 -3
  145. data/spec/support/model_reconstruction.rb +16 -12
  146. data/spec/support/reporting.rb +1 -1
  147. data/spec/support/test_data.rb +2 -2
  148. metadata +49 -105
  149. data/lib/kt-paperclip.rb +0 -1
  150. data/spec/support/conditional_filter_helper.rb +0 -5
@@ -3,8 +3,8 @@ module Paperclip
3
3
  # Amazon's S3 file hosting service is a scalable, easy place to store files for
4
4
  # distribution. You can find out more about it at http://aws.amazon.com/s3
5
5
  #
6
- # To use Paperclip with S3, include the +aws-sdk+ gem in your Gemfile:
7
- # gem 'aws-sdk'
6
+ # To use Paperclip with S3, include the +aws-sdk-s3+ gem in your Gemfile:
7
+ # gem 'aws-sdk-s3'
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
@@ -96,7 +96,7 @@ module Paperclip
96
96
  # separate parts of your file name.
97
97
  # * +s3_host_name+: If you are using your bucket in Tokyo region
98
98
  # etc, write host_name (e.g., 's3-ap-northeast-1.amazonaws.com').
99
- # * +s3_region+: For aws-sdk v2, s3_region is required.
99
+ # * +s3_region+: For aws-sdk-s3, s3_region is required.
100
100
  # * +s3_metadata+: These key/value pairs will be stored with the
101
101
  # object. This option works by prefixing each key with
102
102
  # "x-amz-meta-" before sending it as a header on the object
@@ -118,25 +118,21 @@ module Paperclip
118
118
  # :s3_storage_class => :REDUCED_REDUNDANCY
119
119
  #
120
120
  # Other storage classes, such as <tt>:STANDARD_IA</tt>, are also available—see the
121
- # documentation for the <tt>aws-sdk</tt> gem for the full list.
121
+ # documentation for the <tt>aws-sdk-s3</tt> gem for the full list.
122
122
 
123
123
  module S3
124
- def self.extended base
124
+ def self.extended(base)
125
125
  begin
126
- require 'aws-sdk'
126
+ require "aws-sdk-s3"
127
127
  rescue LoadError => e
128
- e.message << " (You may need to install the aws-sdk gem)"
128
+ e.message << " (You may need to install the aws-sdk-s3 gem)"
129
129
  raise e
130
130
  end
131
- if Gem::Version.new(Aws::VERSION) >= Gem::Version.new(2) &&
132
- Gem::Version.new(Aws::VERSION) <= Gem::Version.new("2.0.33")
133
- raise LoadError, "paperclip does not support aws-sdk versions 2.0.0 - 2.0.33. Please upgrade aws-sdk to a newer version."
134
- end
135
131
 
136
132
  base.instance_eval do
137
- @s3_options = @options[:s3_options] || {}
133
+ @s3_options = @options[:s3_options] || {}
138
134
  @s3_permissions = set_permissions(@options[:s3_permissions])
139
- @s3_protocol = @options[:s3_protocol] || "".freeze
135
+ @s3_protocol = @options[:s3_protocol] || ""
140
136
  @s3_metadata = @options[:s3_metadata] || {}
141
137
  @s3_headers = {}
142
138
  merge_s3_headers(@options[:s3_headers], @s3_headers, @s3_metadata)
@@ -144,47 +140,46 @@ module Paperclip
144
140
  @s3_storage_class = set_storage_class(@options[:s3_storage_class])
145
141
 
146
142
  @s3_server_side_encryption = "AES256"
147
- if @options[:s3_server_side_encryption].blank?
148
- @s3_server_side_encryption = false
149
- end
150
- if @s3_server_side_encryption
151
- @s3_server_side_encryption = @options[:s3_server_side_encryption]
152
- end
143
+ @s3_server_side_encryption = false if @options[:s3_server_side_encryption].blank?
144
+ @s3_server_side_encryption = @options[:s3_server_side_encryption] if @s3_server_side_encryption
153
145
 
154
- unless @options[:url].to_s.match(/\A:s3.*url\z/) || @options[:url] == ":asset_host".freeze
155
- @options[:path] = path_option.gsub(/:url/, @options[:url]).sub(/\A:rails_root\/public\/system/, "".freeze)
156
- @options[:url] = ":s3_path_url".freeze
146
+ unless @options[:url].to_s.match(/\A:s3.*url\z/) || @options[:url] == ":asset_host"
147
+ @options[:path] = path_option.gsub(/:url/, @options[:url]).sub(/\A:rails_root\/public\/system/, "")
148
+ @options[:url] = ":s3_path_url"
157
149
  end
158
150
  @options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol)
159
151
 
160
152
  @http_proxy = @options[:http_proxy] || nil
161
153
 
162
- if @options.has_key?(:use_accelerate_endpoint) &&
163
- Gem::Version.new(Aws::VERSION) < Gem::Version.new("2.3.0")
164
- raise LoadError, ":use_accelerate_endpoint is only available from aws-sdk version 2.3.0. Please upgrade aws-sdk to a newer version."
165
- end
166
-
167
154
  @use_accelerate_endpoint = @options[:use_accelerate_endpoint]
168
155
  end
169
156
 
170
- Paperclip.interpolates(:s3_alias_url) do |attachment, style|
171
- protocol = attachment.s3_protocol(style, true)
172
- host = attachment.s3_host_alias
173
- path = attachment.path(style).
174
- split("/")[attachment.s3_prefixes_in_alias..-1].
175
- join("/").
176
- sub(%r{\A/}, "".freeze)
177
- "#{protocol}//#{host}/#{path}"
178
- end unless Paperclip::Interpolations.respond_to? :s3_alias_url
179
- Paperclip.interpolates(:s3_path_url) do |attachment, style|
180
- "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_name}/#{attachment.bucket_name}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
181
- end unless Paperclip::Interpolations.respond_to? :s3_path_url
182
- Paperclip.interpolates(:s3_domain_url) do |attachment, style|
183
- "#{attachment.s3_protocol(style, true)}//#{attachment.bucket_name}.#{attachment.s3_host_name}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
184
- end unless Paperclip::Interpolations.respond_to? :s3_domain_url
185
- Paperclip.interpolates(:asset_host) do |attachment, style|
186
- "#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
187
- end unless Paperclip::Interpolations.respond_to? :asset_host
157
+ unless Paperclip::Interpolations.respond_to? :s3_alias_url
158
+ Paperclip.interpolates(:s3_alias_url) do |attachment, style|
159
+ protocol = attachment.s3_protocol(style, true)
160
+ host = attachment.s3_host_alias
161
+ path = attachment.path(style).
162
+ split("/")[attachment.s3_prefixes_in_alias..-1].
163
+ join("/").
164
+ sub(%r{\A/}, "")
165
+ "#{protocol}//#{host}/#{path}"
166
+ end
167
+ end
168
+ unless Paperclip::Interpolations.respond_to? :s3_path_url
169
+ Paperclip.interpolates(:s3_path_url) do |attachment, style|
170
+ "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_name}/#{attachment.bucket_name}/#{attachment.path(style).sub(%r{\A/}, '')}"
171
+ end
172
+ end
173
+ unless Paperclip::Interpolations.respond_to? :s3_domain_url
174
+ Paperclip.interpolates(:s3_domain_url) do |attachment, style|
175
+ "#{attachment.s3_protocol(style, true)}//#{attachment.bucket_name}.#{attachment.s3_host_name}/#{attachment.path(style).sub(%r{\A/}, '')}"
176
+ end
177
+ end
178
+ unless Paperclip::Interpolations.respond_to? :asset_host
179
+ Paperclip.interpolates(:asset_host) do |attachment, style|
180
+ attachment.path(style).sub(%r{\A/}, "").to_s
181
+ end
182
+ end
188
183
  end
189
184
 
190
185
  def expiring_url(time = 3600, style_name = default_style)
@@ -192,7 +187,7 @@ module Paperclip
192
187
  base_options = { expires_in: time }
193
188
  s3_object(style_name).presigned_url(
194
189
  :get,
195
- base_options.merge(s3_url_options),
190
+ base_options.merge(s3_url_options)
196
191
  ).to_s
197
192
  else
198
193
  url(style_name)
@@ -207,7 +202,7 @@ module Paperclip
207
202
  host_name = @options[:s3_host_name]
208
203
  host_name = host_name.call(self) if host_name.is_a?(Proc)
209
204
 
210
- host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com".freeze
205
+ host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com"
211
206
  end
212
207
 
213
208
  def s3_region
@@ -236,7 +231,7 @@ module Paperclip
236
231
  def bucket_name
237
232
  @bucket = @options[:bucket] || s3_credentials[:bucket]
238
233
  @bucket = @bucket.call(self) if @bucket.respond_to?(:call)
239
- @bucket or raise ArgumentError, "missing required :bucket option"
234
+ @bucket || raise(ArgumentError, "missing required :bucket option")
240
235
  end
241
236
 
242
237
  def s3_interface
@@ -245,7 +240,7 @@ module Paperclip
245
240
 
246
241
  if using_http_proxy?
247
242
 
248
- proxy_opts = { :host => http_proxy_host }
243
+ proxy_opts = { host: http_proxy_host }
249
244
  proxy_opts[:port] = http_proxy_port if http_proxy_port
250
245
  if http_proxy_user
251
246
  userinfo = http_proxy_user.to_s
@@ -275,10 +270,10 @@ module Paperclip
275
270
  end
276
271
 
277
272
  def style_name_as_path(style_name)
278
- path(style_name).sub(%r{\A/},'')
273
+ path(style_name).sub(%r{\A/}, "")
279
274
  end
280
275
 
281
- def s3_object style_name = default_style
276
+ def s3_object(style_name = default_style)
282
277
  s3_bucket.object style_name_as_path(style_name)
283
278
  end
284
279
 
@@ -306,17 +301,17 @@ module Paperclip
306
301
  using_http_proxy? ? @http_proxy[:password] : nil
307
302
  end
308
303
 
309
- def set_permissions permissions
310
- permissions = { :default => permissions } unless permissions.respond_to?(:merge)
311
- permissions.merge :default => (permissions[:default] || :"public-read")
304
+ def set_permissions(permissions)
305
+ permissions = { default: permissions } unless permissions.respond_to?(:merge)
306
+ permissions.merge default: (permissions[:default] || :"public-read")
312
307
  end
313
308
 
314
309
  def set_storage_class(storage_class)
315
- storage_class = {:default => storage_class} unless storage_class.respond_to?(:merge)
310
+ storage_class = { default: storage_class } unless storage_class.respond_to?(:merge)
316
311
  storage_class
317
312
  end
318
313
 
319
- def parse_credentials creds
314
+ def parse_credentials(creds)
320
315
  creds = creds.respond_to?(:call) ? creds.call(self) : creds
321
316
  creds = find_credentials(creds).stringify_keys
322
317
  (creds[RailsEnvironment.get] || creds).symbolize_keys
@@ -359,26 +354,26 @@ module Paperclip
359
354
 
360
355
  def flush_writes #:nodoc:
361
356
  @queued_for_write.each do |style, file|
362
- retries = 0
357
+ retries = 0
363
358
  begin
364
359
  log("saving #{path(style)}")
365
360
  write_options = {
366
- :content_type => file.content_type,
367
- :acl => s3_permissions(style)
361
+ content_type: file.content_type,
362
+ acl: s3_permissions(style)
368
363
  }
369
364
 
370
365
  # add storage class for this style if defined
371
366
  storage_class = s3_storage_class(style)
372
- write_options.merge!(:storage_class => storage_class) if storage_class
367
+ write_options.merge!(storage_class: storage_class) if storage_class
373
368
 
374
- if @s3_server_side_encryption
375
- write_options[:server_side_encryption] = @s3_server_side_encryption
376
- end
369
+ write_options[:server_side_encryption] = @s3_server_side_encryption if @s3_server_side_encryption
377
370
 
378
371
  style_specific_options = styles[style]
379
372
 
380
373
  if style_specific_options
381
- merge_s3_headers( style_specific_options[:s3_headers], @s3_headers, @s3_metadata) if style_specific_options[:s3_headers]
374
+ if style_specific_options[:s3_headers]
375
+ merge_s3_headers(style_specific_options[:s3_headers], @s3_headers, @s3_metadata)
376
+ end
382
377
  @s3_metadata.merge!(style_specific_options[:s3_metadata]) if style_specific_options[:s3_metadata]
383
378
  end
384
379
 
@@ -392,7 +387,7 @@ module Paperclip
392
387
  rescue ::Aws::S3::Errors::SlowDown
393
388
  retries += 1
394
389
  if retries <= 5
395
- sleep((2 ** retries) * 0.5)
390
+ sleep((2**retries) * 0.5)
396
391
  retry
397
392
  else
398
393
  raise
@@ -421,11 +416,7 @@ module Paperclip
421
416
 
422
417
  def copy_to_local_file(style, local_dest_path)
423
418
  log("copying #{path(style)} to local file #{local_dest_path}")
424
- ::File.open(local_dest_path, 'wb') do |local_file|
425
- s3_object(style).get do |chunk|
426
- local_file.write(chunk)
427
- end
428
- end
419
+ s3_object(style).download_file(local_dest_path)
429
420
  rescue Aws::Errors::ServiceError => e
430
421
  warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}")
431
422
  false
@@ -433,12 +424,12 @@ module Paperclip
433
424
 
434
425
  private
435
426
 
436
- def find_credentials creds
427
+ def find_credentials(creds)
437
428
  case creds
438
429
  when File
439
- YAML::load(ERB.new(File.read(creds.path)).result)
430
+ YAML::safe_load(ERB.new(File.read(creds.path)).result)
440
431
  when String, Pathname
441
- YAML::load(ERB.new(File.read(creds)).result)
432
+ YAML::safe_load(ERB.new(File.read(creds)).result)
442
433
  when Hash
443
434
  creds
444
435
  when NilClass
@@ -454,13 +445,14 @@ module Paperclip
454
445
 
455
446
  def merge_s3_headers(http_headers, s3_headers, s3_metadata)
456
447
  return if http_headers.nil?
448
+
457
449
  http_headers = http_headers.call(instance) if http_headers.respond_to?(:call)
458
- http_headers.inject({}) do |headers,(name,value)|
450
+ http_headers.inject({}) do |_headers, (name, value)|
459
451
  case name.to_s
460
452
  when /\Ax-amz-meta-(.*)/i
461
453
  s3_metadata[$1.downcase] = value
462
454
  else
463
- s3_headers[name.to_s.downcase.sub(/\Ax-amz-/,'').tr("-","_").to_sym] = value
455
+ s3_headers[name.to_s.downcase.sub(/\Ax-amz-/, "").tr("-", "_").to_sym] = value
464
456
  end
465
457
  end
466
458
  end
@@ -1,17 +1,15 @@
1
- # encoding: utf-8
2
1
  module Paperclip
3
2
  # The Style class holds the definition of a thumbnail style, applying
4
3
  # whatever processing is required to normalize the definition and delaying
5
4
  # the evaluation of block parameters until useful context is available.
6
5
 
7
6
  class Style
8
-
9
7
  attr_reader :name, :attachment, :format
10
8
 
11
9
  # Creates a Style object. +name+ is the name of the attachment,
12
10
  # +definition+ is the style definition from has_attached_file, which
13
11
  # can be string, array or hash
14
- def initialize name, definition, attachment
12
+ def initialize(name, definition, attachment)
15
13
  @name = name
16
14
  @attachment = attachment
17
15
  if definition.is_a? Hash
@@ -71,8 +69,8 @@ module Paperclip
71
69
  # Arguments other than the standard geometry, format etc are just passed through from
72
70
  # initialization and any procs are called here, just before post-processing.
73
71
  def processor_options
74
- args = {:style => name}
75
- @other_args.each do |k,v|
72
+ args = { style: name }
73
+ @other_args.each do |k, v|
76
74
  args[k] = v.respond_to?(:call) ? v.call(attachment) : v
77
75
  end
78
76
  [:processors, :geometry, :format, :whiny, :convert_options, :source_file_options].each do |k|
@@ -104,6 +102,5 @@ module Paperclip
104
102
  base = attachment.options[:default_format]
105
103
  base.respond_to?(:call) ? base.call(attachment, name) : base
106
104
  end
107
-
108
105
  end
109
106
  end
@@ -12,7 +12,8 @@ module Paperclip
12
12
  if RUBY_PLATFORM =~ /java/
13
13
  case prefix_suffix
14
14
  when String
15
- prefix, suffix = prefix_suffix, ''
15
+ prefix = prefix_suffix
16
+ suffix = ""
16
17
  when Array
17
18
  prefix, suffix = *prefix_suffix
18
19
  else
@@ -32,12 +33,10 @@ module Paperclip
32
33
  # for binary mode is ASCII-8BIT. This behavior is what's in CRuby, but not
33
34
  # in JRuby
34
35
  def binmode
35
- set_encoding('ASCII-8BIT')
36
+ set_encoding("ASCII-8BIT")
36
37
  super
37
38
  end
38
39
  end
39
40
  end
40
41
 
41
- if RUBY_PLATFORM =~ /java/
42
- ::Tempfile.send :include, Paperclip::TempfileEncoding
43
- end
42
+ ::Tempfile.include Paperclip::TempfileEncoding if RUBY_PLATFORM =~ /java/
@@ -1,6 +1,5 @@
1
1
  module Paperclip
2
2
  class TempfileFactory
3
-
4
3
  def generate(name = random_name)
5
4
  @name = name
6
5
  file = Tempfile.new([basename, extension])
@@ -1,13 +1,12 @@
1
1
  module Paperclip
2
2
  # Handles thumbnailing images that are uploaded.
3
3
  class Thumbnail < Processor
4
-
5
4
  attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options,
6
5
  :source_file_options, :animated, :auto_orient, :frame_index
7
6
 
8
7
  # List of formats that we need to preserve animation
9
- ANIMATED_FORMATS = %w(gif)
10
- MULTI_FRAME_FORMATS = %w(.mkv .avi .mp4 .mov .mpg .mpeg .gif)
8
+ ANIMATED_FORMATS = %w(gif).freeze
9
+ MULTI_FRAME_FORMATS = %w(.mkv .avi .mp4 .mov .mpg .mpeg .gif).freeze
11
10
 
12
11
  # Creates a Thumbnail object set to work on the +file+ given. It
13
12
  # will attempt to transform the image into one defined by +target_geometry+
@@ -31,7 +30,7 @@ module Paperclip
31
30
  super
32
31
 
33
32
  geometry = options[:geometry].to_s
34
- @crop = geometry[-1,1] == '#'
33
+ @crop = geometry[-1, 1] == "#"
35
34
  @target_geometry = options.fetch(:string_geometry_parser, Geometry).parse(geometry)
36
35
  @current_geometry = options.fetch(:file_geometry_parser, Geometry).from_file(@file)
37
36
  @source_file_options = options[:source_file_options]
@@ -40,9 +39,7 @@ module Paperclip
40
39
  @format = options[:format]
41
40
  @animated = options.fetch(:animated, true)
42
41
  @auto_orient = options.fetch(:auto_orient, true)
43
- if @auto_orient && @current_geometry.respond_to?(:auto_orient)
44
- @current_geometry.auto_orient
45
- end
42
+ @current_geometry.auto_orient if @auto_orient && @current_geometry.respond_to?(:auto_orient)
46
43
  @source_file_options = @source_file_options.split(/\s+/) if @source_file_options.respond_to?(:split)
47
44
  @convert_options = @convert_options.split(/\s+/) if @convert_options.respond_to?(:split)
48
45
 
@@ -82,10 +79,13 @@ module Paperclip
82
79
  convert(
83
80
  parameters,
84
81
  source: "#{File.expand_path(src.path)}#{frame}",
85
- dest: File.expand_path(dst.path),
82
+ dest: File.expand_path(dst.path)
86
83
  )
87
84
  rescue Terrapin::ExitStatusError => e
88
- raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
85
+ if @whiny
86
+ message = "There was an error processing the thumbnail for #{@basename}:\n" + e.message
87
+ raise Paperclip::Error, message
88
+ end
89
89
  rescue Terrapin::CommandNotFoundError => e
90
90
  raise Paperclip::Errors::CommandNotFoundError.new("Could not run the `convert` command. Please install ImageMagick.")
91
91
  end
@@ -113,13 +113,13 @@ module Paperclip
113
113
  end
114
114
 
115
115
  def animated?
116
- @animated && (ANIMATED_FORMATS.include?(@format.to_s) || @format.blank?) && identified_as_animated?
116
+ @animated && (ANIMATED_FORMATS.include?(@format.to_s) || @format.blank?) && identified_as_animated?
117
117
  end
118
118
 
119
119
  # Return true if ImageMagick's +identify+ returns an animated format
120
120
  def identified_as_animated?
121
121
  if @identified_as_animated.nil?
122
- @identified_as_animated = ANIMATED_FORMATS.include? identify("-format %m :file", :file => "#{@file.path}[0]").to_s.downcase.strip
122
+ @identified_as_animated = ANIMATED_FORMATS.include? identify("-format %m :file", file: "#{@file.path}[0]").to_s.downcase.strip
123
123
  end
124
124
  @identified_as_animated
125
125
  rescue Terrapin::ExitStatusError => e
@@ -1,15 +1,8 @@
1
- require 'uri'
2
- require 'active_support/core_ext/module/delegation'
1
+ require "uri"
2
+ require "active_support/core_ext/module/delegation"
3
3
 
4
4
  module Paperclip
5
5
  class UrlGenerator
6
- class << self
7
- def encoder
8
- @encoder ||= URI::RFC2396_Parser.new
9
- end
10
- delegate :escape, :unescape, to: :encoder
11
- end
12
-
13
6
  def initialize(attachment)
14
7
  @attachment = attachment
15
8
  end
@@ -49,8 +42,8 @@ module Paperclip
49
42
 
50
43
  def timestamp_as_needed(url, options)
51
44
  if options[:timestamp] && timestamp_possible?
52
- delimiter_char = url.match(/\?.+=/) ? '&' : '?'
53
- "#{url}#{delimiter_char}#{@attachment.updated_at.to_s}"
45
+ delimiter_char = url.match(/\?.+=/) ? "&" : "?"
46
+ "#{url}#{delimiter_char}#{@attachment.updated_at}"
54
47
  else
55
48
  url
56
49
  end
@@ -72,7 +65,7 @@ module Paperclip
72
65
  if url.respond_to?(:escape)
73
66
  url.escape
74
67
  else
75
- self.class.escape(url).gsub(escape_regex){|m| "%#{m.ord.to_s(16).upcase}" }
68
+ URI.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
76
69
  end
77
70
  end
78
71
 
@@ -2,7 +2,7 @@ module Paperclip
2
2
  module Validators
3
3
  class AttachmentContentTypeValidator < ActiveModel::EachValidator
4
4
  def initialize(options)
5
- options[:allow_nil] = true unless options.has_key?(:allow_nil)
5
+ options[:allow_nil] = true unless options.key?(:allow_nil)
6
6
  super
7
7
  end
8
8
 
@@ -40,7 +40,7 @@ module Paperclip
40
40
  end
41
41
 
42
42
  def mark_invalid(record, attribute, types)
43
- record.errors.add attribute, :invalid, options.merge(:types => types.join(', '))
43
+ record.errors.add attribute, :invalid, options.merge(types: types.join(", "))
44
44
  end
45
45
 
46
46
  def allowed_types
@@ -52,7 +52,7 @@ module Paperclip
52
52
  end
53
53
 
54
54
  def check_validity!
55
- unless options.has_key?(:content_type) || options.has_key?(:not)
55
+ unless options.key?(:content_type) || options.key?(:not)
56
56
  raise ArgumentError, "You must pass in either :content_type or :not to the validator"
57
57
  end
58
58
  end
@@ -2,7 +2,7 @@ module Paperclip
2
2
  module Validators
3
3
  class AttachmentFileNameValidator < ActiveModel::EachValidator
4
4
  def initialize(options)
5
- options[:allow_nil] = true unless options.has_key?(:allow_nil)
5
+ options[:allow_nil] = true unless options.key?(:allow_nil)
6
6
  super
7
7
  end
8
8
 
@@ -28,19 +28,15 @@ module Paperclip
28
28
  end
29
29
 
30
30
  def validate_whitelist(record, attribute, value)
31
- if allowed.present? && allowed.none? { |type| type === value }
32
- mark_invalid record, attribute, allowed
33
- end
31
+ mark_invalid record, attribute, allowed if allowed.present? && allowed.none? { |type| type === value }
34
32
  end
35
33
 
36
34
  def validate_blacklist(record, attribute, value)
37
- if forbidden.present? && forbidden.any? { |type| type === value }
38
- mark_invalid record, attribute, forbidden
39
- end
35
+ mark_invalid record, attribute, forbidden if forbidden.present? && forbidden.any? { |type| type === value }
40
36
  end
41
37
 
42
38
  def mark_invalid(record, attribute, patterns)
43
- record.errors.add attribute, :invalid, options.merge(:names => patterns.join(', '))
39
+ record.errors.add attribute, :invalid, options.merge(names: patterns.join(", "))
44
40
  end
45
41
 
46
42
  def allowed
@@ -52,7 +48,7 @@ module Paperclip
52
48
  end
53
49
 
54
50
  def check_validity!
55
- unless options.has_key?(:matches) || options.has_key?(:not)
51
+ unless options.key?(:matches) || options.key?(:not)
56
52
  raise ArgumentError, "You must pass in either :matches or :not to the validator"
57
53
  end
58
54
  end
@@ -77,4 +73,3 @@ module Paperclip
77
73
  end
78
74
  end
79
75
  end
80
-
@@ -1,4 +1,4 @@
1
- require 'active_model/validations/presence'
1
+ require "active_model/validations/presence"
2
2
 
3
3
  module Paperclip
4
4
  module Validators
@@ -26,4 +26,3 @@ module Paperclip
26
26
  end
27
27
  end
28
28
  end
29
-
@@ -1,12 +1,10 @@
1
- require 'active_model/validations/presence'
1
+ require "active_model/validations/presence"
2
2
 
3
3
  module Paperclip
4
4
  module Validators
5
5
  class AttachmentPresenceValidator < ActiveModel::EachValidator
6
- def validate_each(record, attribute, value)
7
- if record.send("#{attribute}_file_name").blank?
8
- record.errors.add(attribute, :blank, options)
9
- end
6
+ def validate_each(record, attribute, _value)
7
+ record.errors.add(attribute, :blank, options) if record.send("#{attribute}_file_name").blank?
10
8
  end
11
9
 
12
10
  def self.helper_method_name
@@ -1,9 +1,9 @@
1
- require 'active_model/validations/numericality'
1
+ require "active_model/validations/numericality"
2
2
 
3
3
  module Paperclip
4
4
  module Validators
5
5
  class AttachmentSizeValidator < ActiveModel::Validations::NumericalityValidator
6
- AVAILABLE_CHECKS = [:less_than, :less_than_or_equal_to, :greater_than, :greater_than_or_equal_to]
6
+ AVAILABLE_CHECKS = [:less_than, :less_than_or_equal_to, :greater_than, :greater_than_or_equal_to].freeze
7
7
 
8
8
  def initialize(options)
9
9
  extract_options(options)
@@ -26,12 +26,12 @@ module Paperclip
26
26
 
27
27
  unless value.send(CHECKS[option], option_value)
28
28
  error_message_key = options[:in] ? :in_between : option
29
- [ attr_name, base_attr_name ].each do |error_attr_name|
29
+ [attr_name, base_attr_name].each do |error_attr_name|
30
30
  record.errors.add(error_attr_name, error_message_key, filtered_options(value).merge(
31
- :min => min_value_in_human_size(record),
32
- :max => max_value_in_human_size(record),
33
- :count => human_size(option_value)
34
- ))
31
+ min: min_value_in_human_size(record),
32
+ max: max_value_in_human_size(record),
33
+ count: human_size(option_value)
34
+ ))
35
35
  end
36
36
  end
37
37
  end
@@ -39,7 +39,7 @@ module Paperclip
39
39
  end
40
40
 
41
41
  def check_validity!
42
- unless (AVAILABLE_CHECKS + [:in]).any? { |argument| options.has_key?(argument) }
42
+ unless (AVAILABLE_CHECKS + [:in]).any? { |argument| options.key?(argument) }
43
43
  raise ArgumentError, "You must pass either :less_than, :greater_than, or :in to the validator"
44
44
  end
45
45
  end
@@ -1,4 +1,4 @@
1
- require 'active_model/validations/presence'
1
+ require "active_model/validations/presence"
2
2
 
3
3
  module Paperclip
4
4
  module Validators
@@ -8,6 +8,8 @@ module Paperclip
8
8
  if Paperclip::MediaTypeSpoofDetector.using(adapter, value.original_filename, value.content_type).spoofed?
9
9
  record.errors.add(attribute, :spoofed_media_type)
10
10
  end
11
+
12
+ adapter.tempfile.close(true) if adapter.tempfile
11
13
  end
12
14
  end
13
15