kt-paperclip 6.4.2 → 8.0.1
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +46 -66
- data/lib/generators/paperclip/paperclip_generator.rb +3 -1
- data/lib/kt-paperclip.rb +2 -0
- data/lib/paperclip/attachment.rb +50 -31
- data/lib/paperclip/attachment_registry.rb +2 -0
- data/lib/paperclip/callbacks.rb +7 -4
- data/lib/paperclip/commands/imagemagick/geometry_parser.rb +63 -0
- data/lib/paperclip/commands/imagemagick/version_detector.rb +41 -0
- data/lib/paperclip/commands/imagemagick.rb +44 -0
- data/lib/paperclip/commands/runner.rb +38 -0
- data/lib/paperclip/commands/unix_file.rb +28 -0
- data/lib/paperclip/content_type_detector.rb +32 -28
- data/lib/paperclip/errors.rb +2 -0
- data/lib/paperclip/file_command_content_type_detector.rb +11 -12
- data/lib/paperclip/filename_cleaner.rb +2 -0
- data/lib/paperclip/geometry.rb +22 -7
- data/lib/paperclip/geometry_detector_factory.rb +11 -31
- data/lib/paperclip/geometry_parser_factory.rb +13 -17
- data/lib/paperclip/glue.rb +5 -2
- data/lib/paperclip/has_attached_file.rb +2 -0
- data/lib/paperclip/helpers.rb +5 -25
- data/lib/paperclip/interpolations/plural_cache.rb +2 -0
- data/lib/paperclip/interpolations.rb +8 -2
- data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
- data/lib/paperclip/io_adapters/attachment_adapter.rb +11 -0
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/file_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/identity_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/nil_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/registry.rb +2 -0
- data/lib/paperclip/io_adapters/stringio_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +2 -0
- data/lib/paperclip/io_adapters/uri_adapter.rb +5 -13
- data/lib/paperclip/locales/fr.yml +18 -0
- data/lib/paperclip/locales/gd.yml +20 -0
- data/lib/paperclip/logger.rb +2 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +5 -3
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -0
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -0
- data/lib/paperclip/matchers.rb +2 -0
- data/lib/paperclip/media_type_spoof_detector.rb +45 -11
- data/lib/paperclip/missing_attachment_styles.rb +2 -0
- data/lib/paperclip/processor.rb +6 -19
- data/lib/paperclip/processor_helpers.rb +2 -0
- data/lib/paperclip/rails_environment.rb +2 -0
- data/lib/paperclip/railtie.rb +2 -0
- data/lib/paperclip/schema.rb +8 -6
- data/lib/paperclip/storage/filesystem.rb +3 -1
- data/lib/paperclip/storage/fog.rb +14 -5
- data/lib/paperclip/storage/s3.rb +44 -8
- data/lib/paperclip/storage.rb +2 -0
- data/lib/paperclip/style.rb +2 -0
- data/lib/paperclip/tempfile.rb +2 -0
- data/lib/paperclip/tempfile_factory.rb +2 -0
- data/lib/paperclip/thumbnail.rb +9 -10
- data/lib/paperclip/url_generator.rb +2 -0
- data/lib/paperclip/validators/attachment_content_type_validator.rb +2 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +3 -1
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +2 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +2 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +4 -1
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +2 -0
- data/lib/paperclip/validators.rb +2 -0
- data/lib/paperclip/version.rb +3 -1
- data/lib/paperclip.rb +26 -6
- data/lib/tasks/paperclip.rake +9 -4
- data/shoulda_macros/paperclip.rb +2 -0
- metadata +22 -425
- data/.codeclimate.yml +0 -17
- data/.github/FUNDING.yml +0 -3
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- data/.github/ISSUE_TEMPLATE/custom.md +0 -10
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- data/.gitignore +0 -19
- data/.hound.yml +0 -1057
- data/.rubocop.yml +0 -3
- data/.travis.yml +0 -45
- data/Appraisals +0 -24
- data/CONTRIBUTING.md +0 -86
- data/Gemfile +0 -19
- data/NEWS +0 -515
- data/RELEASING.md +0 -17
- data/Rakefile +0 -52
- data/UPGRADING +0 -17
- data/features/basic_integration.feature +0 -85
- data/features/migration.feature +0 -29
- data/features/rake_tasks.feature +0 -62
- data/features/step_definitions/attachment_steps.rb +0 -110
- data/features/step_definitions/html_steps.rb +0 -15
- data/features/step_definitions/rails_steps.rb +0 -257
- data/features/step_definitions/s3_steps.rb +0 -14
- data/features/step_definitions/web_steps.rb +0 -106
- data/features/support/env.rb +0 -12
- data/features/support/fakeweb.rb +0 -11
- data/features/support/file_helpers.rb +0 -34
- data/features/support/fixtures/boot_config.txt +0 -15
- data/features/support/fixtures/gemfile.txt +0 -5
- data/features/support/fixtures/preinitializer.txt +0 -20
- data/features/support/paths.rb +0 -28
- data/features/support/rails.rb +0 -39
- data/features/support/selectors.rb +0 -19
- data/gemfiles/4.2.gemfile +0 -20
- data/gemfiles/5.0.gemfile +0 -20
- data/gemfiles/5.1.gemfile +0 -20
- data/gemfiles/5.2.gemfile +0 -20
- data/gemfiles/6.0.gemfile +0 -20
- data/paperclip.gemspec +0 -50
- data/spec/database.yml +0 -4
- data/spec/paperclip/attachment_definitions_spec.rb +0 -13
- data/spec/paperclip/attachment_processing_spec.rb +0 -79
- data/spec/paperclip/attachment_registry_spec.rb +0 -158
- data/spec/paperclip/attachment_spec.rb +0 -1590
- data/spec/paperclip/content_type_detector_spec.rb +0 -47
- data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -40
- data/spec/paperclip/filename_cleaner_spec.rb +0 -13
- data/spec/paperclip/geometry_detector_spec.rb +0 -38
- data/spec/paperclip/geometry_parser_spec.rb +0 -73
- data/spec/paperclip/geometry_spec.rb +0 -255
- data/spec/paperclip/glue_spec.rb +0 -42
- data/spec/paperclip/has_attached_file_spec.rb +0 -78
- data/spec/paperclip/integration_spec.rb +0 -702
- data/spec/paperclip/interpolations_spec.rb +0 -270
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +0 -160
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +0 -140
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +0 -88
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +0 -17
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +0 -131
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +0 -142
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +0 -8
- data/spec/paperclip/io_adapters/nil_adapter_spec.rb +0 -25
- data/spec/paperclip/io_adapters/registry_spec.rb +0 -35
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +0 -64
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +0 -146
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +0 -231
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +0 -19
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +0 -108
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +0 -69
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +0 -88
- data/spec/paperclip/media_type_spoof_detector_spec.rb +0 -120
- data/spec/paperclip/meta_class_spec.rb +0 -30
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +0 -88
- data/spec/paperclip/paperclip_spec.rb +0 -196
- data/spec/paperclip/plural_cache_spec.rb +0 -37
- data/spec/paperclip/processor_helpers_spec.rb +0 -57
- data/spec/paperclip/processor_spec.rb +0 -26
- data/spec/paperclip/rails_environment_spec.rb +0 -30
- data/spec/paperclip/rake_spec.rb +0 -103
- data/spec/paperclip/schema_spec.rb +0 -252
- data/spec/paperclip/storage/filesystem_spec.rb +0 -79
- data/spec/paperclip/storage/fog_spec.rb +0 -560
- data/spec/paperclip/storage/s3_live_spec.rb +0 -188
- data/spec/paperclip/storage/s3_spec.rb +0 -1746
- data/spec/paperclip/style_spec.rb +0 -251
- data/spec/paperclip/tempfile_factory_spec.rb +0 -33
- data/spec/paperclip/tempfile_spec.rb +0 -35
- data/spec/paperclip/thumbnail_spec.rb +0 -504
- data/spec/paperclip/url_generator_spec.rb +0 -231
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +0 -410
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +0 -249
- data/spec/paperclip/validators/attachment_presence_validator_spec.rb +0 -85
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +0 -325
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +0 -48
- data/spec/paperclip/validators_spec.rb +0 -164
- data/spec/spec_helper.rb +0 -45
- data/spec/support/assertions.rb +0 -84
- data/spec/support/fake_model.rb +0 -24
- data/spec/support/fake_rails.rb +0 -12
- data/spec/support/fixtures/12k.png +0 -0
- data/spec/support/fixtures/50x50.png +0 -0
- data/spec/support/fixtures/5k.png +0 -0
- data/spec/support/fixtures/animated +0 -0
- data/spec/support/fixtures/animated.gif +0 -0
- data/spec/support/fixtures/animated.unknown +0 -0
- data/spec/support/fixtures/aws_s3.yml +0 -13
- data/spec/support/fixtures/bad.png +0 -1
- data/spec/support/fixtures/empty.html +0 -1
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/fog.yml +0 -8
- data/spec/support/fixtures/rotated.jpg +0 -0
- data/spec/support/fixtures/s3.yml +0 -8
- data/spec/support/fixtures/spaced file.jpg +0 -0
- data/spec/support/fixtures/spaced file.png +0 -0
- data/spec/support/fixtures/text.txt +0 -1
- data/spec/support/fixtures/twopage.pdf +0 -0
- data/spec/support/fixtures/uppercase.PNG +0 -0
- data/spec/support/matchers/accept.rb +0 -5
- data/spec/support/matchers/exist.rb +0 -5
- data/spec/support/matchers/have_column.rb +0 -23
- data/spec/support/mock_attachment.rb +0 -24
- data/spec/support/mock_interpolator.rb +0 -24
- data/spec/support/mock_url_generator_builder.rb +0 -26
- data/spec/support/model_reconstruction.rb +0 -72
- data/spec/support/reporting.rb +0 -11
- data/spec/support/test_data.rb +0 -13
- data/spec/support/version_helper.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71b12469bab65eb2861d1170c154ecf1a08f6a0591806096f3d49f598f4ec115
|
|
4
|
+
data.tar.gz: 12efe7db20633834994b3b1836cc697ff21dbf1bd37851346d1bd5e0961aa045
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6db416b89eaa01127e3b8eb7ac7615a19d840a236ea114be4814675d61765fa53f25e25b351b5d9438badf06ab3a20ec036565a418f47dbbcd97563d96e0f91f
|
|
7
|
+
data.tar.gz: 8aa390b628e9926d17c9de71e0dfe861fe2197762fff916064e1b61bd18fda5e3d2f6eda291d4e208e36ecb2fa3fc98ca366e5a28c479f7dde00b02736be2765
|
data/LICENSE
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
1
|
LICENSE
|
|
3
2
|
|
|
4
3
|
The MIT License
|
|
5
4
|
|
|
6
5
|
Copyright (c) 2008-2016 Jon Yurek and thoughtbot, inc.
|
|
6
|
+
Copyright (c) 2019-2025 Kreeti Technologies Pvt Ltd.
|
|
7
7
|
|
|
8
8
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
9
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
|
@@ -90,76 +90,44 @@ Requirements
|
|
|
90
90
|
|
|
91
91
|
### Ruby and Rails
|
|
92
92
|
|
|
93
|
-
Paperclip now requires Ruby version **>= 2.
|
|
93
|
+
Paperclip now requires Ruby version **>= 2.7** and Rails version **>= 5.2**
|
|
94
94
|
(only if you're going to use Paperclip with Ruby on Rails).
|
|
95
95
|
|
|
96
|
-
### Image Processor
|
|
96
|
+
### ImageMagick Image Processor
|
|
97
97
|
|
|
98
|
-
[ImageMagick](http://www.imagemagick.org) must be installed and Paperclip must have access to it.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
[ImageMagick](http://www.imagemagick.org) must be installed and Paperclip must have access to it.
|
|
99
|
+
Refer to ImageMagick's [installations instructions](https://imagemagick.org/download/).
|
|
100
|
+
ImageMagick 7 is the latest version. As of April 2026, some package managers such as `apt`
|
|
101
|
+
still install ImageMagick 6.
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
In development mode, you might add this line to `config/environments/development.rb)`:
|
|
103
|
+
Paperclip supports both ImageMagick versions 6 and 7, and will auto-detect your version.
|
|
104
|
+
You may enforce a specific version in an initializer such as `config/initializers/paperclip.rb`:
|
|
107
105
|
|
|
108
106
|
```ruby
|
|
109
|
-
Paperclip.options[:
|
|
107
|
+
Paperclip.options[:imagemagick_version] = "7"
|
|
110
108
|
```
|
|
111
109
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
brew install imagemagick
|
|
115
|
-
|
|
116
|
-
If you are dealing with pdf uploads or running the test suite, you'll also need
|
|
117
|
-
to install GhostScript. On Mac OS X, you can also install that using Homebrew:
|
|
118
|
-
|
|
119
|
-
brew install gs
|
|
120
|
-
|
|
121
|
-
If you are on Ubuntu (or any Debian base Linux distribution), you'll want to run
|
|
122
|
-
the following with apt-get:
|
|
123
|
-
|
|
124
|
-
sudo apt-get install imagemagick -y
|
|
125
|
-
|
|
126
|
-
### `file`
|
|
127
|
-
|
|
128
|
-
The Unix [`file` command](https://en.wikipedia.org/wiki/File_(command)) is required for content-type checking.
|
|
129
|
-
This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
|
|
130
|
-
so Windows users must make sure that the devkit is installed and added to the system `PATH`.
|
|
131
|
-
|
|
132
|
-
**Manual Installation**
|
|
133
|
-
|
|
134
|
-
If you're using Windows 7+ as a development environment, you may need to install the `file.exe` application manually. The `file spoofing` system in Paperclip 4+ relies on this; if you don't have it working, you'll receive `Validation failed: Upload file has an extension that does not match its contents.` errors.
|
|
135
|
-
|
|
136
|
-
To manually install, you should perform the following:
|
|
110
|
+
Please ensure ImageMagick is in your environment path, or alternatively set
|
|
111
|
+
the path manually in an initializer:
|
|
137
112
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-

|
|
142
|
-
|
|
143
|
-
Next, you need to integrate with your environment - preferably through the `PATH` variable, or by changing your `config/environments/development.rb` file
|
|
144
|
-
|
|
145
|
-
**PATH**
|
|
146
|
-
|
|
147
|
-
1. Click "Start"
|
|
148
|
-
2. On "Computer", right-click and select "Properties"
|
|
149
|
-
3. In Properties, select "Advanced System Settings"
|
|
150
|
-
4. Click the "Environment Variables" button
|
|
151
|
-
5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`)
|
|
152
|
-
6. Restart any CMD shells you have open & see if it works
|
|
113
|
+
```ruby
|
|
114
|
+
Paperclip.options[:imagemagick_path] = "/usr/local/bin/"
|
|
115
|
+
```
|
|
153
116
|
|
|
154
|
-
|
|
117
|
+
### Optional: Unix `file` Command
|
|
155
118
|
|
|
156
|
-
|
|
119
|
+
Paperclip uses the [Marcel gem](https://github.com/rails/marcel) to detect file content types.
|
|
120
|
+
If Marcel cannot detect the type, the [Unix `file` command](https://en.wikipedia.org/wiki/File_(command))
|
|
121
|
+
is used as an optional fallback. To use it, ensure `file` is in your environment path,
|
|
122
|
+
or alternatively set its path manually in an initializer:
|
|
157
123
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
124
|
+
```ruby
|
|
125
|
+
Paperclip.options[:file_command_path] = "/usr/local/bin/"
|
|
126
|
+
```
|
|
161
127
|
|
|
162
|
-
|
|
128
|
+
Windows users should install the `file` utility via the Ruby Installer for Windows'
|
|
129
|
+
[DevKit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit), or alternatively,
|
|
130
|
+
by installing [MSYS2](https://www.msys2.org/) which provides Unix utilities for Windows.
|
|
163
131
|
|
|
164
132
|
---
|
|
165
133
|
|
|
@@ -171,7 +139,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
|
|
|
171
139
|
Include the gem in your Gemfile:
|
|
172
140
|
|
|
173
141
|
```ruby
|
|
174
|
-
gem "kt-paperclip", "~>
|
|
142
|
+
gem "kt-paperclip", "~> 8.0"
|
|
175
143
|
```
|
|
176
144
|
|
|
177
145
|
Or, if you want to get the latest, you can get master from the main paperclip repository:
|
|
@@ -407,8 +375,10 @@ validates_attachment :avatar,
|
|
|
407
375
|
content_type: ["image/jpeg", "image/gif", "image/png"]
|
|
408
376
|
```
|
|
409
377
|
|
|
410
|
-
`Paperclip::ContentTypeDetector`
|
|
411
|
-
|
|
378
|
+
`Paperclip::ContentTypeDetector` uses the file's extension as a hint when the contents alone are
|
|
379
|
+
ambiguous, so the stored `content_type` is not by itself proof of what a file contains. The check
|
|
380
|
+
that ignores the filename entirely is `validates_media_type_spoof_detection` (see Security
|
|
381
|
+
Validations below); use it alongside your `content_type` validation.
|
|
412
382
|
|
|
413
383
|
### Duplicate error messages
|
|
414
384
|
|
|
@@ -476,17 +446,26 @@ being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
|
|
|
476
446
|
`.jpg` extension. This validation will only add validation errors to the form. It
|
|
477
447
|
will not cause errors to be raised.
|
|
478
448
|
|
|
449
|
+
The type is detected from the file's contents only, using magic-number detection plus the Unix
|
|
450
|
+
`file` utility. The filename is never consulted. Where `file` is unavailable the check falls back
|
|
451
|
+
to magic-number detection alone, which cannot identify text-based formats; content it cannot
|
|
452
|
+
identify at all is accepted rather than rejected.
|
|
453
|
+
|
|
479
454
|
This can sometimes cause false validation errors in applications that use custom
|
|
480
455
|
file extensions. In these cases you may wish to add your custom extension to the
|
|
481
456
|
list of content type mappings by creating `config/initializers/paperclip.rb`:
|
|
482
457
|
|
|
483
458
|
```ruby
|
|
484
|
-
# Allow ".foo" as an extension for files
|
|
459
|
+
# Allow ".foo" as an extension for files whose contents are detected as "text/plain".
|
|
485
460
|
Paperclip.options[:content_type_mappings] = {
|
|
486
461
|
foo: %w(text/plain)
|
|
487
462
|
}
|
|
488
463
|
```
|
|
489
464
|
|
|
465
|
+
The value is the type the *contents* detect as (what `file -b --mime` reports), not the type you
|
|
466
|
+
would like the extension to mean. Text-based formats such as SVG and CSV are the usual reason to
|
|
467
|
+
need one.
|
|
468
|
+
|
|
490
469
|
---
|
|
491
470
|
|
|
492
471
|
Defaults
|
|
@@ -592,9 +571,9 @@ Storage
|
|
|
592
571
|
|
|
593
572
|
Paperclip ships with 3 storage adapters:
|
|
594
573
|
|
|
595
|
-
* File Storage
|
|
596
|
-
* S3 Storage (via `aws-sdk-s3`)
|
|
597
|
-
* Fog Storage
|
|
574
|
+
* File Storage (`storage: :filesystem`)
|
|
575
|
+
* S3 Storage (via `aws-sdk-s3`) (`storage: :s3`)
|
|
576
|
+
* Fog Storage (`storage: :fog`)
|
|
598
577
|
|
|
599
578
|
If you would like to use Paperclip with another storage, you can install these
|
|
600
579
|
gems along side with Paperclip:
|
|
@@ -1070,5 +1049,6 @@ Thank you to all [the contributors](https://github.com/kreeti/kt-paperclip/graph
|
|
|
1070
1049
|
License
|
|
1071
1050
|
-------
|
|
1072
1051
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1052
|
+
Copyright © 2020-2021 Kreeti Technologies Pvt. Ltd.
|
|
1053
|
+
Copyright © 2008-2017 thoughtbot, inc.
|
|
1054
|
+
It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "rails/generators/active_record"
|
|
2
4
|
|
|
3
5
|
class PaperclipGenerator < ActiveRecord::Generators::Base
|
|
@@ -31,6 +33,6 @@ class PaperclipGenerator < ActiveRecord::Generators::Base
|
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def migration_version
|
|
34
|
-
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
36
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
35
37
|
end
|
|
36
38
|
end
|
data/lib/kt-paperclip.rb
CHANGED
data/lib/paperclip/attachment.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "uri"
|
|
2
4
|
require "paperclip/url_generator"
|
|
3
5
|
require "active_support/deprecation"
|
|
@@ -10,35 +12,36 @@ module Paperclip
|
|
|
10
12
|
class Attachment
|
|
11
13
|
def self.default_options
|
|
12
14
|
@default_options ||= {
|
|
13
|
-
convert_options:
|
|
14
|
-
default_style:
|
|
15
|
-
default_url:
|
|
16
|
-
escape_url:
|
|
17
|
-
restricted_characters:
|
|
18
|
-
filename_cleaner:
|
|
19
|
-
hash_data:
|
|
20
|
-
hash_digest:
|
|
21
|
-
interpolator:
|
|
22
|
-
only_process:
|
|
23
|
-
path:
|
|
24
|
-
preserve_files:
|
|
25
|
-
processors:
|
|
26
|
-
source_file_options:
|
|
27
|
-
storage:
|
|
28
|
-
styles:
|
|
29
|
-
url:
|
|
30
|
-
url_generator:
|
|
31
|
-
use_default_time_zone:
|
|
32
|
-
use_timestamp:
|
|
33
|
-
whiny:
|
|
34
|
-
validate_media_type:
|
|
35
|
-
adapter_options:
|
|
36
|
-
check_validity_before_processing:
|
|
15
|
+
convert_options: {},
|
|
16
|
+
default_style: :original,
|
|
17
|
+
default_url: "/:attachment/:style/missing.png",
|
|
18
|
+
escape_url: true,
|
|
19
|
+
restricted_characters: /[&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/,
|
|
20
|
+
filename_cleaner: nil,
|
|
21
|
+
hash_data: ":class/:attachment/:id/:style/:updated_at",
|
|
22
|
+
hash_digest: "SHA1",
|
|
23
|
+
interpolator: Paperclip::Interpolations,
|
|
24
|
+
only_process: [],
|
|
25
|
+
path: ":rails_root/public:url",
|
|
26
|
+
preserve_files: false,
|
|
27
|
+
processors: [:thumbnail],
|
|
28
|
+
source_file_options: {},
|
|
29
|
+
storage: :filesystem,
|
|
30
|
+
styles: {},
|
|
31
|
+
url: "/system/:class/:attachment/:id_partition/:style/:filename",
|
|
32
|
+
url_generator: Paperclip::UrlGenerator,
|
|
33
|
+
use_default_time_zone: true,
|
|
34
|
+
use_timestamp: true,
|
|
35
|
+
whiny: Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails],
|
|
36
|
+
validate_media_type: true,
|
|
37
|
+
adapter_options: { hash_digest: Digest::MD5 },
|
|
38
|
+
check_validity_before_processing: true,
|
|
39
|
+
return_file_attributes_on_destroy: false
|
|
37
40
|
}
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny,
|
|
41
|
-
:options, :interpolator, :source_file_options
|
|
44
|
+
:options, :interpolator, :source_file_options, :queued_for_delete
|
|
42
45
|
attr_accessor :post_processing
|
|
43
46
|
|
|
44
47
|
# Creates an Attachment object. +name+ is the name of the attachment,
|
|
@@ -69,6 +72,8 @@ module Paperclip
|
|
|
69
72
|
# +interpolator+ - the object used to interpolate filenames and URLs. Defaults to Paperclip::Interpolations
|
|
70
73
|
# +url_generator+ - the object used to generate URLs, using the interpolator. Defaults to Paperclip::UrlGenerator
|
|
71
74
|
# +escape_url+ - Perform URI escaping to URLs. Defaults to true
|
|
75
|
+
# +return_file_attributes_on_destroy+ - whether attachment-related attributes should be displayed when
|
|
76
|
+
# destroying a record. Defaults to false.
|
|
72
77
|
def initialize(name, instance, options = {})
|
|
73
78
|
@name = name.to_sym
|
|
74
79
|
@name_string = name.to_s
|
|
@@ -563,12 +568,10 @@ module Paperclip
|
|
|
563
568
|
path(style) if exists?(style)
|
|
564
569
|
end.compact
|
|
565
570
|
end
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
instance_write(:created_at, nil) if has_enabled_but_unset_created_at?
|
|
571
|
-
instance_write(:updated_at, nil)
|
|
571
|
+
|
|
572
|
+
return if show_attrs_and_destroy_callback_triggered?
|
|
573
|
+
|
|
574
|
+
clear_all_attachment_attributes
|
|
572
575
|
end
|
|
573
576
|
|
|
574
577
|
def flush_errors #:nodoc:
|
|
@@ -613,5 +616,21 @@ module Paperclip
|
|
|
613
616
|
def has_enabled_but_unset_created_at?
|
|
614
617
|
able_to_store_created_at? && !instance_read(:created_at)
|
|
615
618
|
end
|
|
619
|
+
|
|
620
|
+
# Checks whether the option to show attributes to be destroyed is enabled and whether a destroy callback has been
|
|
621
|
+
# invoked when deleting the entire record.
|
|
622
|
+
def show_attrs_and_destroy_callback_triggered?
|
|
623
|
+
@options[:return_file_attributes_on_destroy] && instance.instance_variable_get(:@_destroy_callback_already_called)
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
# Sets attachment-related attributes to `nil`.
|
|
627
|
+
def clear_all_attachment_attributes
|
|
628
|
+
instance_write(:file_name, nil)
|
|
629
|
+
instance_write(:content_type, nil)
|
|
630
|
+
instance_write(:file_size, nil)
|
|
631
|
+
instance_write(:fingerprint, nil)
|
|
632
|
+
instance_write(:created_at, nil) if has_enabled_but_unset_created_at?
|
|
633
|
+
instance_write(:updated_at, nil)
|
|
634
|
+
end
|
|
616
635
|
end
|
|
617
636
|
end
|
data/lib/paperclip/callbacks.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Paperclip
|
|
2
4
|
module Callbacks
|
|
3
5
|
def self.included(base)
|
|
@@ -9,14 +11,15 @@ module Paperclip
|
|
|
9
11
|
def define_paperclip_callbacks(*callbacks)
|
|
10
12
|
define_callbacks(*[callbacks, { terminator: hasta_la_vista_baby }].flatten)
|
|
11
13
|
callbacks.each do |callback|
|
|
12
|
-
|
|
13
|
-
def before_#{callback}(*args, &blk)
|
|
14
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
|
15
|
+
def self.before_#{callback}(*args, &blk)
|
|
14
16
|
set_callback(:#{callback}, :before, *args, &blk)
|
|
15
17
|
end
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
def self.after_#{callback}(*args, &blk)
|
|
17
20
|
set_callback(:#{callback}, :after, *args, &blk)
|
|
18
21
|
end
|
|
19
|
-
|
|
22
|
+
RUBY
|
|
20
23
|
end
|
|
21
24
|
end
|
|
22
25
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paperclip
|
|
4
|
+
module Commands
|
|
5
|
+
module ImageMagick
|
|
6
|
+
module GeometryParser
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
FORMAT = /\b(\d*)x?(\d*)\b(?:,(\d?))?(@>|>@|[><#@%^!])?/i.freeze
|
|
10
|
+
|
|
11
|
+
# Runs `magick identify` and returns a Paperclip::Geometry
|
|
12
|
+
def detect(file)
|
|
13
|
+
parse(fetch(file))
|
|
14
|
+
end
|
|
15
|
+
alias_method :from_file, :detect
|
|
16
|
+
|
|
17
|
+
# Parses a "WxH,O" string into a Paperclip::Geometry
|
|
18
|
+
def parse(string)
|
|
19
|
+
return unless (match = string&.strip&.match(FORMAT))
|
|
20
|
+
|
|
21
|
+
Paperclip::Geometry.new(
|
|
22
|
+
width: match[1],
|
|
23
|
+
height: match[2],
|
|
24
|
+
orientation: match[3],
|
|
25
|
+
modifier: match[4]
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def fetch(file)
|
|
32
|
+
filepath = path(file)
|
|
33
|
+
raise_error("Cannot find the geometry of a file with a blank name") if filepath.blank?
|
|
34
|
+
|
|
35
|
+
str = Paperclip::Commands::ImageMagick.identify(
|
|
36
|
+
"-format '%wx%h,#{orientation}' :file",
|
|
37
|
+
{ file: "#{filepath}[0]" },
|
|
38
|
+
{ swallow_stderr: true }
|
|
39
|
+
).presence
|
|
40
|
+
|
|
41
|
+
raise_error unless str
|
|
42
|
+
|
|
43
|
+
str
|
|
44
|
+
rescue Terrapin::ExitStatusError
|
|
45
|
+
raise_error
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def path(file)
|
|
49
|
+
file.respond_to?(:path) ? file.path : file
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def orientation
|
|
53
|
+
Paperclip.options[:use_exif_orientation] ? "%[exif:orientation]" : "1"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def raise_error(message = nil)
|
|
57
|
+
message ||= "Could not identify image size"
|
|
58
|
+
raise Errors::NotIdentifiedByImageMagickError.new(message)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paperclip
|
|
4
|
+
module Commands
|
|
5
|
+
module ImageMagick
|
|
6
|
+
module VersionDetector
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
# Returns 6, 7, or nil (not installed)
|
|
10
|
+
def detected_version
|
|
11
|
+
return @detected_version if defined?(@detected_version)
|
|
12
|
+
|
|
13
|
+
@detected_version = detect
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def detect
|
|
19
|
+
return 7 if valid?("magick")
|
|
20
|
+
return 6 if valid?("convert")
|
|
21
|
+
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def valid?(command)
|
|
26
|
+
run(command).to_s.include?("ImageMagick")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def run(command)
|
|
30
|
+
Paperclip::Commands::Runner.run(command, path, "-version", {}, swallow_stderr: true)
|
|
31
|
+
rescue Terrapin::CommandLineError
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def path
|
|
36
|
+
Paperclip::Commands::ImageMagick.imagemagick_path
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paperclip
|
|
4
|
+
module Commands
|
|
5
|
+
module ImageMagick
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
def convert(arguments = nil, interpolation_values = {}, local_options = {})
|
|
9
|
+
run(convert_command, imagemagick_path, arguments, interpolation_values, local_options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def identify(arguments = nil, interpolation_values = {}, local_options = {})
|
|
13
|
+
run(identify_command, imagemagick_path, arguments, interpolation_values, local_options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def imagemagick_path
|
|
17
|
+
Paperclip.options[:imagemagick_path]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def run(command, path = nil, arguments = nil, interpolation_values = {}, local_options = {})
|
|
23
|
+
Runner.run(command, path || imagemagick_path, arguments, interpolation_values, local_options)
|
|
24
|
+
rescue Terrapin::CommandNotFoundError
|
|
25
|
+
raise Errors::CommandNotFoundError.new("Could not run the `#{command}` command. Please install ImageMagick.")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns true if ImageMagick 7 is in use (either detected or forced via config)
|
|
29
|
+
def magick_command?
|
|
30
|
+
version = Paperclip.options[:imagemagick_version]&.to_i ||
|
|
31
|
+
VersionDetector.detected_version
|
|
32
|
+
!version.nil? && version >= 7
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def convert_command
|
|
36
|
+
magick_command? ? "magick" : "convert"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def identify_command
|
|
40
|
+
magick_command? ? "magick identify" : "identify"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paperclip
|
|
4
|
+
module Commands
|
|
5
|
+
module Runner
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
def run(command, path = nil, arguments = nil, interpolation_values = {}, local_options = {})
|
|
9
|
+
if Paperclip.logging? && (Paperclip.options[:log_command] || local_options[:log_command])
|
|
10
|
+
local_options = local_options.merge(logger: Paperclip.logger)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
binary = resolve_binary(command, path)
|
|
14
|
+
|
|
15
|
+
Terrapin::CommandLine.new(binary, arguments, local_options)
|
|
16
|
+
.run(interpolation_values)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def resolve_binary(command, path)
|
|
22
|
+
# @deprecated +Paperclip.options[:command_path]+ will be removed in Paperclip 8.0
|
|
23
|
+
path ||= Paperclip.options[:command_path]
|
|
24
|
+
return command unless path
|
|
25
|
+
|
|
26
|
+
# command may be multi-word (e.g. "magick identify")
|
|
27
|
+
words = command.split(" ", 2)
|
|
28
|
+
candidate = File.join(path, words[0])
|
|
29
|
+
if File.executable?(candidate)
|
|
30
|
+
words[0] = candidate
|
|
31
|
+
words.join(" ")
|
|
32
|
+
else
|
|
33
|
+
command
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paperclip
|
|
4
|
+
module Commands
|
|
5
|
+
module UnixFile
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
# Returns a normalized content type value, otherwise nil.
|
|
9
|
+
def detect_content_type(file)
|
|
10
|
+
type = run_file_command(file)
|
|
11
|
+
return if type.blank? || type.match(/\(.*?\)/)
|
|
12
|
+
|
|
13
|
+
type.split(/[:;\s]+/)[0].strip
|
|
14
|
+
rescue Terrapin::CommandLineError => e
|
|
15
|
+
Paperclip.log("Error while determining content type: #{e}")
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def run_file_command(file)
|
|
22
|
+
Runner.run("file", Paperclip.options[:file_command_path], "-b --mime :file", { file: file })
|
|
23
|
+
rescue Terrapin::CommandLineError
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|