paperclip 5.2.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.github/issue_template.md +3 -0
  3. data/MIGRATING-ES.md +317 -0
  4. data/MIGRATING.md +375 -0
  5. data/NEWS +36 -0
  6. data/README.md +52 -18
  7. data/UPGRADING +3 -3
  8. data/features/step_definitions/attachment_steps.rb +10 -10
  9. data/features/step_definitions/rails_steps.rb +1 -1
  10. data/lib/generators/paperclip/paperclip_generator.rb +9 -1
  11. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  12. data/lib/paperclip/attachment.rb +19 -6
  13. data/lib/paperclip/file_command_content_type_detector.rb +1 -1
  14. data/lib/paperclip/filename_cleaner.rb +0 -1
  15. data/lib/paperclip/geometry_detector_factory.rb +3 -3
  16. data/lib/paperclip/helpers.rb +3 -3
  17. data/lib/paperclip/interpolations.rb +6 -1
  18. data/lib/paperclip/io_adapters/abstract_adapter.rb +11 -6
  19. data/lib/paperclip/io_adapters/attachment_adapter.rb +7 -1
  20. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +2 -1
  21. data/lib/paperclip/io_adapters/uri_adapter.rb +8 -6
  22. data/lib/paperclip/logger.rb +1 -1
  23. data/lib/paperclip/media_type_spoof_detector.rb +11 -7
  24. data/lib/paperclip/processor.rb +10 -2
  25. data/lib/paperclip/schema.rb +1 -1
  26. data/lib/paperclip/storage/fog.rb +3 -2
  27. data/lib/paperclip/storage/s3.rb +8 -16
  28. data/lib/paperclip/style.rb +0 -1
  29. data/lib/paperclip/thumbnail.rb +8 -5
  30. data/lib/paperclip/url_generator.rb +1 -0
  31. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +4 -0
  32. data/lib/paperclip/version.rb +1 -1
  33. data/lib/paperclip.rb +2 -1
  34. data/paperclip.gemspec +2 -2
  35. data/spec/paperclip/attachment_processing_spec.rb +0 -1
  36. data/spec/paperclip/attachment_spec.rb +17 -2
  37. data/spec/paperclip/content_type_detector_spec.rb +1 -1
  38. data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -1
  39. data/spec/paperclip/filename_cleaner_spec.rb +0 -1
  40. data/spec/paperclip/integration_spec.rb +41 -5
  41. data/spec/paperclip/interpolations_spec.rb +9 -0
  42. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +59 -0
  43. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +33 -16
  44. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +56 -8
  45. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +1 -1
  46. data/spec/paperclip/media_type_spoof_detector_spec.rb +41 -0
  47. data/spec/paperclip/paperclip_spec.rb +13 -13
  48. data/spec/paperclip/processor_spec.rb +4 -4
  49. data/spec/paperclip/schema_spec.rb +46 -46
  50. data/spec/paperclip/storage/fog_spec.rb +5 -0
  51. data/spec/paperclip/storage/s3_spec.rb +6 -6
  52. data/spec/paperclip/style_spec.rb +0 -1
  53. data/spec/paperclip/thumbnail_spec.rb +8 -6
  54. data/spec/paperclip/url_generator_spec.rb +0 -1
  55. data/spec/spec_helper.rb +0 -1
  56. data/spec/support/model_reconstruction.rb +2 -2
  57. metadata +120 -20
  58. data/spec/support/conditional_filter_helper.rb +0 -5
data/NEWS CHANGED
@@ -1,3 +1,38 @@
1
+ 6.1.0 (2018-07-27):
2
+
3
+ * BUGFIX: Don't double-encode URLs (Roderick Monje).
4
+ * BUGFIX: Only use the content_type when it exists (Jean-Philippe Doyle).
5
+ * STABILITY: Better handling of the content-disposition header. Now supports
6
+ file name that is either enclosed or not in double quotes and is case
7
+ insensitive as per RC6266 grammar (Hasan Kumar, Yves Riel).
8
+ * STABILITY: Change database column type of attachment file size from unsigned 4-byte
9
+ `integer` to unsigned 8-byte `bigint`. The former type limits attachment size
10
+ to just over 2GB, which can easily be exceeded by a large video file (Laurent
11
+ Arnoud, Alen Zamanyan).
12
+ * STABILITY: Better error message when thumbnail processing errors (Hayden Ball).
13
+ * STABILITY: Fix file linking issues around Windows (Akihiko Odaki).
14
+ * STABILITY: Files without an extension will now be checked for spoofing attempts
15
+ (George Walters II).
16
+ * STABILITY: Manually close Tempfiles when we are done with them (Erkki Eilonen).
17
+
18
+ 6.0.0 (2018-03-09):
19
+
20
+ * Improvement: Depend only on `aws-sdk-s3` instead of `aws-sdk` (https://github.com/thoughtbot/paperclip/pull/2481)
21
+
22
+ 5.3.0 (2018-03-09):
23
+
24
+ * Improvement: Use `FactoryBot` instead of `FactoryGirl` (https://github.com/thoughtbot/paperclip/pull/2501)
25
+ * Improvement: README updates (https://github.com/thoughtbot/paperclip/pull/2411, https://github.com/thoughtbot/paperclip/pull/2433, https://github.com/thoughtbot/paperclip/pull/2374, https://github.com/thoughtbot/paperclip/pull/2417, https://github.com/thoughtbot/paperclip/pull/2536)
26
+ * Improvement: Remove Ruby 2.4 deprecation warning (https://github.com/thoughtbot/paperclip/pull/2401)
27
+ * Improvement: Rails 5 migration compatibility (https://github.com/thoughtbot/paperclip/pull/2470)
28
+ * Improvement: Documentation around post processing (https://github.com/thoughtbot/paperclip/pull/2381)
29
+ * Improvement: S3 hostname example documentation (https://github.com/thoughtbot/paperclip/pull/2379)
30
+ * Bugfix: Allow paperclip to load in IRB (https://github.com/thoughtbot/paperclip/pull/2369)
31
+ * Bugfix: MIME type detection (https://github.com/thoughtbot/paperclip/issues/2527)
32
+ * Bugfix: Bad tempfile state after symlink failure (https://github.com/thoughtbot/paperclip/pull/2540)
33
+ * Bugfix: Rewind file after Fog bucket creation (https://github.com/thoughtbot/paperclip/pull/2572)
34
+ * Improvement: Use `Terrapin` instead of `Cocaine` (https://github.com/thoughtbot/paperclip/pull/2553)
35
+
1
36
  5.2.1 (2018-01-25):
2
37
 
3
38
  * Bugfix: Fix copying files on Windows. (#2532)
@@ -36,6 +71,7 @@
36
71
  * Improvement: S3 storage option `:s3_prefixes_in_alias`. (#2287)
37
72
  * Improvement: Fog option `:fog_public` can be a lambda. (#2302)
38
73
  * Improvement: One fewer warning on JRuby. (#2352)
74
+ * Ruby 2.4.0 compatibility (doesn't use Fixnum anymore)
39
75
 
40
76
  5.1.0 (2016-08-19):
41
77
 
data/README.md CHANGED
@@ -1,6 +1,28 @@
1
1
  Paperclip
2
2
  =========
3
3
 
4
+ # Deprecated
5
+
6
+ **[Paperclip is deprecated]**.
7
+
8
+ For new projects, we recommend Rails' own [ActiveStorage].
9
+
10
+ For existing projects, please consult and contribute to [the migration guide] ([en español]).
11
+
12
+
13
+ We will leave the Issues open as a discussion forum _only_. We do _not_
14
+ guarantee a response from us in the Issues.
15
+
16
+ We are no longer accepting pull requests _except_ pull requests against the
17
+ migration guide. All other pull requests will be closed without merging.
18
+
19
+ [Paperclip is deprecated]: https://robots.thoughtbot.com/closing-the-trombone
20
+ [ActiveStorage]: http://guides.rubyonrails.org/active_storage_overview.html
21
+ [the migration guide]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
22
+ [en español]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING-ES.md
23
+
24
+ # Existing documentation
25
+
4
26
  ## Documentation valid for `master` branch
5
27
 
6
28
  Please check the documentation for the paperclip version you are using:
@@ -87,7 +109,7 @@ Requirements
87
109
  ### Ruby and Rails
88
110
 
89
111
  Paperclip now requires Ruby version **>= 2.1** and Rails version **>= 4.2**
90
- (only if you're going to use Paperclip with Ruby on Rails.)
112
+ (only if you're going to use Paperclip with Ruby on Rails).
91
113
 
92
114
  ### Image Processor
93
115
 
@@ -105,7 +127,7 @@ In development mode, you might add this line to `config/environments/development
105
127
  Paperclip.options[:command_path] = "/usr/local/bin/"
106
128
  ```
107
129
 
108
- If you're on Mac OS X, you'll want to run the following with [Homebrew] (http://www.brew.sh):
130
+ If you're on Mac OS X, you'll want to run the following with [Homebrew](http://www.brew.sh):
109
131
 
110
132
  brew install imagemagick
111
133
 
@@ -167,7 +189,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
167
189
  Include the gem in your Gemfile:
168
190
 
169
191
  ```ruby
170
- gem "paperclip", "~> 5.0.0"
192
+ gem "paperclip", "~> 6.0.0"
171
193
  ```
172
194
 
173
195
  Or, if you want to get the latest, you can get master from the main paperclip repository:
@@ -206,6 +228,8 @@ end
206
228
 
207
229
  ### Migrations
208
230
 
231
+
232
+ Assuming you have a `users` table, add an `avatar` column to the `users` table:
209
233
  ```ruby
210
234
  class AddAvatarColumnsToUsers < ActiveRecord::Migration
211
235
  def up
@@ -221,10 +245,11 @@ end
221
245
  (Or you can use the Rails migration generator: `rails generate paperclip user avatar`)
222
246
 
223
247
  ### Edit and New Views
224
-
248
+ Make sure you have corresponding methods in your controller:
225
249
  ```erb
226
250
  <%= form_for @user, url: users_path, html: { multipart: true } do |form| %>
227
251
  <%= form.file_field :avatar %>
252
+ <%= form.submit %>
228
253
  <% end %>
229
254
  ```
230
255
 
@@ -233,6 +258,7 @@ end
233
258
  ```erb
234
259
  <%= simple_form_for @user, url: users_path do |form| %>
235
260
  <%= form.input :avatar, as: :file %>
261
+ <%= form.submit %>
236
262
  <% end %>
237
263
  ```
238
264
 
@@ -240,7 +266,7 @@ end
240
266
 
241
267
  ```ruby
242
268
  def create
243
- @user = User.create( user_params )
269
+ @user = User.create(user_params)
244
270
  end
245
271
 
246
272
  private
@@ -254,7 +280,7 @@ end
254
280
  ```
255
281
 
256
282
  ### View Helpers
257
-
283
+ Add these to the view where you want your images displayed:
258
284
  ```erb
259
285
  <%= image_tag @user.avatar.url %>
260
286
  <%= image_tag @user.avatar.url(:medium) %>
@@ -337,7 +363,7 @@ Lastly, you can also define multiple validations on a single attachment using `v
337
363
 
338
364
  ```ruby
339
365
  validates_attachment :avatar, presence: true,
340
- content_type: { content_type: "image/jpeg" },
366
+ content_type: "image/jpeg",
341
367
  size: { in: 0..10.kilobytes }
342
368
  ```
343
369
 
@@ -347,7 +373,7 @@ called with valid attachments._
347
373
 
348
374
  ```ruby
349
375
  class Message < ActiveRecord::Base
350
- has_attached_file :asset, styles: {thumb: "100x100#"}
376
+ has_attached_file :asset, styles: { thumb: "100x100#" }
351
377
 
352
378
  before_post_process :skip_for_audio
353
379
 
@@ -363,8 +389,8 @@ afterwards, then assign manually:
363
389
 
364
390
  ```ruby
365
391
  class Book < ActiveRecord::Base
366
- has_attached_file :document, styles: {thumbnail: "60x60#"}
367
- validates_attachment :document, content_type: { content_type: "application/pdf" }
392
+ has_attached_file :document, styles: { thumbnail: "60x60#" }
393
+ validates_attachment :document, content_type: "application/pdf"
368
394
  validates_something_else # Other validations that conflict with Paperclip's
369
395
  end
370
396
 
@@ -396,7 +422,7 @@ image-y ones:
396
422
 
397
423
  ```ruby
398
424
  validates_attachment :avatar,
399
- content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
425
+ content_type: ["image/jpeg", "image/gif", "image/png"]
400
426
  ```
401
427
 
402
428
  `Paperclip::ContentTypeDetector` will attempt to match a file's extension to an
@@ -563,7 +589,7 @@ Storage
563
589
  Paperclip ships with 3 storage adapters:
564
590
 
565
591
  * File Storage
566
- * S3 Storage (via `aws-sdk`)
592
+ * S3 Storage (via `aws-sdk-s3`)
567
593
  * Fog Storage
568
594
 
569
595
  If you would like to use Paperclip with another storage, you can install these
@@ -589,10 +615,10 @@ _**NOTE**: This is a change from previous versions of Paperclip, but is overall
589
615
  safer choice for the default file store._
590
616
 
591
617
  You may also choose to store your files using Amazon's S3 service. To do so, include
592
- the `aws-sdk` gem in your Gemfile:
618
+ the `aws-sdk-s3` gem in your Gemfile:
593
619
 
594
620
  ```ruby
595
- gem 'aws-sdk', '~> 2.3.0'
621
+ gem 'aws-sdk-s3'
596
622
  ```
597
623
 
598
624
  And then you can specify using S3 from `has_attached_file`.
@@ -656,6 +682,14 @@ JPGs will remain JPGs). `Paperclip::Thumbnail` uses ImageMagick to process
656
682
  images; [ImageMagick's geometry documentation](http://www.imagemagick.org/script/command-line-processing.php#geometry)
657
683
  has more information on the accepted style formats.
658
684
 
685
+ For more fine-grained control of the conversion process, `source_file_options` and `convert_options` can be used to pass flags and settings directly to ImageMagick's powerful Convert tool, [documented here](https://www.imagemagick.org/script/convert.php). For example:
686
+
687
+ ```ruby
688
+ has_attached_file :image, styles: { regular: ['800x800>', :png]},
689
+ source_file_options: { regular: "-density 96 -depth 8 -quality 85" },
690
+ convert_options: { regular: "-posterize 3"}
691
+ ```
692
+
659
693
  ImageMagick supports a number of environment variables for controlling its resource limits. For example, you can enforce memory or execution time limits by setting the following variables in your application's process environment:
660
694
 
661
695
  * `MAGICK_MEMORY_LIMIT=128MiB`
@@ -738,7 +772,7 @@ called with valid attachments._
738
772
 
739
773
  ```ruby
740
774
  class Message < ActiveRecord::Base
741
- has_attached_file :asset, styles: {thumb: "100x100#"}
775
+ has_attached_file :asset, styles: { thumb: "100x100#" }
742
776
 
743
777
  before_post_process :skip_for_audio
744
778
 
@@ -983,7 +1017,7 @@ similar mechanism for whichever parallel testing library you use.
983
1017
 
984
1018
  **Integration Tests**
985
1019
 
986
- Using integration tests with FactoryGirl may save multiple copies of
1020
+ Using integration tests with FactoryBot may save multiple copies of
987
1021
  your test files within the app. To avoid this, specify a custom path in
988
1022
  the `config/environments/test.rb` like so:
989
1023
 
@@ -1000,11 +1034,11 @@ config.after(:suite) do
1000
1034
  end
1001
1035
  ```
1002
1036
 
1003
- **Example of test configuration with Factory Girl**
1037
+ **Example of test configuration with Factory Bot**
1004
1038
 
1005
1039
 
1006
1040
  ```ruby
1007
- FactoryGirl.define do
1041
+ FactoryBot.define do
1008
1042
  factory :user do
1009
1043
  avatar { File.new("#{Rails.root}/spec/support/fixtures/image.jpg") }
1010
1044
  end
data/UPGRADING CHANGED
@@ -2,9 +2,9 @@
2
2
  # NOTE FOR UPGRADING FROM 4.3.0 OR EARLIER #
3
3
  ##################################################
4
4
 
5
- Paperclip is now compatible with aws-sdk >= 2.0.0.
5
+ Paperclip is now compatible with aws-sdk-s3.
6
6
 
7
- If you are using S3 storage, aws-sdk >= 2.0.0 requires you to make a few small
7
+ If you are using S3 storage, aws-sdk-s3 requires you to make a few small
8
8
  changes:
9
9
 
10
10
  * You must set the `s3_region`
@@ -13,5 +13,5 @@ changes:
13
13
  using a hyphen. For example, `:public_read` needs to be changed to
14
14
  `public-read`.
15
15
 
16
- For a walkthrough of upgrading from 4 to 5 and aws-sdk >= 2.0 you can watch
16
+ For a walkthrough of upgrading from 4 to *5* (not 6) and aws-sdk >= 2.0 you can watch
17
17
  http://rubythursday.com/episodes/ruby-snack-27-upgrade-paperclip-and-aws-sdk-in-prep-for-rails-5
@@ -84,12 +84,12 @@ end
84
84
 
85
85
  Then /^I should have attachment columns for "([^"]*)"$/ do |attachment_name|
86
86
  cd(".") do
87
- columns = eval(`bundle exec rails runner "puts User.columns.map{ |column| [column.name, column.type] }.inspect"`.strip)
87
+ columns = eval(`bundle exec rails runner "puts User.columns.map{ |column| [column.name, column.sql_type] }.inspect"`.strip)
88
88
  expect_columns = [
89
- ["#{attachment_name}_file_name", :string],
90
- ["#{attachment_name}_content_type", :string],
91
- ["#{attachment_name}_file_size", :integer],
92
- ["#{attachment_name}_updated_at", :datetime]
89
+ ["#{attachment_name}_file_name", "varchar"],
90
+ ["#{attachment_name}_content_type", "varchar"],
91
+ ["#{attachment_name}_file_size", "bigint"],
92
+ ["#{attachment_name}_updated_at", "datetime"]
93
93
  ]
94
94
  expect(columns).to include(*expect_columns)
95
95
  end
@@ -97,12 +97,12 @@ end
97
97
 
98
98
  Then /^I should not have attachment columns for "([^"]*)"$/ do |attachment_name|
99
99
  cd(".") do
100
- columns = eval(`bundle exec rails runner "puts User.columns.map{ |column| [column.name, column.type] }.inspect"`.strip)
100
+ columns = eval(`bundle exec rails runner "puts User.columns.map{ |column| [column.name, column.sql_type] }.inspect"`.strip)
101
101
  expect_columns = [
102
- ["#{attachment_name}_file_name", :string],
103
- ["#{attachment_name}_content_type", :string],
104
- ["#{attachment_name}_file_size", :integer],
105
- ["#{attachment_name}_updated_at", :datetime]
102
+ ["#{attachment_name}_file_name", "varchar"],
103
+ ["#{attachment_name}_content_type", "varchar"],
104
+ ["#{attachment_name}_file_size", "bigint"],
105
+ ["#{attachment_name}_updated_at", "datetime"]
106
106
  ]
107
107
 
108
108
  expect(columns).not_to include(*expect_columns)
@@ -17,7 +17,7 @@ Given /^I generate a new rails application$/ do
17
17
  gem "jruby-openssl", :platform => :jruby
18
18
  gem "capybara"
19
19
  gem "gherkin"
20
- gem "aws-sdk", "~> 2.0.0"
20
+ gem "aws-sdk-s3"
21
21
  gem "racc", :platform => :rbx
22
22
  gem "rubysl", :platform => :rbx
23
23
  """
@@ -13,7 +13,9 @@ class PaperclipGenerator < ActiveRecord::Generators::Base
13
13
  end
14
14
 
15
15
  def generate_migration
16
- migration_template "paperclip_migration.rb.erb", "db/migrate/#{migration_file_name}"
16
+ migration_template("paperclip_migration.rb.erb",
17
+ "db/migrate/#{migration_file_name}",
18
+ migration_version: migration_version)
17
19
  end
18
20
 
19
21
  def migration_name
@@ -27,4 +29,10 @@ class PaperclipGenerator < ActiveRecord::Generators::Base
27
29
  def migration_class_name
28
30
  migration_name.camelize
29
31
  end
32
+
33
+ def migration_version
34
+ if Rails.version.start_with? "5"
35
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
36
+ end
37
+ end
30
38
  end
@@ -1,4 +1,4 @@
1
- class <%= migration_class_name %> < ActiveRecord::Migration
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  change_table :<%= table_name %> do |t|
4
4
  <% attachment_names.each do |attachment| -%>
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'uri'
3
2
  require 'paperclip/url_generator'
4
3
  require 'active_support/deprecation'
@@ -338,8 +337,15 @@ module Paperclip
338
337
  # inconsistencies in timing of S3 commands. It's possible that calling
339
338
  # #reprocess! will lose data if the files are not kept.
340
339
  def reprocess!(*style_args)
341
- saved_only_process, @options[:only_process] = @options[:only_process], style_args
342
- saved_preserve_files, @options[:preserve_files] = @options[:preserve_files], true
340
+ saved_flags = @options.slice(
341
+ :only_process,
342
+ :preserve_files,
343
+ :check_validity_before_processing
344
+ )
345
+ @options[:only_process] = style_args
346
+ @options[:preserve_files] = true
347
+ @options[:check_validity_before_processing] = false
348
+
343
349
  begin
344
350
  assign(self)
345
351
  save
@@ -348,8 +354,7 @@ module Paperclip
348
354
  warn "#{e} - skipping file."
349
355
  false
350
356
  ensure
351
- @options[:only_process] = saved_only_process
352
- @options[:preserve_files] = saved_preserve_files
357
+ @options.merge!(saved_flags)
353
358
  end
354
359
  end
355
360
 
@@ -532,6 +537,10 @@ module Paperclip
532
537
  reduce(original) do |file, processor|
533
538
  file = Paperclip.processor(processor).make(file, style.processor_options, self)
534
539
  intermediate_files << file unless file == @queued_for_write[:original]
540
+ # if we're processing the original, close + unlink the source tempfile
541
+ if name == :original
542
+ @queued_for_write[:original].close(true)
543
+ end
535
544
  file
536
545
  end
537
546
 
@@ -591,7 +600,11 @@ module Paperclip
591
600
  def unlink_files(files)
592
601
  Array(files).each do |file|
593
602
  file.close unless file.closed?
594
- file.unlink if file.respond_to?(:unlink) && file.path.present? && File.exist?(file.path)
603
+
604
+ begin
605
+ file.unlink if file.respond_to?(:unlink)
606
+ rescue Errno::ENOENT
607
+ end
595
608
  end
596
609
  end
597
610
 
@@ -16,7 +16,7 @@ module Paperclip
16
16
  # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
17
17
  type = begin
18
18
  Paperclip.run("file", "-b --mime :file", file: @filename)
19
- rescue Cocaine::CommandLineError => e
19
+ rescue Terrapin::CommandLineError => e
20
20
  Paperclip.log("Error while determining content type: #{e}")
21
21
  SENSIBLE_DEFAULT
22
22
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Paperclip
3
2
  class FilenameCleaner
4
3
  def initialize(invalid_character_regex)
@@ -17,16 +17,16 @@ module Paperclip
17
17
  orientation = Paperclip.options[:use_exif_orientation] ?
18
18
  "%[exif:orientation]" : "1"
19
19
  Paperclip.run(
20
- "identify",
20
+ Paperclip.options[:is_windows] ? "magick identify" : "identify",
21
21
  "-format '%wx%h,#{orientation}' :file", {
22
22
  :file => "#{path}[0]"
23
23
  }, {
24
24
  :swallow_stderr => true
25
25
  }
26
26
  )
27
- rescue Cocaine::ExitStatusError
27
+ rescue Terrapin::ExitStatusError
28
28
  ""
29
- rescue Cocaine::CommandNotFoundError => e
29
+ rescue Terrapin::CommandNotFoundError => e
30
30
  raise_because_imagemagick_missing
31
31
  end
32
32
  end
@@ -27,12 +27,12 @@ module Paperclip
27
27
  #
28
28
  def run(cmd, arguments = "", interpolation_values = {}, local_options = {})
29
29
  command_path = options[:command_path]
30
- cocaine_path_array = Cocaine::CommandLine.path.try(:split, Cocaine::OS.path_separator)
31
- Cocaine::CommandLine.path = [cocaine_path_array, command_path].flatten.compact.uniq
30
+ terrapin_path_array = Terrapin::CommandLine.path.try(:split, Terrapin::OS.path_separator)
31
+ Terrapin::CommandLine.path = [terrapin_path_array, command_path].flatten.compact.uniq
32
32
  if logging? && (options[:log_command] || local_options[:log_command])
33
33
  local_options = local_options.merge(:logger => logger)
34
34
  end
35
- Cocaine::CommandLine.new(cmd, arguments, local_options).run(interpolation_values)
35
+ Terrapin::CommandLine.new(cmd, arguments, local_options).run(interpolation_values)
36
36
  end
37
37
 
38
38
  # Find all instances of the given Active Record model +klass+ with attachment +name+.
@@ -5,6 +5,7 @@ module Paperclip
5
5
  # Paperclip.interpolates method.
6
6
  module Interpolations
7
7
  extend self
8
+ ID_PARTITION_LIMIT = 1_000_000_000
8
9
 
9
10
  # Hash assignment of interpolations. Included only for compatibility,
10
11
  # and is not intended for normal use.
@@ -175,7 +176,11 @@ module Paperclip
175
176
  def id_partition attachment, style_name
176
177
  case id = attachment.instance.id
177
178
  when Integer
178
- ("%09d".freeze % id).scan(/\d{3}/).join("/".freeze)
179
+ if id < ID_PARTITION_LIMIT
180
+ ("%09d".freeze % id).scan(/\d{3}/).join("/".freeze)
181
+ else
182
+ ("%012d".freeze % id).scan(/\d{3}/).join("/".freeze)
183
+ end
179
184
  when String
180
185
  id.scan(/.{3}/).first(3).join("/".freeze)
181
186
  else
@@ -4,7 +4,7 @@ module Paperclip
4
4
  class AbstractAdapter
5
5
  OS_RESTRICTED_CHARACTERS = %r{[/:]}
6
6
 
7
- attr_reader :content_type, :original_filename, :size
7
+ attr_reader :content_type, :original_filename, :size, :tempfile
8
8
  delegate :binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :readbyte, :rewind, :unlink, :to => :@tempfile
9
9
  alias :length :size
10
10
 
@@ -57,13 +57,18 @@ module Paperclip
57
57
  end
58
58
 
59
59
  def link_or_copy_file(src, dest)
60
- Paperclip.log("Trying to link #{src} to #{dest}")
61
- FileUtils.ln(src, dest, force: true) # overwrite existing
60
+ begin
61
+ Paperclip.log("Trying to link #{src} to #{dest}")
62
+ FileUtils.ln(src, dest, force: true) # overwrite existing
63
+ rescue Errno::EXDEV, Errno::EPERM, Errno::ENOENT, Errno::EEXIST => e
64
+ Paperclip.log(
65
+ "Link failed with #{e.message}; copying link #{src} to #{dest}"
66
+ )
67
+ FileUtils.cp(src, dest)
68
+ end
69
+
62
70
  @destination.close
63
71
  @destination.open.binmode
64
- rescue Errno::EXDEV, Errno::EPERM, Errno::ENOENT, Errno::EEXIST => e
65
- Paperclip.log("Link failed with #{e.message}; copying link #{src} to #{dest}")
66
- FileUtils.cp(src, dest)
67
72
  end
68
73
  end
69
74
  end
@@ -31,7 +31,13 @@ module Paperclip
31
31
  if source.staged?
32
32
  link_or_copy_file(source.staged_path(@style), destination.path)
33
33
  else
34
- source.copy_to_local_file(@style, destination.path)
34
+ begin
35
+ source.copy_to_local_file(@style, destination.path)
36
+ rescue Errno::EACCES
37
+ # clean up lingering tempfile if we cannot access source file
38
+ destination.close(true)
39
+ raise
40
+ end
35
41
  end
36
42
  destination
37
43
  end
@@ -9,7 +9,8 @@ module Paperclip
9
9
  REGEXP = /\Ahttps?:\/\//
10
10
 
11
11
  def initialize(target, options = {})
12
- super(URI(URI.escape(target)), options)
12
+ escaped = URI.escape(target)
13
+ super(URI(target == URI.unescape(target) ? escaped : target), options)
13
14
  end
14
15
  end
15
16
  end
@@ -28,15 +28,17 @@ module Paperclip
28
28
  end
29
29
 
30
30
  def content_type_from_content
31
- if @content.respond_to?(:content_type)
32
- @content.content_type
33
- end
31
+ @content.meta["content-type"].presence
34
32
  end
35
33
 
36
34
  def filename_from_content_disposition
37
- if @content.meta.key?("content-disposition")
38
- matches = @content.meta["content-disposition"].match(/filename="([^"]*)"/)
39
- matches[1] if matches
35
+ if @content.meta.key?("content-disposition") && @content.meta["content-disposition"].match(/filename/i)
36
+ # can include both filename and filename* values according to RCF6266. filename should come first
37
+ _, filename = @content.meta["content-disposition"].split(/filename\*?\s*=\s*/i)
38
+
39
+ # filename can be enclosed in quotes or not
40
+ matches = filename.match(/"(.*)"/)
41
+ matches ? matches[1] : filename.split(';')[0]
40
42
  end
41
43
  end
42
44
 
@@ -2,7 +2,7 @@ module Paperclip
2
2
  module Logger
3
3
  # Log a paperclip-specific line. This will log to STDOUT
4
4
  # by default. Set Paperclip.options[:log] to false to turn off.
5
- def log message
5
+ def log(message)
6
6
  logger.info("[paperclip] #{message}") if logging?
7
7
  end
8
8
 
@@ -11,7 +11,7 @@ module Paperclip
11
11
  end
12
12
 
13
13
  def spoofed?
14
- if has_name? && has_extension? && media_type_mismatch? && mapping_override_mismatch?
14
+ if has_name? && media_type_mismatch? && mapping_override_mismatch?
15
15
  Paperclip.log("Content Type Spoof: Filename #{File.basename(@name)} (#{supplied_content_type} from Headers, #{content_types_from_name.map(&:to_s)} from Extension), content type discovered from file command: #{calculated_content_type}. See documentation to allow this combination.")
16
16
  true
17
17
  else
@@ -30,15 +30,18 @@ module Paperclip
30
30
  end
31
31
 
32
32
  def media_type_mismatch?
33
- supplied_type_mismatch? || calculated_type_mismatch?
33
+ extension_type_mismatch? || calculated_type_mismatch?
34
34
  end
35
35
 
36
- def supplied_type_mismatch?
37
- supplied_media_type.present? && !media_types_from_name.include?(supplied_media_type)
36
+ def extension_type_mismatch?
37
+ supplied_media_type.present? &&
38
+ has_extension? &&
39
+ !media_types_from_name.include?(supplied_media_type)
38
40
  end
39
41
 
40
42
  def calculated_type_mismatch?
41
- !media_types_from_name.include?(calculated_media_type)
43
+ supplied_media_type.present? &&
44
+ !calculated_content_type.include?(supplied_media_type)
42
45
  end
43
46
 
44
47
  def mapping_override_mismatch?
@@ -72,8 +75,9 @@ module Paperclip
72
75
 
73
76
  def type_from_file_command
74
77
  begin
75
- Paperclip.run("file", "-b --mime :file", :file => @file.path).split(/[:;]\s+/).first
76
- rescue Cocaine::CommandLineError
78
+ Paperclip.run("file", "-b --mime :file", file: @file.path).
79
+ split(/[:;\s]+/).first
80
+ rescue Terrapin::CommandLineError
77
81
  ""
78
82
  end
79
83
  end
@@ -37,13 +37,21 @@ module Paperclip
37
37
  # The convert method runs the convert binary with the provided arguments.
38
38
  # See Paperclip.run for the available options.
39
39
  def convert(arguments = "", local_options = {})
40
- Paperclip.run('convert', arguments, local_options)
40
+ Paperclip.run(
41
+ Paperclip.options[:is_windows] ? "magick convert" : "convert",
42
+ arguments,
43
+ local_options,
44
+ )
41
45
  end
42
46
 
43
47
  # The identify method runs the identify binary with the provided arguments.
44
48
  # See Paperclip.run for the available options.
45
49
  def identify(arguments = "", local_options = {})
46
- Paperclip.run('identify', arguments, local_options)
50
+ Paperclip.run(
51
+ Paperclip.options[:is_windows] ? "magick identify" : "identify",
52
+ arguments,
53
+ local_options,
54
+ )
47
55
  end
48
56
  end
49
57
  end
@@ -5,7 +5,7 @@ module Paperclip
5
5
  module Schema
6
6
  COLUMNS = {:file_name => :string,
7
7
  :content_type => :string,
8
- :file_size => :integer,
8
+ :file_size => :bigint,
9
9
  :updated_at => :datetime}
10
10
 
11
11
  def self.included(base)