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
@@ -1,22 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
4
+ # The content-type detection strategy is as follows:
5
+ #
6
+ # 1. Blank/Empty files: If there's no filepath or the file is empty,
7
+ # provide a sensible default (application/octet-stream or inode/x-empty)
8
+ #
9
+ # 2. Calculated match: Return the first result that is found by both the
10
+ # Marcel gem (or `file` command) and MIME::Types.
11
+ #
12
+ # 3. Standard types: Return the first standard (without an x- prefix) entry
13
+ # in MIME::Types
14
+ #
15
+ # 4. Experimental types: If there were no standard types in MIME::Types
16
+ # list, try to return the first experimental one
17
+ #
18
+ # 5. Raw `file` command: Just use the output of Marcel (or `file` command),
19
+ # cached from step 2.
20
+ #
21
+ # 6. If nothing found, return a sensible default.
2
22
  class ContentTypeDetector
3
- # The content-type detection strategy is as follows:
4
- #
5
- # 1. Blank/Empty files: If there's no filepath or the file is empty,
6
- # provide a sensible default (application/octet-stream or inode/x-empty)
7
- #
8
- # 2. Calculated match: Return the first result that is found by both the
9
- # `file` command and MIME::Types.
10
- #
11
- # 3. Standard types: Return the first standard (without an x- prefix) entry
12
- # in MIME::Types
13
- #
14
- # 4. Experimental types: If there were no standard types in MIME::Types
15
- # list, try to return the first experimental one
16
- #
17
- # 5. Raw `file` command: Just use the output of the `file` command raw, or
18
- # a sensible default. This is cached from Step 2.
19
-
20
23
  EMPTY_TYPE = "inode/x-empty"
21
24
  SENSIBLE_DEFAULT = "application/octet-stream"
22
25
 
@@ -25,15 +28,15 @@ module Paperclip
25
28
  end
26
29
 
27
30
  # Returns a String describing the file's content type
28
- def detect
31
+ def detect(default = SENSIBLE_DEFAULT)
29
32
  if blank_name?
30
- SENSIBLE_DEFAULT
33
+ default
31
34
  elsif empty_file?
32
35
  EMPTY_TYPE
33
36
  elsif calculated_type_matches.any?
34
37
  calculated_type_matches.first
35
38
  else
36
- type_from_file_contents || SENSIBLE_DEFAULT
39
+ type_from_file_contents || default
37
40
  end.to_s
38
41
  end
39
42
 
@@ -60,21 +63,22 @@ module Paperclip
60
63
  end
61
64
 
62
65
  def type_from_file_contents
63
- type_from_mime_magic || type_from_file_command
66
+ return @type_from_file_contents if defined?(@type_from_file_contents)
67
+
68
+ @type_from_file_contents = type_from_marcel || type_from_file_command
64
69
  rescue Errno::ENOENT => e
65
70
  Paperclip.log("Error while determining content type: #{e}")
66
- SENSIBLE_DEFAULT
71
+ @type_from_file_contents = nil
67
72
  end
68
73
 
69
- def type_from_mime_magic
70
- @type_from_mime_magic ||= File.open(@filepath) do |file|
71
- MimeMagic.by_magic(file).try(:type)
72
- end
74
+ def type_from_marcel
75
+ type = Marcel::MimeType.for(Pathname.new(@filepath), name: @filepath)
76
+ # Marcel::MineType returns 'application/octet-stream' if it can't find a valid type.
77
+ type == SENSIBLE_DEFAULT ? nil : type
73
78
  end
74
79
 
75
80
  def type_from_file_command
76
- @type_from_file_command ||=
77
- FileCommandContentTypeDetector.new(@filepath).detect
81
+ Commands::UnixFile.detect_content_type(@filepath)
78
82
  end
79
83
  end
80
84
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  # A base error class for Paperclip. Most of the error that will be thrown
3
5
  # from Paperclip will inherits from this class.
@@ -1,28 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
4
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::ContentTypeDetector+ instead.
2
5
  class FileCommandContentTypeDetector
6
+ # @deprecated Will be removed in Paperclip 8.0.
3
7
  SENSIBLE_DEFAULT = "application/octet-stream"
4
8
 
9
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::ContentTypeDetector+ instead.
5
10
  def initialize(filename)
11
+ warn_deprecation
6
12
  @filename = filename
7
13
  end
8
14
 
15
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::ContentTypeDetector+ instead.
9
16
  def detect
10
- type_from_file_command
17
+ warn_deprecation
18
+ Paperclip::Commands::UnixFile.detect_content_type(@filename) || SENSIBLE_DEFAULT
11
19
  end
12
20
 
13
21
  private
14
22
 
15
- def type_from_file_command
16
- # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
17
- type = begin
18
- Paperclip.run("file", "-b --mime :file", file: @filename)
19
- rescue Terrapin::CommandLineError => e
20
- Paperclip.log("Error while determining content type: #{e}")
21
- SENSIBLE_DEFAULT
22
- end
23
-
24
- type = SENSIBLE_DEFAULT if type.nil? || type.match(/\(.*?\)/)
25
- type.split(/[:;\s]+/)[0]
23
+ def warn_deprecation
24
+ Paperclip.deprecator.warn("Paperclip::FileCommandContentTypeDetector has been replaced by Paperclip::ContentTypeDetector.")
26
25
  end
27
26
  end
28
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class FilenameCleaner
3
5
  def initialize(invalid_character_regex)
@@ -1,35 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  # Defines the geometry of an image.
3
5
  class Geometry
4
- attr_accessor :height, :width, :modifier
6
+ attr_accessor :height, :width, :modifier, :orientation
5
7
 
6
8
  EXIF_ROTATED_ORIENTATION_VALUES = [5, 6, 7, 8].freeze
7
9
 
8
10
  # Gives a Geometry representing the given height and width
9
- def initialize(width = nil, height = nil, modifier = nil)
11
+ def initialize(width = nil, height = nil, modifier = nil, orientation = nil)
10
12
  if width.is_a?(Hash)
11
13
  options = width
12
14
  @height = options[:height].to_f
13
15
  @width = options[:width].to_f
14
- @modifier = options[:modifier]
16
+ @modifier = options[:modifier].presence
15
17
  @orientation = options[:orientation].to_i
16
18
  else
17
19
  @height = height.to_f
18
20
  @width = width.to_f
19
- @modifier = modifier
21
+ @modifier = modifier.presence
22
+ @orientation = orientation.to_i
20
23
  end
21
24
  end
22
25
 
23
26
  # Extracts the Geometry from a file (or path to a file)
27
+ #
28
+ # @deprecated Will be removed in Paperclip 8.0.
24
29
  def self.from_file(file)
25
- GeometryDetector.new(file).make
30
+ Commands::ImageMagick::GeometryParser.from_file(file)
26
31
  end
27
32
 
28
33
  # Extracts the Geometry from a "WxH,O" string
29
34
  # Where W is the width, H is the height,
30
35
  # and O is the EXIF orientation
36
+ #
37
+ # @deprecated Will be removed in Paperclip 8.0.
31
38
  def self.parse(string)
32
- GeometryParser.new(string).make
39
+ Commands::ImageMagick::GeometryParser.parse(string)
33
40
  end
34
41
 
35
42
  # Swaps the height and width if necessary
@@ -72,13 +79,21 @@ module Paperclip
72
79
 
73
80
  # Returns the width and height in a format suitable to be passed to Geometry.parse
74
81
  def to_s
75
- s = ""
82
+ s = +""
76
83
  s << width.to_i.to_s if width > 0
77
84
  s << "x#{height.to_i}" if height > 0
78
85
  s << modifier.to_s
79
86
  s
80
87
  end
81
88
 
89
+ def ==(other)
90
+ other.is_a?(Geometry) &&
91
+ width == other.width &&
92
+ height == other.height &&
93
+ modifier == other.modifier &&
94
+ orientation == other.orientation
95
+ end
96
+
82
97
  # Same as to_s
83
98
  def inspect
84
99
  to_s
@@ -1,45 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
4
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
2
5
  class GeometryDetector
6
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
3
7
  def initialize(file)
8
+ warn_deprecation
4
9
  @file = file
5
- raise_if_blank_file
10
+ raise Errors::NotIdentifiedByImageMagickError.new("Cannot find the geometry of a file with a blank name") if @file.blank?
6
11
  end
7
12
 
13
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
8
14
  def make
9
- geometry = GeometryParser.new(geometry_string.strip).make
10
- geometry || raise(Errors::NotIdentifiedByImageMagickError.new)
15
+ warn_deprecation
16
+ Paperclip::Commands::ImageMagick::GeometryParser.from_file(@file)
11
17
  end
12
18
 
13
19
  private
14
20
 
15
- def geometry_string
16
- orientation = Paperclip.options[:use_exif_orientation] ?
17
- "%[exif:orientation]" : "1"
18
- Paperclip.run(
19
- Paperclip.options[:is_windows] ? "magick identify" : "identify",
20
- "-format '%wx%h,#{orientation}' :file", {
21
- file: "#{path}[0]"
22
- },
23
- swallow_stderr: true
24
- )
25
- rescue Terrapin::ExitStatusError
26
- ""
27
- rescue Terrapin::CommandNotFoundError => e
28
- raise_because_imagemagick_missing
29
- end
30
-
31
- def path
32
- @file.respond_to?(:path) ? @file.path : @file
33
- end
34
-
35
- def raise_if_blank_file
36
- if path.blank?
37
- raise Errors::NotIdentifiedByImageMagickError.new("Cannot find the geometry of a file with a blank name")
38
- end
39
- end
40
-
41
- def raise_because_imagemagick_missing
42
- raise Errors::CommandNotFoundError.new("Could not run the `identify` command. Please install ImageMagick.")
21
+ def warn_deprecation
22
+ Paperclip.deprecator.warn("Paperclip::GeometryDetector has been replaced by Paperclip::Commands::ImageMagick::GeometryParser")
43
23
  end
44
24
  end
45
25
  end
@@ -1,31 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
4
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
2
5
  class GeometryParser
3
- FORMAT = /\b(\d*)x?(\d*)\b(?:,(\d?))?(\@\>|\>\@|[\>\<\#\@\%^!])?/i.freeze
6
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser::FORMAT+ instead.
7
+ FORMAT = Paperclip::Commands::ImageMagick::GeometryParser::FORMAT
8
+
9
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
4
10
  def initialize(string)
11
+ warn_deprecation
5
12
  @string = string
6
13
  end
7
14
 
15
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::ImageMagick::GeometryParser+ instead.
8
16
  def make
9
- if match
10
- Geometry.new(
11
- height: @height,
12
- width: @width,
13
- modifier: @modifier,
14
- orientation: @orientation
15
- )
16
- end
17
+ warn_deprecation
18
+ Paperclip::Commands::ImageMagick::GeometryParser.parse(@string)
17
19
  end
18
20
 
19
21
  private
20
22
 
21
- def match
22
- if actual_match = @string && @string.match(FORMAT)
23
- @width = actual_match[1]
24
- @height = actual_match[2]
25
- @orientation = actual_match[3]
26
- @modifier = actual_match[4]
27
- end
28
- actual_match
23
+ def warn_deprecation
24
+ Paperclip.deprecator.warn("Paperclip::GeometryParser has been replaced by Paperclip::Commands::ImageMagick::GeometryParser")
29
25
  end
30
26
  end
31
27
  end
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "paperclip/callbacks"
2
4
  require "paperclip/validators"
3
5
  require "paperclip/schema"
4
6
 
5
7
  module Paperclip
6
8
  module Glue
9
+ LOCALE_PATHS = Dir.glob("#{File.dirname(__FILE__)}/locales/*.{rb,yml}")
10
+
7
11
  def self.included(base)
8
12
  base.extend ClassMethods
9
13
  base.send :include, Callbacks
10
14
  base.send :include, Validators
11
15
  base.send :include, Schema if defined? ActiveRecord::Base
12
16
 
13
- locale_path = Dir.glob(File.dirname(__FILE__) + "/locales/*.{rb,yml}")
14
- I18n.load_path += locale_path unless I18n.load_path.include?(locale_path)
17
+ I18n.load_path += LOCALE_PATHS unless (LOCALE_PATHS - I18n.load_path).empty?
15
18
  end
16
19
  end
17
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class HasAttachedFile
3
5
  def self.define_on(klass, name, options)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Helpers
3
5
  def configure
@@ -8,31 +10,9 @@ module Paperclip
8
10
  Paperclip::Interpolations[key] = block
9
11
  end
10
12
 
11
- # The run method takes the name of a binary to run, the arguments
12
- # to that binary, the values to interpolate and some local options.
13
- #
14
- # :cmd -> The name of a binary to run.
15
- #
16
- # :arguments -> The command line arguments to that binary.
17
- #
18
- # :interpolation_values -> Values to be interpolated into the arguments.
19
- #
20
- # :local_options -> The options to be used by Cocain::CommandLine.
21
- # These could be: runner
22
- # logger
23
- # swallow_stderr
24
- # expected_outcodes
25
- # environment
26
- # runner_options
27
- #
28
- def run(cmd, arguments = "", interpolation_values = {}, local_options = {})
29
- command_path = options[:command_path]
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
- if logging? && (options[:log_command] || local_options[:log_command])
33
- local_options = local_options.merge(logger: logger)
34
- end
35
- Terrapin::CommandLine.new(cmd, arguments, local_options).run(interpolation_values)
13
+ # @deprecated Will be removed in Paperclip 8.0. Use +Paperclip::Commands::Runner.run+ instead.
14
+ def run(command, arguments = nil, interpolation_values = {}, local_options = {})
15
+ Commands::Runner.run(command, nil, arguments, interpolation_values, local_options)
36
16
  end
37
17
 
38
18
  # Find all instances of the given Active Record model +klass+ with attachment +name+.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Interpolations
3
5
  class PluralCache
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  # This module contains all the methods that are available for interpolation
3
5
  # in paths and urls. To add your own (or override an existing one), you
@@ -54,10 +56,14 @@ module Paperclip
54
56
  # Returns the interpolated URL. Will raise an error if the url itself
55
57
  # contains ":url" to prevent infinite recursion. This interpolation
56
58
  # is used in the default :path to ease default specifications.
57
- RIGHT_HERE = "#{__FILE__.gsub(%r{\A\./}, '')}:#{__LINE__ + 3}"
58
59
  def url(attachment, style_name)
59
- raise Errors::InfiniteInterpolationError if caller.any? { |b| b.index(RIGHT_HERE) }
60
+ if Thread.current.thread_variable_get(:kt_paperclip_no_recursion)
61
+ raise Errors::InfiniteInterpolationError
62
+ end
63
+ Thread.current.thread_variable_set(:kt_paperclip_no_recursion, true)
60
64
  attachment.url(style_name, timestamp: false, escape: false)
65
+ ensure
66
+ Thread.current.thread_variable_set(:kt_paperclip_no_recursion, false)
61
67
  end
62
68
 
63
69
  # Returns the timestamp as defined by the <attachment>_updated_at field
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
 
3
5
  module Paperclip
@@ -17,7 +19,7 @@ module Paperclip
17
19
  @fingerprint ||= begin
18
20
  digest = @options.fetch(:hash_digest).new
19
21
  File.open(path, "rb") do |f|
20
- buf = ""
22
+ buf = String.new
21
23
  digest.update(buf) while f.read(16384, buf)
22
24
  end
23
25
  digest.hexdigest
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class AttachmentAdapter < AbstractAdapter
3
5
  def self.register
@@ -33,6 +35,15 @@ module Paperclip
33
35
  else
34
36
  begin
35
37
  source.copy_to_local_file(@style, destination.path)
38
+
39
+ # Some sources (like S3) writes to a temporary file first for multi-part downloads then moves
40
+ # it to the final destination path. This means our destination Tempfile reference is stale
41
+ # and reads will return an empty string. For compatibility, we need to copy the contents
42
+ # of the destination file to our current Tempfile instance.
43
+ if destination.size.zero?
44
+ IO.copy_stream(destination.path, destination)
45
+ destination.rewind
46
+ end
36
47
  rescue Errno::EACCES
37
48
  # clean up lingering tempfile if we cannot access source file
38
49
  destination.close(true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class DataUriAdapter < StringioAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class EmptyStringAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class FileAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class HttpUrlProxyAdapter < UriAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class IdentityAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class NilAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class AdapterRegistry
3
5
  class NoHandlerError < Paperclip::Error; end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class StringioAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  class UploadedFileAdapter < AbstractAdapter
3
5
  def self.register
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "open-uri"
2
4
 
3
5
  module Paperclip
@@ -50,20 +52,10 @@ module Paperclip
50
52
  "index.html"
51
53
  end
52
54
 
53
- if RUBY_VERSION < '2.5'
54
- def download_content
55
- options = { read_timeout: Paperclip.options[:read_timeout] }.compact
56
-
57
- # rubocop:disable Security/Open
58
- open(@target, options)
59
- # rubocop:enable Security/Open
60
- end
61
- else
62
- def download_content
63
- options = { read_timeout: Paperclip.options[:read_timeout] }.compact
55
+ def download_content
56
+ options = { read_timeout: Paperclip.options[:read_timeout] }.compact
64
57
 
65
- URI.open(@target, options)
66
- end
58
+ URI.open(@target, options)
67
59
  end
68
60
 
69
61
  def copy_to_tempfile(src)
@@ -0,0 +1,18 @@
1
+ fr:
2
+ errors:
3
+ messages:
4
+ in_between: "doit être entre %{min} et %{max}"
5
+ spoofed_media_type: "à du contenu qui ne correspond pas au type déclaré"
6
+
7
+ number:
8
+ human:
9
+ storage_units:
10
+ format: "%n %u"
11
+ units:
12
+ byte:
13
+ one: "Octet"
14
+ other: "Octets"
15
+ kb: "ko"
16
+ mb: "Mo"
17
+ gb: "Go"
18
+ tb: "To"
@@ -0,0 +1,20 @@
1
+ gd:
2
+ errors:
3
+ messages:
4
+ in_between: "– feumaidh seo a bhith eadar %{min} ’s %{max}"
5
+ spoofed_media_type: "– tha susbaint ann nach eil a-rèir na chaidh aithris"
6
+
7
+ number:
8
+ human:
9
+ storage_units:
10
+ format: "%n %u"
11
+ units:
12
+ byte:
13
+ one: "bhaidht"
14
+ two: "bhaidht"
15
+ few: "baidhtean"
16
+ other: "baidht"
17
+ kb: "KB"
18
+ mb: "MB"
19
+ gb: "GB"
20
+ tb: "TB"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Logger
3
5
  # Log a paperclip-specific line. This will log to STDOUT
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Shoulda
3
5
  module Matchers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Shoulda
3
5
  module Matchers
@@ -39,7 +41,7 @@ module Paperclip
39
41
  end
40
42
 
41
43
  def failure_message
42
- "#{expected_attachment}\n".tap do |message|
44
+ (+"#{expected_attachment}\n").tap do |message|
43
45
  message << accepted_types_and_failures.to_s
44
46
  message << "\n\n" if @allowed_types.present? && @rejected_types.present?
45
47
  message << rejected_types_and_failures.to_s
@@ -54,7 +56,7 @@ module Paperclip
54
56
 
55
57
  def accepted_types_and_failures
56
58
  if @allowed_types.present?
57
- "Accept content types: #{@allowed_types.join(', ')}\n".tap do |message|
59
+ (+"Accept content types: #{@allowed_types.join(', ')}\n").tap do |message|
58
60
  message << if @missing_allowed_types.present?
59
61
  " #{@missing_allowed_types.join(', ')} were rejected."
60
62
  else
@@ -66,7 +68,7 @@ module Paperclip
66
68
 
67
69
  def rejected_types_and_failures
68
70
  if @rejected_types.present?
69
- "Reject content types: #{@rejected_types.join(', ')}\n".tap do |message|
71
+ (+"Reject content types: #{@rejected_types.join(', ')}\n").tap do |message|
70
72
  message << if @missing_rejected_types.present?
71
73
  " #{@missing_rejected_types.join(', ')} were accepted."
72
74
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Shoulda
3
5
  module Matchers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Paperclip
2
4
  module Shoulda
3
5
  module Matchers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "paperclip/matchers/have_attached_file_matcher"
2
4
  require "paperclip/matchers/validate_attachment_presence_matcher"
3
5
  require "paperclip/matchers/validate_attachment_content_type_matcher"