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.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +46 -66
  4. data/lib/generators/paperclip/paperclip_generator.rb +3 -1
  5. data/lib/kt-paperclip.rb +2 -0
  6. data/lib/paperclip/attachment.rb +50 -31
  7. data/lib/paperclip/attachment_registry.rb +2 -0
  8. data/lib/paperclip/callbacks.rb +7 -4
  9. data/lib/paperclip/commands/imagemagick/geometry_parser.rb +63 -0
  10. data/lib/paperclip/commands/imagemagick/version_detector.rb +41 -0
  11. data/lib/paperclip/commands/imagemagick.rb +44 -0
  12. data/lib/paperclip/commands/runner.rb +38 -0
  13. data/lib/paperclip/commands/unix_file.rb +28 -0
  14. data/lib/paperclip/content_type_detector.rb +32 -28
  15. data/lib/paperclip/errors.rb +2 -0
  16. data/lib/paperclip/file_command_content_type_detector.rb +11 -12
  17. data/lib/paperclip/filename_cleaner.rb +2 -0
  18. data/lib/paperclip/geometry.rb +22 -7
  19. data/lib/paperclip/geometry_detector_factory.rb +11 -31
  20. data/lib/paperclip/geometry_parser_factory.rb +13 -17
  21. data/lib/paperclip/glue.rb +5 -2
  22. data/lib/paperclip/has_attached_file.rb +2 -0
  23. data/lib/paperclip/helpers.rb +5 -25
  24. data/lib/paperclip/interpolations/plural_cache.rb +2 -0
  25. data/lib/paperclip/interpolations.rb +8 -2
  26. data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
  27. data/lib/paperclip/io_adapters/attachment_adapter.rb +11 -0
  28. data/lib/paperclip/io_adapters/data_uri_adapter.rb +2 -0
  29. data/lib/paperclip/io_adapters/empty_string_adapter.rb +2 -0
  30. data/lib/paperclip/io_adapters/file_adapter.rb +2 -0
  31. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +2 -0
  32. data/lib/paperclip/io_adapters/identity_adapter.rb +2 -0
  33. data/lib/paperclip/io_adapters/nil_adapter.rb +2 -0
  34. data/lib/paperclip/io_adapters/registry.rb +2 -0
  35. data/lib/paperclip/io_adapters/stringio_adapter.rb +2 -0
  36. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +2 -0
  37. data/lib/paperclip/io_adapters/uri_adapter.rb +5 -13
  38. data/lib/paperclip/locales/fr.yml +18 -0
  39. data/lib/paperclip/locales/gd.yml +20 -0
  40. data/lib/paperclip/logger.rb +2 -0
  41. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -0
  42. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +5 -3
  43. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -0
  44. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -0
  45. data/lib/paperclip/matchers.rb +2 -0
  46. data/lib/paperclip/media_type_spoof_detector.rb +45 -11
  47. data/lib/paperclip/missing_attachment_styles.rb +2 -0
  48. data/lib/paperclip/processor.rb +6 -19
  49. data/lib/paperclip/processor_helpers.rb +2 -0
  50. data/lib/paperclip/rails_environment.rb +2 -0
  51. data/lib/paperclip/railtie.rb +2 -0
  52. data/lib/paperclip/schema.rb +8 -6
  53. data/lib/paperclip/storage/filesystem.rb +3 -1
  54. data/lib/paperclip/storage/fog.rb +14 -5
  55. data/lib/paperclip/storage/s3.rb +44 -8
  56. data/lib/paperclip/storage.rb +2 -0
  57. data/lib/paperclip/style.rb +2 -0
  58. data/lib/paperclip/tempfile.rb +2 -0
  59. data/lib/paperclip/tempfile_factory.rb +2 -0
  60. data/lib/paperclip/thumbnail.rb +9 -10
  61. data/lib/paperclip/url_generator.rb +2 -0
  62. data/lib/paperclip/validators/attachment_content_type_validator.rb +2 -0
  63. data/lib/paperclip/validators/attachment_file_name_validator.rb +3 -1
  64. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +2 -0
  65. data/lib/paperclip/validators/attachment_presence_validator.rb +2 -0
  66. data/lib/paperclip/validators/attachment_size_validator.rb +4 -1
  67. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +2 -0
  68. data/lib/paperclip/validators.rb +2 -0
  69. data/lib/paperclip/version.rb +3 -1
  70. data/lib/paperclip.rb +26 -6
  71. data/lib/tasks/paperclip.rake +9 -4
  72. data/shoulda_macros/paperclip.rb +2 -0
  73. metadata +22 -425
  74. data/.codeclimate.yml +0 -17
  75. data/.github/FUNDING.yml +0 -3
  76. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  77. data/.github/ISSUE_TEMPLATE/custom.md +0 -10
  78. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  79. data/.gitignore +0 -19
  80. data/.hound.yml +0 -1057
  81. data/.rubocop.yml +0 -3
  82. data/.travis.yml +0 -45
  83. data/Appraisals +0 -24
  84. data/CONTRIBUTING.md +0 -86
  85. data/Gemfile +0 -19
  86. data/NEWS +0 -515
  87. data/RELEASING.md +0 -17
  88. data/Rakefile +0 -52
  89. data/UPGRADING +0 -17
  90. data/features/basic_integration.feature +0 -85
  91. data/features/migration.feature +0 -29
  92. data/features/rake_tasks.feature +0 -62
  93. data/features/step_definitions/attachment_steps.rb +0 -110
  94. data/features/step_definitions/html_steps.rb +0 -15
  95. data/features/step_definitions/rails_steps.rb +0 -257
  96. data/features/step_definitions/s3_steps.rb +0 -14
  97. data/features/step_definitions/web_steps.rb +0 -106
  98. data/features/support/env.rb +0 -12
  99. data/features/support/fakeweb.rb +0 -11
  100. data/features/support/file_helpers.rb +0 -34
  101. data/features/support/fixtures/boot_config.txt +0 -15
  102. data/features/support/fixtures/gemfile.txt +0 -5
  103. data/features/support/fixtures/preinitializer.txt +0 -20
  104. data/features/support/paths.rb +0 -28
  105. data/features/support/rails.rb +0 -39
  106. data/features/support/selectors.rb +0 -19
  107. data/gemfiles/4.2.gemfile +0 -20
  108. data/gemfiles/5.0.gemfile +0 -20
  109. data/gemfiles/5.1.gemfile +0 -20
  110. data/gemfiles/5.2.gemfile +0 -20
  111. data/gemfiles/6.0.gemfile +0 -20
  112. data/paperclip.gemspec +0 -50
  113. data/spec/database.yml +0 -4
  114. data/spec/paperclip/attachment_definitions_spec.rb +0 -13
  115. data/spec/paperclip/attachment_processing_spec.rb +0 -79
  116. data/spec/paperclip/attachment_registry_spec.rb +0 -158
  117. data/spec/paperclip/attachment_spec.rb +0 -1590
  118. data/spec/paperclip/content_type_detector_spec.rb +0 -47
  119. data/spec/paperclip/file_command_content_type_detector_spec.rb +0 -40
  120. data/spec/paperclip/filename_cleaner_spec.rb +0 -13
  121. data/spec/paperclip/geometry_detector_spec.rb +0 -38
  122. data/spec/paperclip/geometry_parser_spec.rb +0 -73
  123. data/spec/paperclip/geometry_spec.rb +0 -255
  124. data/spec/paperclip/glue_spec.rb +0 -42
  125. data/spec/paperclip/has_attached_file_spec.rb +0 -78
  126. data/spec/paperclip/integration_spec.rb +0 -702
  127. data/spec/paperclip/interpolations_spec.rb +0 -270
  128. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +0 -160
  129. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +0 -140
  130. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +0 -88
  131. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +0 -17
  132. data/spec/paperclip/io_adapters/file_adapter_spec.rb +0 -131
  133. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +0 -142
  134. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +0 -8
  135. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +0 -25
  136. data/spec/paperclip/io_adapters/registry_spec.rb +0 -35
  137. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +0 -64
  138. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +0 -146
  139. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +0 -231
  140. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +0 -19
  141. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +0 -108
  142. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +0 -69
  143. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +0 -88
  144. data/spec/paperclip/media_type_spoof_detector_spec.rb +0 -120
  145. data/spec/paperclip/meta_class_spec.rb +0 -30
  146. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +0 -88
  147. data/spec/paperclip/paperclip_spec.rb +0 -196
  148. data/spec/paperclip/plural_cache_spec.rb +0 -37
  149. data/spec/paperclip/processor_helpers_spec.rb +0 -57
  150. data/spec/paperclip/processor_spec.rb +0 -26
  151. data/spec/paperclip/rails_environment_spec.rb +0 -30
  152. data/spec/paperclip/rake_spec.rb +0 -103
  153. data/spec/paperclip/schema_spec.rb +0 -252
  154. data/spec/paperclip/storage/filesystem_spec.rb +0 -79
  155. data/spec/paperclip/storage/fog_spec.rb +0 -560
  156. data/spec/paperclip/storage/s3_live_spec.rb +0 -188
  157. data/spec/paperclip/storage/s3_spec.rb +0 -1746
  158. data/spec/paperclip/style_spec.rb +0 -251
  159. data/spec/paperclip/tempfile_factory_spec.rb +0 -33
  160. data/spec/paperclip/tempfile_spec.rb +0 -35
  161. data/spec/paperclip/thumbnail_spec.rb +0 -504
  162. data/spec/paperclip/url_generator_spec.rb +0 -231
  163. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +0 -410
  164. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +0 -249
  165. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +0 -85
  166. data/spec/paperclip/validators/attachment_size_validator_spec.rb +0 -325
  167. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +0 -48
  168. data/spec/paperclip/validators_spec.rb +0 -164
  169. data/spec/spec_helper.rb +0 -45
  170. data/spec/support/assertions.rb +0 -84
  171. data/spec/support/fake_model.rb +0 -24
  172. data/spec/support/fake_rails.rb +0 -12
  173. data/spec/support/fixtures/12k.png +0 -0
  174. data/spec/support/fixtures/50x50.png +0 -0
  175. data/spec/support/fixtures/5k.png +0 -0
  176. data/spec/support/fixtures/animated +0 -0
  177. data/spec/support/fixtures/animated.gif +0 -0
  178. data/spec/support/fixtures/animated.unknown +0 -0
  179. data/spec/support/fixtures/aws_s3.yml +0 -13
  180. data/spec/support/fixtures/bad.png +0 -1
  181. data/spec/support/fixtures/empty.html +0 -1
  182. data/spec/support/fixtures/empty.xlsx +0 -0
  183. data/spec/support/fixtures/fog.yml +0 -8
  184. data/spec/support/fixtures/rotated.jpg +0 -0
  185. data/spec/support/fixtures/s3.yml +0 -8
  186. data/spec/support/fixtures/spaced file.jpg +0 -0
  187. data/spec/support/fixtures/spaced file.png +0 -0
  188. data/spec/support/fixtures/text.txt +0 -1
  189. data/spec/support/fixtures/twopage.pdf +0 -0
  190. data/spec/support/fixtures/uppercase.PNG +0 -0
  191. data/spec/support/matchers/accept.rb +0 -5
  192. data/spec/support/matchers/exist.rb +0 -5
  193. data/spec/support/matchers/have_column.rb +0 -23
  194. data/spec/support/mock_attachment.rb +0 -24
  195. data/spec/support/mock_interpolator.rb +0 -24
  196. data/spec/support/mock_url_generator_builder.rb +0 -26
  197. data/spec/support/model_reconstruction.rb +0 -72
  198. data/spec/support/reporting.rb +0 -11
  199. data/spec/support/test_data.rb +0 -13
  200. data/spec/support/version_helper.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cff96583dd89dcd0254140d27f4b8043137acd917c804d7710367d719342119
4
- data.tar.gz: 27c6a63b58e72a52ec6ea87e82267d0a3ddb87815333295618d8d179c5c52d45
3
+ metadata.gz: 71b12469bab65eb2861d1170c154ecf1a08f6a0591806096f3d49f598f4ec115
4
+ data.tar.gz: 12efe7db20633834994b3b1836cc697ff21dbf1bd37851346d1bd5e0961aa045
5
5
  SHA512:
6
- metadata.gz: c37f46113c6c74e4e862b287174873f58d467adcfaee18766738c87eaa1757deac8363810883b3b0ae604d4cfa8b1223ec7edbe3af9687972c7ba53cc62578ab
7
- data.tar.gz: 8cc931814748df871550746bb8798cc06bc018285659f4ddf07632d24d72fa374f867b840a7aa776da957821755cbe869a130abd77ce75636b71a6f5a9df14ed
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.2** and Rails version **>= 4.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. To ensure
99
- that it does, on your command line, run `which convert` (one of the ImageMagick
100
- utilities). This will give you the path where that utility is installed. For
101
- example, it might return `/usr/local/bin/convert`.
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
- Then, in your environment config file, let Paperclip know to look there by adding that
104
- directory to its path.
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[:command_path] = "/usr/local/bin/"
107
+ Paperclip.options[:imagemagick_version] = "7"
110
108
  ```
111
109
 
112
- If you're on Mac OS X, you'll want to run the following with [Homebrew](http://www.brew.sh):
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
- > **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)**
139
-
140
- To test, you can use the image below:
141
- ![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png)
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
- OR
117
+ ### Optional: Unix `file` Command
155
118
 
156
- **Environment**
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
- 1. Open `config/environments/development.rb`
159
- 2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'`
160
- 3. Restart your Rails server
124
+ ```ruby
125
+ Paperclip.options[:file_command_path] = "/usr/local/bin/"
126
+ ```
161
127
 
162
- Either of these methods will give your Rails setup access to the `file.exe` functionality, thus providing the ability to check the contents of a file (fixing the spoofing problem)
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", "~> 6.3"
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` will attempt to match a file's extension to an
411
- inferred content_type, regardless of the actual contents of the file.
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 with the MIME type "text/plain".
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
- Paperclip is Copyright © 2008-2017 thoughtbot, inc. It is free software, and may be
1074
- redistributed under the terms specified in the MIT-LICENSE file.
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}]" if Rails.version.first.to_i > 4
36
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
35
37
  end
36
38
  end
data/lib/kt-paperclip.rb CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "paperclip"
@@ -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: :original,
15
- default_url: "/:attachment/:style/missing.png",
16
- escape_url: true,
17
- restricted_characters: /[&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/,
18
- filename_cleaner: nil,
19
- hash_data: ":class/:attachment/:id/:style/:updated_at",
20
- hash_digest: "SHA1",
21
- interpolator: Paperclip::Interpolations,
22
- only_process: [],
23
- path: ":rails_root/public:url",
24
- preserve_files: false,
25
- processors: [:thumbnail],
26
- source_file_options: {},
27
- storage: :filesystem,
28
- styles: {},
29
- url: "/system/:class/:attachment/:id_partition/:style/:filename",
30
- url_generator: Paperclip::UrlGenerator,
31
- use_default_time_zone: true,
32
- use_timestamp: true,
33
- whiny: Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails],
34
- validate_media_type: true,
35
- adapter_options: { hash_digest: Digest::MD5 },
36
- check_validity_before_processing: true
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
- instance_write(:file_name, nil)
567
- instance_write(:content_type, nil)
568
- instance_write(:file_size, nil)
569
- instance_write(:fingerprint, nil)
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "singleton"
2
4
 
3
5
  module Paperclip
@@ -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
- eval <<-end_callbacks
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
- def after_#{callback}(*args, &blk)
18
+
19
+ def self.after_#{callback}(*args, &blk)
17
20
  set_callback(:#{callback}, :after, *args, &blk)
18
21
  end
19
- end_callbacks
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