shrine 2.14.0 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of shrine might be problematic. Click here for more details.

Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +384 -374
  3. data/README.md +132 -63
  4. data/doc/advantages.md +191 -109
  5. data/doc/attacher.md +1 -1
  6. data/doc/carrierwave.md +4 -4
  7. data/doc/creating_storages.md +2 -2
  8. data/doc/design.md +2 -2
  9. data/doc/direct_s3.md +3 -3
  10. data/doc/metadata.md +1 -1
  11. data/doc/multiple_files.md +2 -2
  12. data/doc/paperclip.md +3 -3
  13. data/doc/plugins/activerecord.md +92 -0
  14. data/doc/plugins/add_metadata.md +93 -0
  15. data/doc/plugins/backgrounding.md +148 -0
  16. data/doc/plugins/backup.md +29 -0
  17. data/doc/plugins/cached_attachment_data.md +23 -0
  18. data/doc/plugins/copy.md +22 -0
  19. data/doc/plugins/data_uri.md +92 -0
  20. data/doc/plugins/default_storage.md +16 -0
  21. data/doc/plugins/default_url.md +33 -0
  22. data/doc/plugins/default_url_options.md +22 -0
  23. data/doc/plugins/delete_promoted.md +10 -0
  24. data/doc/plugins/delete_raw.md +16 -0
  25. data/doc/plugins/derivation_endpoint.md +747 -0
  26. data/doc/plugins/determine_mime_type.md +64 -0
  27. data/doc/plugins/direct_upload.md +170 -0
  28. data/doc/plugins/download_endpoint.md +83 -0
  29. data/doc/plugins/dynamic_storage.md +20 -0
  30. data/doc/plugins/hooks.md +56 -0
  31. data/doc/plugins/included.md +15 -0
  32. data/doc/plugins/infer_extension.md +57 -0
  33. data/doc/plugins/keep_files.md +20 -0
  34. data/doc/plugins/logging.md +39 -0
  35. data/doc/plugins/metadata_attribues.md +43 -0
  36. data/doc/plugins/migration_helpers.md +58 -0
  37. data/doc/plugins/module_include.md +40 -0
  38. data/doc/plugins/moving.md +17 -0
  39. data/doc/plugins/multi_delete.md +18 -0
  40. data/doc/plugins/parallelize.md +14 -0
  41. data/doc/plugins/parsed_json.md +9 -0
  42. data/doc/plugins/presign_endpoint.md +133 -0
  43. data/doc/plugins/pretty_location.md +29 -0
  44. data/doc/plugins/processing.md +68 -0
  45. data/doc/plugins/rack_file.md +49 -0
  46. data/doc/plugins/rack_response.md +96 -0
  47. data/doc/plugins/recache.md +27 -0
  48. data/doc/plugins/refresh_metadata.md +31 -0
  49. data/doc/plugins/remote_url.md +104 -0
  50. data/doc/plugins/remove_attachment.md +16 -0
  51. data/doc/plugins/remove_invalid.md +9 -0
  52. data/doc/plugins/restore_cached_data.md +14 -0
  53. data/doc/plugins/sequel.md +64 -0
  54. data/doc/plugins/signature.md +49 -0
  55. data/doc/plugins/store_dimensions.md +68 -0
  56. data/doc/plugins/tempfile.md +40 -0
  57. data/doc/plugins/upload_endpoint.md +123 -0
  58. data/doc/plugins/upload_options.md +28 -0
  59. data/doc/plugins/validation_helpers.md +129 -0
  60. data/doc/plugins/versions.md +179 -0
  61. data/doc/processing.md +217 -247
  62. data/doc/refile.md +3 -3
  63. data/doc/release_notes/1.0.0.md +143 -0
  64. data/doc/release_notes/1.1.0.md +184 -0
  65. data/doc/release_notes/1.2.0.md +37 -0
  66. data/doc/release_notes/1.3.0.md +90 -0
  67. data/doc/release_notes/1.4.0.md +167 -0
  68. data/doc/release_notes/1.4.1.md +9 -0
  69. data/doc/release_notes/1.4.2.md +20 -0
  70. data/doc/release_notes/2.0.0.md +173 -0
  71. data/doc/release_notes/2.0.1.md +12 -0
  72. data/doc/release_notes/2.1.0.md +59 -0
  73. data/doc/release_notes/2.1.1.md +8 -0
  74. data/doc/release_notes/2.10.0.md +52 -0
  75. data/doc/release_notes/2.10.1.md +6 -0
  76. data/doc/release_notes/2.11.0.md +69 -0
  77. data/doc/release_notes/2.12.0.md +65 -0
  78. data/doc/release_notes/2.13.0.md +146 -0
  79. data/doc/release_notes/2.14.0.md +278 -0
  80. data/doc/release_notes/2.15.0.md +82 -0
  81. data/doc/release_notes/2.2.0.md +98 -0
  82. data/doc/release_notes/2.3.0.md +50 -0
  83. data/doc/release_notes/2.3.1.md +10 -0
  84. data/doc/release_notes/2.4.0.md +87 -0
  85. data/doc/release_notes/2.4.1.md +29 -0
  86. data/doc/release_notes/2.5.0.md +130 -0
  87. data/doc/release_notes/2.6.0.md +254 -0
  88. data/doc/release_notes/2.6.1.md +14 -0
  89. data/doc/release_notes/2.7.0.md +180 -0
  90. data/doc/release_notes/2.8.0.md +95 -0
  91. data/doc/release_notes/2.9.0.md +82 -0
  92. data/doc/retrieving_uploads.md +1 -1
  93. data/doc/storage/file_system.md +96 -0
  94. data/doc/storage/s3.md +293 -0
  95. data/doc/validation.md +1 -1
  96. data/lib/shrine/plugins/_urlsafe_serialization.rb +33 -125
  97. data/lib/shrine/plugins/activerecord.rb +0 -78
  98. data/lib/shrine/plugins/add_metadata.rb +0 -80
  99. data/lib/shrine/plugins/backgrounding.rb +0 -134
  100. data/lib/shrine/plugins/backup.rb +0 -22
  101. data/lib/shrine/plugins/cached_attachment_data.rb +0 -15
  102. data/lib/shrine/plugins/copy.rb +0 -14
  103. data/lib/shrine/plugins/data_uri.rb +0 -73
  104. data/lib/shrine/plugins/default_storage.rb +0 -11
  105. data/lib/shrine/plugins/default_url.rb +0 -25
  106. data/lib/shrine/plugins/default_url_options.rb +0 -16
  107. data/lib/shrine/plugins/delete_promoted.rb +0 -6
  108. data/lib/shrine/plugins/delete_raw.rb +0 -10
  109. data/lib/shrine/plugins/derivation_endpoint.rb +652 -0
  110. data/lib/shrine/plugins/determine_mime_type.rb +1 -85
  111. data/lib/shrine/plugins/direct_upload.rb +0 -155
  112. data/lib/shrine/plugins/download_endpoint.rb +11 -73
  113. data/lib/shrine/plugins/dynamic_storage.rb +0 -17
  114. data/lib/shrine/plugins/hooks.rb +0 -48
  115. data/lib/shrine/plugins/included.rb +0 -12
  116. data/lib/shrine/plugins/infer_extension.rb +0 -49
  117. data/lib/shrine/plugins/keep_files.rb +0 -19
  118. data/lib/shrine/plugins/logging.rb +0 -39
  119. data/lib/shrine/plugins/metadata_attributes.rb +0 -35
  120. data/lib/shrine/plugins/migration_helpers.rb +0 -50
  121. data/lib/shrine/plugins/module_include.rb +0 -32
  122. data/lib/shrine/plugins/moving.rb +0 -12
  123. data/lib/shrine/plugins/multi_delete.rb +0 -13
  124. data/lib/shrine/plugins/parallelize.rb +0 -8
  125. data/lib/shrine/plugins/parsed_json.rb +0 -5
  126. data/lib/shrine/plugins/presign_endpoint.rb +2 -117
  127. data/lib/shrine/plugins/pretty_location.rb +0 -22
  128. data/lib/shrine/plugins/processing.rb +0 -55
  129. data/lib/shrine/plugins/rack_file.rb +0 -39
  130. data/lib/shrine/plugins/rack_response.rb +0 -81
  131. data/lib/shrine/plugins/recache.rb +0 -21
  132. data/lib/shrine/plugins/refresh_metadata.rb +0 -24
  133. data/lib/shrine/plugins/remote_url.rb +0 -85
  134. data/lib/shrine/plugins/remove_attachment.rb +0 -10
  135. data/lib/shrine/plugins/remove_invalid.rb +0 -6
  136. data/lib/shrine/plugins/restore_cached_data.rb +0 -10
  137. data/lib/shrine/plugins/sequel.rb +0 -54
  138. data/lib/shrine/plugins/signature.rb +0 -37
  139. data/lib/shrine/plugins/store_dimensions.rb +0 -63
  140. data/lib/shrine/plugins/tempfile.rb +4 -35
  141. data/lib/shrine/plugins/upload_endpoint.rb +2 -109
  142. data/lib/shrine/plugins/upload_options.rb +0 -20
  143. data/lib/shrine/plugins/validation_helpers.rb +0 -36
  144. data/lib/shrine/plugins/versions.rb +0 -156
  145. data/lib/shrine/storage/file_system.rb +0 -77
  146. data/lib/shrine/storage/s3.rb +0 -249
  147. data/lib/shrine/version.rb +1 -1
  148. data/shrine.gemspec +2 -2
  149. metadata +86 -6
@@ -2,43 +2,6 @@
2
2
 
3
3
  class Shrine
4
4
  module Plugins
5
- # The `signature` plugin provides the ability to calculate a hash from file
6
- # content. This hash can be used as a checksum or just as a unique
7
- # signature for the uploaded file.
8
- #
9
- # Shrine.plugin :signature
10
- #
11
- # The plugin adds a `#calculate_signature` instance and class method to the
12
- # uploader. The method accepts an IO object and a hashing algorithm, and
13
- # returns the calculated hash.
14
- #
15
- # Shrine.calculate_signature(io, :md5)
16
- # #=> "9a0364b9e99bb480dd25e1f0284c8555"
17
- #
18
- # You can then use the `add_metadata` plugin to add a new metadata field
19
- # with the calculated hash.
20
- #
21
- # plugin :add_metadata
22
- #
23
- # add_metadata :md5 do |io, context|
24
- # calculate_signature(io, :md5)
25
- # end
26
- #
27
- # This will generate a hash for each uploaded file, but if you want to
28
- # generate one only for the original file, you can add a conditional:
29
- #
30
- # add_metadata :md5 do |io, context|
31
- # calculate_signature(io, :md5) if context[:action] == :cache
32
- # end
33
- #
34
- # The following hashing algorithms are supported: SHA1, SHA256, SHA384,
35
- # SHA512, MD5, and CRC32.
36
- #
37
- # You can also choose which format will the calculated hash be encoded in:
38
- #
39
- # Shrine.calculate_signature(io, :sha256, format: :base64)
40
- #
41
- # The supported encoding formats are `hex` (default), `base64`, and `none`.
42
5
  module Signature
43
6
  module ClassMethods
44
7
  # Calculates `algorithm` hash of the contents of the IO object, and
@@ -2,69 +2,6 @@
2
2
 
3
3
  class Shrine
4
4
  module Plugins
5
- # The `store_dimensions` plugin extracts dimensions of uploaded images and
6
- # stores them into the metadata hash (by default it uses the [fastimage]
7
- # gem).
8
- #
9
- # plugin :store_dimensions
10
- #
11
- # The dimensions are stored as "width" and "height" metadata values on the
12
- # Shrine::UploadedFile object. For convenience the plugin also adds
13
- # `#width`, `#height` and `#dimensions` reader methods.
14
- #
15
- # image = uploader.upload(file)
16
- #
17
- # image.metadata["width"] #=> 300
18
- # image.metadata["height"] #=> 500
19
- # # or
20
- # image.width #=> 300
21
- # image.height #=> 500
22
- # # or
23
- # image.dimensions #=> [300, 500]
24
- #
25
- # By default the [fastimage] gem is used to extract dimensions. You can
26
- # choose a different built-in analyzer via the `:analyzer` option:
27
- #
28
- # plugin :store_dimensions, analyzer: :mini_magick
29
- #
30
- # The following analyzers are supported:
31
- #
32
- # :fastimage
33
- # : (Default). Uses the [fastimage] gem to extract dimensions from any IO
34
- # object.
35
- #
36
- # :mini_magick
37
- # : Uses the [mini_magick] gem to extract dimensions from File objects. If
38
- # non-file IO object is given it will be temporarily downloaded to disk.
39
- #
40
- # :ruby_vips
41
- # : Uses the [ruby-vips] gem to extract dimensions from File objects. If
42
- # non-file IO object is given it will be temporarily downloaded to disk.
43
- #
44
- # You can also create your own custom dimensions analyzer, where you can
45
- # reuse any of the built-in analyzers. The analyzer is a lambda that
46
- # accepts an IO object and returns width and height as a two-element array,
47
- # or `nil` if dimensions could not be extracted.
48
- #
49
- # plugin :store_dimensions, analyzer: -> (io, analyzers) do
50
- # dimensions = analyzers[:fastimage].call(io) # try extracting dimensions with FastImage
51
- # dimensions ||= analyzers[:mini_magick].call(io) # otherwise fall back to MiniMagick
52
- # dimensions
53
- # end
54
- #
55
- # You can use methods for extracting the dimensions directly:
56
- #
57
- # # or YourUploader.extract_dimensions(io)
58
- # Shrine.extract_dimensions(io) # calls the defined analyzer
59
- # #=> [300, 400]
60
- #
61
- # # or YourUploader.dimensions_analyzers
62
- # Shrine.dimensions_analyzers[:fastimage].call(io) # calls a built-in analyzer
63
- # #=> [300, 400]
64
- #
65
- # [fastimage]: https://github.com/sdsykes/fastimage
66
- # [mini_magick]: https://github.com/minimagick/minimagick
67
- # [ruby-vips]: https://github.com/libvips/ruby-vips
68
5
  module StoreDimensions
69
6
  def self.configure(uploader, opts = {})
70
7
  uploader.opts[:dimensions_analyzer] = opts.fetch(:analyzer, uploader.opts.fetch(:dimensions_analyzer, :fastimage))
@@ -1,44 +1,13 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The `tempfile` plugin makes it easier to reuse a single copy of an
4
- # uploaded file on disk.
5
- #
6
- # Shrine.plugin :tempfile
7
- #
8
- # The plugin provides the `UploadedFile#tempfile` method, which when called
9
- # on an open uploaded file will return a copy of its content on disk. The
10
- # first time the method is called the file content will cached into a
11
- # temporary file and returned. On any subsequent method calls the cached
12
- # temporary file will be returned directly. The temporary file is deleted
13
- # when the uploaded file is closed.
14
- #
15
- # uploaded_file.open do
16
- # # ...
17
- # uploaded_file.tempfile #=> #<Tempfile:...> (file is cached)
18
- # # ...
19
- # uploaded_file.tempfile #=> #<Tempfile:...> (cache is returned)
20
- # # ...
21
- # end # tempfile is deleted
22
- #
23
- # # OR
24
- #
25
- # uploaded_file.open
26
- # # ...
27
- # uploaded_file.tempfile #=> #<Tempfile:...> (file is cached)
28
- # # ...
29
- # uploaded_file.tempfile #=> #<Tempfile:...> (cache is returned)
30
- # # ...
31
- # uploaded_file.close # tempfile is deleted
32
- #
33
- # This plugin also modifies `Shrine.with_file` to call
34
- # `UploadedFile#tempfile` when the given IO object is an open
35
- # `UploadedFile`. Since `Shrine.with_file` is typically called on the
36
- # `Shrine` class directly, it's recommended to load this plugin globally.
37
3
  module Tempfile
38
4
  module ClassMethods
39
5
  def with_file(io)
40
6
  if io.is_a?(UploadedFile) && io.opened?
41
- yield io.tempfile
7
+ # open a new file descriptor for thread safety
8
+ File.open(io.tempfile.path, binmode: true) do |file|
9
+ yield file
10
+ end
42
11
  else
43
12
  super
44
13
  end
@@ -7,113 +7,6 @@ require "digest"
7
7
 
8
8
  class Shrine
9
9
  module Plugins
10
- # The `upload_endpoint` plugin provides a Rack endpoint which accepts file
11
- # uploads and forwards them to specified storage. On the client side it's
12
- # recommended to use [Uppy] for asynchronous uploads.
13
- #
14
- # plugin :upload_endpoint
15
- #
16
- # The plugin adds a `Shrine.upload_endpoint` method which, given a storage
17
- # identifier, returns a Rack application that accepts multipart POST
18
- # requests, and uploads received files to the specified storage. You can
19
- # run this Rack application inside your app:
20
- #
21
- # # config.ru (Rack)
22
- # map "/images/upload" do
23
- # run ImageUploader.upload_endpoint(:cache)
24
- # end
25
- #
26
- # # OR
27
- #
28
- # # config/routes.rb (Rails)
29
- # Rails.application.routes.draw do
30
- # mount ImageUploader.upload_endpoint(:cache) => "/images/upload"
31
- # end
32
- #
33
- # Asynchronous upload is typically meant to replace the caching phase in
34
- # the default synchronous workflow, so we want the uploads to go to
35
- # temporary (`:cache`) storage.
36
- #
37
- # The above will create a `POST /images/upload` endpoint, which uploads the
38
- # file received in the `file` param using `ImageUploader`, and returns a
39
- # JSON representation of the uploaded file.
40
- #
41
- # # POST /images/upload
42
- # {
43
- # "id": "43kewit94.jpg",
44
- # "storage": "cache",
45
- # "metadata": {
46
- # "size": 384393,
47
- # "filename": "nature.jpg",
48
- # "mime_type": "image/jpeg"
49
- # }
50
- # }
51
- #
52
- # This JSON string can now be assigned to an attachment attribute instead
53
- # of a raw file. In a form it can be written to a hidden attachment field,
54
- # and then it can be assigned as the attachment.
55
- #
56
- # ## Limiting filesize
57
- #
58
- # It's good practice to limit the accepted filesize of uploaded files. You
59
- # can do that with the `:max_size` option:
60
- #
61
- # plugin :upload_endpoint, max_size: 20*1024*1024 # 20 MB
62
- #
63
- # If the uploaded file is larger than the specified value, a `413 Payload
64
- # Too Large` response will be returned.
65
- #
66
- # ## Checksum
67
- #
68
- # If you want the upload endpoint to verify the integrity of the uploaded
69
- # file, you can include the `Content-MD5` header in the request filled with
70
- # the base64-encoded MD5 hash of the file that was calculated prior to the
71
- # upload, and the endpoint will automatically use it to verify the uploaded
72
- # data.
73
- #
74
- # If the checksums don't match, a `460 Checksum Mismatch` response is
75
- # returned.
76
- #
77
- # ## Context
78
- #
79
- # The upload context will *not* contain `:record` and `:name` values, as
80
- # the upload happens independently of a database record. The endpoint will
81
- # send the following upload context:
82
- #
83
- # * `:action` - holds the value `:upload`
84
- # * `:request` - holds an instance of `Rack::Request`
85
- #
86
- # You can update the upload context via `:upload_context`:
87
- #
88
- # plugin :upload_endpoint, upload_context: -> (request) do
89
- # { location: "my-location" }
90
- # end
91
- #
92
- # ## Upload
93
- #
94
- # You can also customize the upload itself via the `:upload` option:
95
- #
96
- # plugin :upload_endpoint, upload: -> (io, context, request) do
97
- # Shrine.new(:cache).upload(io, context)
98
- # end
99
- #
100
- # ## Response
101
- #
102
- # The response returned by the endpoint can be customized via the
103
- # `:rack_response` option:
104
- #
105
- # plugin :upload_endpoint, rack_response: -> (uploaded_file, request) do
106
- # body = { data: uploaded_file.data, url: uploaded_file.url }.to_json
107
- # [201, { "Content-Type" => "application/json" }, [body]]
108
- # end
109
- #
110
- # ## Ad-hoc options
111
- #
112
- # You can override any of the options above when creating the endpoint:
113
- #
114
- # Shrine.upload_endpoint(:cache, max_size: 20*1024*1024)
115
- #
116
- # [Uppy]: https://uppy.io
117
10
  module UploadEndpoint
118
11
  def self.load_dependencies(uploader, opts = {})
119
12
  uploader.plugin :rack_file
@@ -237,7 +130,7 @@ class Shrine
237
130
  if @rack_response
238
131
  @rack_response.call(object, request)
239
132
  else
240
- [200, {"Content-Type" => CONTENT_TYPE_JSON}, [object.to_json]]
133
+ [200, { "Content-Type" => CONTENT_TYPE_JSON }, [object.to_json]]
241
134
  end
242
135
  end
243
136
 
@@ -251,7 +144,7 @@ class Shrine
251
144
 
252
145
  # Used for early returning an error response.
253
146
  def error!(status, message)
254
- throw :halt, [status, {"Content-Type" => CONTENT_TYPE_TEXT}, [message]]
147
+ throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]]
255
148
  end
256
149
 
257
150
  # Returns the uploader around the specified storage.
@@ -2,26 +2,6 @@
2
2
 
3
3
  class Shrine
4
4
  module Plugins
5
- # The `upload_options` plugin allows you to automatically pass additional
6
- # upload options to storage on every upload:
7
- #
8
- # plugin :upload_options, cache: { acl: "private" }
9
- #
10
- # Keys are names of the registered storages, and values are either hashes
11
- # or blocks.
12
- #
13
- # plugin :upload_options, store: ->(io, context) do
14
- # if [:original, :thumb].include?(context[:version])
15
- # { acl: "public-read" }
16
- # else
17
- # { acl: "private" }
18
- # end
19
- # end
20
- #
21
- # If you're uploading the file directly, you can also pass `:upload_options`
22
- # to the uploader.
23
- #
24
- # uploader.upload(file, upload_options: { acl: "public-read" })
25
5
  module UploadOptions
26
6
  def self.configure(uploader, options = {})
27
7
  uploader.opts[:upload_options] ||= {}
@@ -2,42 +2,6 @@
2
2
 
3
3
  class Shrine
4
4
  module Plugins
5
- # The `validation_helpers` plugin provides helper methods for validating
6
- # attached files.
7
- #
8
- # plugin :validation_helpers
9
- #
10
- # Attacher.validate do
11
- # validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
12
- # validate_max_size 5*1024*1024 if record.guest?
13
- # end
14
- #
15
- # The validation methods are instance-level, the `Attacher.validate` block
16
- # is evaluated in context of an instance of `Shrine::Attacher`, so you can
17
- # easily do conditional validation.
18
- #
19
- # The validation methods return whether the validation succeeded, allowing
20
- # you to do conditional validation.
21
- #
22
- # if validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
23
- # validate_max_width 2000
24
- # validate_max_height 2000
25
- # end
26
- #
27
- # If you would like to change default validation error messages, you can
28
- # pass in the `:default_messages` option to the plugin:
29
- #
30
- # plugin :validation_helpers, default_messages: {
31
- # max_size: ->(max) { I18n.t("errors.file.max_size", max: max) },
32
- # mime_type_inclusion: ->(whitelist) { I18n.t("errors.file.mime_type_inclusion", whitelist: whitelist) },
33
- # }
34
- #
35
- # If you would like to change the error message inline, you can pass the
36
- # `:message` option to any validation method:
37
- #
38
- # validate_mime_type_inclusion %w[image/jpeg image/png image/gif], message: "must be JPEG, PNG or GIF"
39
- #
40
- # For a complete list of all validation helpers, see AttacherMethods.
41
5
  module ValidationHelpers
42
6
  def self.configure(uploader, opts = {})
43
7
  uploader.opts[:validation_default_messages] ||= {}
@@ -2,162 +2,6 @@
2
2
 
3
3
  class Shrine
4
4
  module Plugins
5
- # The `versions` plugin enables your uploader to deal with versions, by
6
- # allowing you to return a Hash of files when processing.
7
- #
8
- # plugin :versions
9
- #
10
- # Here is an example of processing image thumbnails using the
11
- # [image_processing] gem:
12
- #
13
- # require "image_processing/mini_magick"
14
- #
15
- # plugin :processing
16
- #
17
- # process(:store) do |io, context|
18
- # versions = { original: io } # retain original
19
- #
20
- # io.download do |original|
21
- # pipeline = ImageProcessing::MiniMagick.source(original)
22
- #
23
- # versions[:large] = pipeline.resize_to_limit!(800, 800)
24
- # versions[:medium] = pipeline.resize_to_limit!(500, 500)
25
- # versions[:small] = pipeline.resize_to_limit!(300, 300)
26
- # end
27
- #
28
- # versions # return the hash of processed files
29
- # end
30
- #
31
- # You probably want to load the `delete_raw` plugin to automatically
32
- # delete processed files after they have been uploaded.
33
- #
34
- # Now when you access the stored attachment through the model, a hash of
35
- # uploaded files will be returned:
36
- #
37
- # user.avatar_data #=>
38
- # # '{
39
- # # "original": {"id":"0gsdf.jpg", "storage":"store", "metadata":{...}},
40
- # # "large": {"id":"lg043.jpg", "storage":"store", "metadata":{...}},
41
- # # "medium": {"id":"kd9fk.jpg", "storage":"store", "metadata":{...}},
42
- # # "small": {"id":"932fl.jpg", "storage":"store", "metadata":{...}}
43
- # # }'
44
- #
45
- # user.avatar #=>
46
- # # {
47
- # # :original => #<Shrine::UploadedFile @data={"id"=>"0gsdf.jpg", ...}>,
48
- # # :large => #<Shrine::UploadedFile @data={"id"=>"lg043.jpg", ...}>,
49
- # # :medium => #<Shrine::UploadedFile @data={"id"=>"kd9fk.jpg", ...}>,
50
- # # :small => #<Shrine::UploadedFile @data={"id"=>"932fl.jpg", ...}>,
51
- # # }
52
- #
53
- # user.avatar[:medium] #=> #<Shrine::UploadedFile>
54
- # user.avatar[:medium].url #=> "/uploads/store/lg043.jpg"
55
- #
56
- # The plugin also extends the `Attacher#url` to accept versions:
57
- #
58
- # user.avatar_url(:large)
59
- # user.avatar_url(:small, download: true) # with URL options
60
- #
61
- # `Shrine.uploaded_file` will also instantiate a hash of
62
- # `Shrine::UploadedFile` objects if given data with versions. If you want
63
- # to apply a change to all files in an attachment, regardless of whether
64
- # it consists of a single file or a hash of versions, you can pass a block
65
- # to `Shrine.uploaded_file` and it will yield each file:
66
- #
67
- # Shrine.uploaded_file(attachment_data) do |uploaded_file|
68
- # # ...
69
- # end
70
- #
71
- # ## Fallbacks
72
- #
73
- # If versions are processed in a background job, there will be a period
74
- # where the user will browse the site before versions have finished
75
- # processing. In this period `Attacher#url` will by default fall back to
76
- # the original file.
77
- #
78
- # user.avatar #=> #<Shrine::UploadedFile>
79
- # user.avatar_url(:large) # falls back to `user.avatar_url`
80
- #
81
- # This behaviour is convenient if you want to gracefully degrade to the
82
- # cached file until the background job has finished processing. However, if
83
- # you would rather provide your own default URLs for versions, you can
84
- # disable this fallback:
85
- #
86
- # plugin :versions, fallback_to_original: false
87
- #
88
- # If you already have some versions processed in the foreground after a
89
- # background job is kicked off (with the `recache` plugin), you can have
90
- # URLs for versions that are yet to be processed fall back to existing
91
- # versions:
92
- #
93
- # plugin :versions, fallbacks: {
94
- # :thumb_2x => :thumb,
95
- # :large_2x => :large,
96
- # }
97
- #
98
- # # ... (background job is kicked off)
99
- #
100
- # user.avatar_url(:thumb_2x) # returns :thumb URL until :thumb_2x becomes available
101
- # user.avatar_url(:large_2x) # returns :large URL until :large_2x becomes available
102
- #
103
- # ## Arrays
104
- #
105
- # In addition to Hashes, the plugin also supports Arrays of files. For
106
- # example, you might want to split a PDf into pages:
107
- #
108
- # process(:store) do |io, context|
109
- # versions = { pages: [] }
110
- #
111
- # io.download do |pdf|
112
- # page_count = MiniMagick::Image.new(pdf.path).pages.count
113
- # pipeline = ImageProcessing::MiniMagick.source(pdf).convert("jpg")
114
- #
115
- # page_count.times do |page_number|
116
- # versions[:pages] << pipeline.loader(page: page_number).call
117
- # end
118
- # end
119
- #
120
- # versions
121
- # end
122
- #
123
- # You can also combine Hashes and Arrays, there is no limit to the level of
124
- # nesting.
125
- #
126
- # ## Original file
127
- #
128
- # It's recommended to always keep the original file after processing
129
- # versions, which you can do by adding the yielded `Shrine::UploadedFile`
130
- # object as one of the versions, by convention named `:original`:
131
- #
132
- # process(:store) do |io, context|
133
- # # processing thumbnail
134
- # { original: io, thumbnail: thumbnail }
135
- # end
136
- #
137
- # If both temporary and permanent storage are Amazon S3, the cached original
138
- # will simply be copied over to permanent storage (without any downloading
139
- # and reuploading), so in these cases the performance impact of storing the
140
- # original file in addition to processed versions is neglibible.
141
- #
142
- # ## Context
143
- #
144
- # The version name will be available via `:version` when generating
145
- # location or a default URL.
146
- #
147
- # def generate_location(io, context)
148
- # "uploads/#{context[:version]}-#{super}"
149
- # end
150
- #
151
- # Attacher.default_url do |options|
152
- # "/images/defaults/#{options[:version]}.jpg"
153
- # end
154
- #
155
- # ## Re-create Versions
156
- #
157
- # If you want to re-create a single or all versions, refer to the [reprocessing versions] guide for details.
158
- #
159
- # [reprocessing versions]: https://shrinerb.com/rdoc/files/doc/regenerating_versions_md.html
160
- # [image_processing]: https://github.com/janko-m/image_processing
161
5
  module Versions
162
6
  def self.load_dependencies(uploader, *)
163
7
  uploader.plugin :default_url