shrine 2.19.3 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +523 -41
  3. data/LICENSE.txt +1 -1
  4. data/README.md +83 -979
  5. data/doc/advantages.md +231 -204
  6. data/doc/attacher.md +304 -153
  7. data/doc/carrierwave.md +297 -226
  8. data/doc/changing_derivatives.md +308 -0
  9. data/doc/changing_location.md +103 -21
  10. data/doc/changing_storage.md +110 -0
  11. data/doc/creating_persistence_plugins.md +132 -0
  12. data/doc/creating_plugins.md +43 -23
  13. data/doc/creating_storages.md +19 -5
  14. data/doc/design.md +147 -97
  15. data/doc/direct_s3.md +38 -28
  16. data/doc/external/articles.md +63 -0
  17. data/doc/external/extensions.md +53 -0
  18. data/doc/external/misc.md +32 -0
  19. data/doc/getting_started.md +1156 -0
  20. data/doc/metadata.md +190 -109
  21. data/doc/multiple_files.md +93 -30
  22. data/doc/paperclip.md +384 -262
  23. data/doc/plugins/activerecord.md +177 -46
  24. data/doc/plugins/add_metadata.md +139 -38
  25. data/doc/plugins/atomic_helpers.md +217 -0
  26. data/doc/plugins/backgrounding.md +156 -98
  27. data/doc/plugins/cached_attachment_data.md +7 -5
  28. data/doc/plugins/column.md +121 -0
  29. data/doc/plugins/data_uri.md +23 -22
  30. data/doc/plugins/default_storage.md +36 -10
  31. data/doc/plugins/default_url.md +30 -13
  32. data/doc/plugins/delete_raw.md +4 -2
  33. data/doc/plugins/derivation_endpoint.md +186 -101
  34. data/doc/plugins/derivatives.md +839 -0
  35. data/doc/plugins/determine_mime_type.md +4 -2
  36. data/doc/plugins/download_endpoint.md +64 -8
  37. data/doc/plugins/dynamic_storage.md +5 -3
  38. data/doc/plugins/entity.md +263 -0
  39. data/doc/plugins/form_assign.md +55 -0
  40. data/doc/plugins/included.md +31 -8
  41. data/doc/plugins/infer_extension.md +21 -10
  42. data/doc/plugins/instrumentation.md +38 -16
  43. data/doc/plugins/keep_files.md +16 -17
  44. data/doc/plugins/metadata_attributes.md +42 -13
  45. data/doc/plugins/mirroring.md +118 -0
  46. data/doc/plugins/model.md +210 -0
  47. data/doc/plugins/module_include.md +4 -2
  48. data/doc/plugins/multi_cache.md +24 -0
  49. data/doc/plugins/persistence.md +101 -0
  50. data/doc/plugins/presign_endpoint.md +9 -4
  51. data/doc/plugins/pretty_location.md +16 -3
  52. data/doc/plugins/processing.md +4 -2
  53. data/doc/plugins/rack_file.md +8 -2
  54. data/doc/plugins/rack_response.md +6 -2
  55. data/doc/plugins/recache.md +4 -2
  56. data/doc/plugins/refresh_metadata.md +49 -9
  57. data/doc/plugins/remote_url.md +84 -47
  58. data/doc/plugins/remove_attachment.md +27 -6
  59. data/doc/plugins/remove_invalid.md +21 -6
  60. data/doc/plugins/restore_cached_data.md +11 -3
  61. data/doc/plugins/sequel.md +159 -35
  62. data/doc/plugins/signature.md +16 -5
  63. data/doc/plugins/store_dimensions.md +14 -2
  64. data/doc/plugins/tempfile.md +4 -2
  65. data/doc/plugins/type_predicates.md +96 -0
  66. data/doc/plugins/upload_endpoint.md +13 -13
  67. data/doc/plugins/upload_options.md +6 -4
  68. data/doc/plugins/{default_url_options.md → url_options.md} +9 -7
  69. data/doc/plugins/validation.md +97 -0
  70. data/doc/plugins/validation_helpers.md +16 -13
  71. data/doc/plugins/versions.md +15 -19
  72. data/doc/processing.md +438 -221
  73. data/doc/refile.md +188 -170
  74. data/doc/release_notes/1.0.0.md +4 -0
  75. data/doc/release_notes/1.1.0.md +6 -2
  76. data/doc/release_notes/1.2.0.md +4 -0
  77. data/doc/release_notes/1.3.0.md +4 -0
  78. data/doc/release_notes/1.4.0.md +4 -0
  79. data/doc/release_notes/1.4.1.md +4 -0
  80. data/doc/release_notes/1.4.2.md +4 -0
  81. data/doc/release_notes/2.0.0.md +4 -0
  82. data/doc/release_notes/2.0.1.md +4 -0
  83. data/doc/release_notes/2.1.0.md +5 -1
  84. data/doc/release_notes/2.1.1.md +4 -0
  85. data/doc/release_notes/2.10.0.md +4 -0
  86. data/doc/release_notes/2.10.1.md +4 -0
  87. data/doc/release_notes/2.11.0.md +4 -0
  88. data/doc/release_notes/2.12.0.md +4 -0
  89. data/doc/release_notes/2.13.0.md +4 -0
  90. data/doc/release_notes/2.14.0.md +5 -1
  91. data/doc/release_notes/2.15.0.md +11 -7
  92. data/doc/release_notes/2.16.0.md +4 -0
  93. data/doc/release_notes/2.17.0.md +4 -0
  94. data/doc/release_notes/2.18.0.md +4 -0
  95. data/doc/release_notes/2.19.0.md +6 -3
  96. data/doc/release_notes/2.2.0.md +4 -0
  97. data/doc/release_notes/2.3.0.md +4 -0
  98. data/doc/release_notes/2.3.1.md +4 -0
  99. data/doc/release_notes/2.4.0.md +4 -0
  100. data/doc/release_notes/2.4.1.md +4 -0
  101. data/doc/release_notes/2.5.0.md +4 -0
  102. data/doc/release_notes/2.6.0.md +4 -0
  103. data/doc/release_notes/2.6.1.md +4 -0
  104. data/doc/release_notes/2.7.0.md +4 -0
  105. data/doc/release_notes/2.8.0.md +4 -0
  106. data/doc/release_notes/2.9.0.md +4 -0
  107. data/doc/release_notes/3.0.0.md +981 -0
  108. data/doc/release_notes/3.0.1.md +22 -0
  109. data/doc/release_notes/3.1.0.md +73 -0
  110. data/doc/release_notes/3.2.0.md +96 -0
  111. data/doc/release_notes/3.2.1.md +31 -0
  112. data/doc/release_notes/3.2.2.md +14 -0
  113. data/doc/release_notes/3.3.0.md +105 -0
  114. data/doc/release_notes/3.4.0.md +35 -0
  115. data/doc/release_notes/3.5.0.md +63 -0
  116. data/doc/release_notes/3.6.0.md +23 -0
  117. data/doc/retrieving_uploads.md +5 -2
  118. data/doc/securing_uploads.md +60 -37
  119. data/doc/storage/file_system.md +20 -3
  120. data/doc/storage/memory.md +19 -0
  121. data/doc/storage/s3.md +122 -78
  122. data/doc/testing.md +141 -133
  123. data/doc/upgrading_to_3.md +708 -0
  124. data/doc/validation.md +54 -90
  125. data/lib/shrine/attacher.rb +292 -169
  126. data/lib/shrine/attachment.rb +13 -46
  127. data/lib/shrine/plugins/_persistence.rb +93 -0
  128. data/lib/shrine/plugins/activerecord.rb +77 -34
  129. data/lib/shrine/plugins/add_metadata.rb +25 -17
  130. data/lib/shrine/plugins/atomic_helpers.rb +119 -0
  131. data/lib/shrine/plugins/backgrounding.rb +77 -113
  132. data/lib/shrine/plugins/cached_attachment_data.rb +6 -15
  133. data/lib/shrine/plugins/column.rb +102 -0
  134. data/lib/shrine/plugins/data_uri.rb +38 -36
  135. data/lib/shrine/plugins/default_storage.rb +45 -15
  136. data/lib/shrine/plugins/default_url.rb +12 -24
  137. data/lib/shrine/plugins/default_url_options.rb +3 -30
  138. data/lib/shrine/plugins/delete_raw.rb +10 -16
  139. data/lib/shrine/plugins/derivation_endpoint.rb +130 -171
  140. data/lib/shrine/plugins/derivatives.rb +645 -0
  141. data/lib/shrine/plugins/determine_mime_type.rb +9 -21
  142. data/lib/shrine/plugins/download_endpoint.rb +118 -133
  143. data/lib/shrine/plugins/dynamic_storage.rb +5 -11
  144. data/lib/shrine/plugins/entity.rb +158 -0
  145. data/lib/shrine/plugins/form_assign.rb +108 -0
  146. data/lib/shrine/plugins/included.rb +6 -6
  147. data/lib/shrine/plugins/infer_extension.rb +17 -20
  148. data/lib/shrine/plugins/instrumentation.rb +59 -43
  149. data/lib/shrine/plugins/keep_files.rb +3 -15
  150. data/lib/shrine/plugins/metadata_attributes.rb +28 -19
  151. data/lib/shrine/plugins/mirroring.rb +142 -0
  152. data/lib/shrine/plugins/model.rb +160 -0
  153. data/lib/shrine/plugins/module_include.rb +3 -3
  154. data/lib/shrine/plugins/multi_cache.rb +27 -0
  155. data/lib/shrine/plugins/presign_endpoint.rb +27 -28
  156. data/lib/shrine/plugins/pretty_location.rb +15 -9
  157. data/lib/shrine/plugins/processing.rb +22 -9
  158. data/lib/shrine/plugins/rack_file.rb +2 -42
  159. data/lib/shrine/plugins/rack_response.rb +21 -10
  160. data/lib/shrine/plugins/recache.rb +6 -5
  161. data/lib/shrine/plugins/refresh_metadata.rb +13 -11
  162. data/lib/shrine/plugins/remote_url.rb +49 -49
  163. data/lib/shrine/plugins/remove_attachment.rb +12 -6
  164. data/lib/shrine/plugins/remove_invalid.rb +19 -8
  165. data/lib/shrine/plugins/restore_cached_data.rb +13 -7
  166. data/lib/shrine/plugins/sequel.rb +86 -36
  167. data/lib/shrine/plugins/signature.rb +10 -16
  168. data/lib/shrine/plugins/store_dimensions.rb +35 -40
  169. data/lib/shrine/plugins/tempfile.rb +1 -3
  170. data/lib/shrine/plugins/type_predicates.rb +113 -0
  171. data/lib/shrine/plugins/upload_endpoint.rb +28 -24
  172. data/lib/shrine/plugins/upload_options.rb +14 -15
  173. data/lib/shrine/plugins/url_options.rb +31 -0
  174. data/lib/shrine/plugins/validation.rb +80 -0
  175. data/lib/shrine/plugins/validation_helpers.rb +35 -58
  176. data/lib/shrine/plugins/versions.rb +107 -87
  177. data/lib/shrine/plugins.rb +22 -0
  178. data/lib/shrine/storage/file_system.rb +46 -64
  179. data/lib/shrine/storage/linter.rb +42 -7
  180. data/lib/shrine/storage/memory.rb +49 -0
  181. data/lib/shrine/storage/s3.rb +173 -160
  182. data/lib/shrine/uploaded_file.rb +32 -32
  183. data/lib/shrine/version.rb +3 -3
  184. data/lib/shrine.rb +87 -150
  185. data/shrine.gemspec +11 -12
  186. metadata +92 -82
  187. data/doc/migrating_storage.md +0 -76
  188. data/doc/plugins/backup.md +0 -31
  189. data/doc/plugins/copy.md +0 -24
  190. data/doc/plugins/delete_promoted.md +0 -12
  191. data/doc/plugins/direct_upload.md +0 -172
  192. data/doc/plugins/hooks.md +0 -58
  193. data/doc/plugins/logging.md +0 -42
  194. data/doc/plugins/migration_helpers.md +0 -60
  195. data/doc/plugins/moving.md +0 -19
  196. data/doc/plugins/multi_delete.md +0 -20
  197. data/doc/plugins/parallelize.md +0 -16
  198. data/doc/plugins/parsed_json.md +0 -23
  199. data/doc/regenerating_versions.md +0 -143
  200. data/lib/shrine/plugins/background_helpers.rb +0 -5
  201. data/lib/shrine/plugins/backup.rb +0 -90
  202. data/lib/shrine/plugins/copy.rb +0 -50
  203. data/lib/shrine/plugins/delete_promoted.rb +0 -20
  204. data/lib/shrine/plugins/direct_upload.rb +0 -217
  205. data/lib/shrine/plugins/hooks.rb +0 -90
  206. data/lib/shrine/plugins/logging.rb +0 -142
  207. data/lib/shrine/plugins/migration_helpers.rb +0 -70
  208. data/lib/shrine/plugins/moving.rb +0 -57
  209. data/lib/shrine/plugins/multi_delete.rb +0 -32
  210. data/lib/shrine/plugins/parallelize.rb +0 -78
  211. data/lib/shrine/plugins/parsed_json.rb +0 -29
@@ -1,4 +1,6 @@
1
- # Signature
1
+ ---
2
+ title: Signature
3
+ ---
2
4
 
3
5
  The [`signature`][signature] plugin provides the ability to calculate a hash
4
6
  from file content. This hash can be used as a checksum or just as a unique
@@ -39,7 +41,7 @@ calculated hash.
39
41
  ```rb
40
42
  plugin :add_metadata
41
43
 
42
- add_metadata :md5 do |io, context|
44
+ add_metadata :md5 do |io|
43
45
  calculate_signature(io, :md5)
44
46
  end
45
47
  ```
@@ -48,11 +50,20 @@ This will generate a hash for each uploaded file, but if you want to generate
48
50
  one only for the original file, you can add a conditional:
49
51
 
50
52
  ```rb
51
- add_metadata :md5 do |io, context|
52
- calculate_signature(io, :md5) if context[:action] == :cache
53
+ add_metadata :md5 do |io, action: nil, **|
54
+ calculate_signature(io, :md5) if action == :cache
53
55
  end
54
56
  ```
55
57
 
58
+ ## Rewinding
59
+
60
+ If you want to calculate signature from a non-rewindable IO object, you can
61
+ tell Shrine to skip rewinding:
62
+
63
+ ```rb
64
+ Shrine.calculate_signature(io, :md5, rewind: false)
65
+ ```
66
+
56
67
  ## Instrumentation
57
68
 
58
69
  If the `instrumentation` plugin has been loaded, the `signature` plugin adds
@@ -95,4 +106,4 @@ Or disable logging altogether:
95
106
  plugin :signature, log_subscriber: nil
96
107
  ```
97
108
 
98
- [signature]: /lib/shrine/plugins/signature.rb
109
+ [signature]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/signature.rb
@@ -1,4 +1,6 @@
1
- # Store Dimensions
1
+ ---
2
+ title: Store Dimensions
3
+ ---
2
4
 
3
5
  The [`store_dimensions`][store_dimensions] plugin extracts dimensions of
4
6
  uploaded images and stores them into the metadata hash (by default it uses the
@@ -70,6 +72,16 @@ Shrine.dimensions(io) #=> [300, 400] (calls the defined analyzer)
70
72
  Shrine.dimensions_analyzers[:fastimage].call(io) #=> [300, 400] (calls a built-in analyzer)
71
73
  ```
72
74
 
75
+ ### Disabling auto-extraction
76
+
77
+ If you want to use the dimensions extraction methods but not automatically
78
+ extract dimensions on upload, you can setup this plugin with the
79
+ `auto_extraction: false` option.
80
+
81
+ ```rb
82
+ plugin :store_dimensions, auto_extraction: false
83
+ ```
84
+
73
85
  ## Errors
74
86
 
75
87
  By default, any exceptions that the analyzer raises while extracting dimensions
@@ -129,7 +141,7 @@ Or disable logging altogether:
129
141
  plugin :store_dimensions, log_subscriber: nil
130
142
  ```
131
143
 
132
- [store_dimensions]: /lib/shrine/plugins/store_dimensions.rb
144
+ [store_dimensions]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/store_dimensions.rb
133
145
  [fastimage]: https://github.com/sdsykes/fastimage
134
146
  [mini_magick]: https://github.com/minimagick/minimagick
135
147
  [ruby-vips]: https://github.com/libvips/ruby-vips
@@ -1,4 +1,6 @@
1
- # Tempfile
1
+ ---
2
+ title: Tempfile
3
+ ---
2
4
 
3
5
  The [`tempfile`][tempfile] plugin makes it easier to reuse a single copy of an
4
6
  uploaded file on disk.
@@ -39,4 +41,4 @@ when the given IO object is an open `UploadedFile`. Since `Shrine.with_file` is
39
41
  typically called on the `Shrine` class directly, it's recommended to load this
40
42
  plugin globally.
41
43
 
42
- [tempfile]: /lib/shrine/plugins/tempfile.rb
44
+ [tempfile]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/tempfile.rb
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: Type Predicates
3
+ ---
4
+
5
+ The [`type_predicates`][type_predicates] plugin adds predicate methods to
6
+ `Shrine::UploadedFile` based on the MIME type. By default, it uses the
7
+ [MiniMime] gem for looking up MIME types.
8
+
9
+ ```rb
10
+ # Gemfile
11
+ gem "mini_mime"
12
+ ```
13
+ ```rb
14
+ Shrine.plugin :type_predicates
15
+ ```
16
+
17
+ ## General predicates
18
+
19
+ The plugin adds four predicate methods based on the general type of the file:
20
+
21
+ ```rb
22
+ file.image? # returns true for any "image/*" MIME type
23
+ file.video? # returns true for any "video/*" MIME type
24
+ file.audio? # returns true for any "audio/*" MIME type
25
+ file.text? # returns true for any "text/*" MIME type
26
+ ```
27
+
28
+ If `mime_type` metadata value is nil, `Shrine::Error` will be raised.
29
+
30
+ ## Specific predicates
31
+
32
+ The `UploadedFile#type?` method takes a file extension, and returns whether the
33
+ `mime_type` metadata value of the uploaded file matches the MIME type
34
+ associated to the given file extension.
35
+
36
+ ```rb
37
+ file.type?(:jpg) # returns true if MIME type is "image/jpeg"
38
+ file.type?(:svg) # returns true if MIME type is "image/svg+xml"
39
+ file.type?(:mov) # returns true if MIME type is "video/quicktime"
40
+ file.type?(:ppt) # returns true if MIME type is "application/vnd.ms-powerpoint"
41
+ ...
42
+ ```
43
+
44
+ For convenience, you can create predicate methods for specific file types:
45
+
46
+ ```rb
47
+ Shrine.plugin :type_predicates, methods: %i[jpg svg mov ppt]
48
+ ```
49
+ ```rb
50
+ file.jpg? # returns true if MIME type is "image/jpeg"
51
+ file.svg? # returns true if MIME type is "image/svg+xml"
52
+ file.mov? # returns true if MIME type is "video/quicktime"
53
+ file.ppt? # returns true if MIME type is "application/vnd.ms-powerpoint"
54
+ ```
55
+
56
+ If `mime_type` metadata value is nil, or the underlying MIME type library
57
+ doesn't recognize a given type, `Shrine::Error` will be raised.
58
+
59
+ ### MIME database
60
+
61
+ The MIME type lookup by file extension is done by the underlying MIME type
62
+ library ([MiniMime] by default). You can change the MIME type library via the
63
+ `:mime` plugin option:
64
+
65
+ ```rb
66
+ Shrine.plugin :type_predicates, mime: :marcel # requires adding "marcel" gem to the Gemfile
67
+ ```
68
+
69
+ The following MIME type libraries are supported:
70
+
71
+ | Name | Description |
72
+ | :---- | :--------- |
73
+ | `:mini_mime` | (**Default**.) Uses [MiniMime] gem to look up MIME type by extension. |
74
+ | `:mime_types` | Uses [mime-types] gem to look up MIME type by extension. |
75
+ | `:mimemagic` | Uses [MimeMagic] gem to look up MIME type by extension. |
76
+ | `:marcel` | Uses [Marcel] gem to look up MIME type by extension. |
77
+ | `:rack_mime` | Uses [Rack::Mime] to look up MIME type by extension. |
78
+
79
+ You can also specify a custom block, which receives the extension and is
80
+ expected to return the corresponding MIME type. Inside the block you can call
81
+ into existing MIME type libraries:
82
+
83
+ ```rb
84
+ Shrine.plugin :type_predicates, mime: -> (extension) do
85
+ mime_type = Shrine.type_lookup(extension, :marcel)
86
+ mime_type ||= Shrine.type_lookup(extension, :mini_mime)
87
+ mime_type
88
+ end
89
+ ```
90
+
91
+ [type_predicates]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/type_predicates.rb
92
+ [MiniMime]: https://github.com/discourse/mini_mime
93
+ [mime-types]: https://github.com/mime-types/ruby-mime-types
94
+ [MimeMagic]: https://github.com/minad/mimemagic
95
+ [Marcel]: https://github.com/basecamp/marcel
96
+ [Rack::Mime]: https://github.com/rack/rack/blob/master/lib/rack/mime.rb
@@ -1,4 +1,6 @@
1
- # Upload Endpoint
1
+ ---
2
+ title: Upload Endpoint
3
+ ---
2
4
 
3
5
  The [`upload_endpoint`][upload_endpoint] plugin provides a Rack endpoint which
4
6
  accepts file uploads and forwards them to specified storage. On the client side
@@ -8,6 +10,8 @@ it's recommended to use [Uppy] for asynchronous uploads.
8
10
  plugin :upload_endpoint
9
11
  ```
10
12
 
13
+ ## Setup
14
+
11
15
  The plugin adds a `Shrine.upload_endpoint` method which, given a storage
12
16
  identifier, returns a Rack application that accepts multipart POST requests,
13
17
  and uploads received files to the specified storage. You can run this Rack
@@ -91,16 +95,9 @@ plugin :upload_endpoint, max_size: 20*1024*1024 # 20 MB
91
95
  If the uploaded file is larger than the specified value, a `413 Payload Too
92
96
  Large` response will be returned.
93
97
 
94
- ## Context
95
-
96
- The upload context will *not* contain `:record` and `:name` values, as the
97
- upload happens independently of a database record. The endpoint will send the
98
- following upload context:
98
+ ## Uploader options
99
99
 
100
- * `:action` holds the value `:upload`
101
- * `:request` – holds an instance of `Rack::Request`
102
-
103
- You can update the upload context via `:upload_context`:
100
+ You can pass additional uploader options via `:upload_context`:
104
101
 
105
102
  ```rb
106
103
  plugin :upload_endpoint, upload_context: -> (request) do
@@ -108,13 +105,16 @@ plugin :upload_endpoint, upload_context: -> (request) do
108
105
  end
109
106
  ```
110
107
 
108
+ Note that the uploader will *not* receive `:record` and `:name` values, as the
109
+ upload happens independently of a database record.
110
+
111
111
  ## Upload
112
112
 
113
113
  You can also customize the upload itself via the `:upload` option:
114
114
 
115
115
  ```rb
116
- plugin :upload_endpoint, upload: -> (io, context, request) do
117
- Shrine.upload(io, :cache, context)
116
+ plugin :upload_endpoint, upload: -> (io, options, request) do
117
+ Shrine.upload(io, :cache, **options)
118
118
  end
119
119
  ```
120
120
 
@@ -173,5 +173,5 @@ and the endpoint will automatically use it to verify the uploaded data.
173
173
 
174
174
  If the checksums don't match, a `460 Checksum Mismatch` response is returned.
175
175
 
176
- [upload_endpoint]: /lib/shrine/plugins/upload_endpoint.rb
176
+ [upload_endpoint]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/upload_endpoint.rb
177
177
  [Uppy]: https://uppy.io
@@ -1,4 +1,6 @@
1
- # Upload Options
1
+ ---
2
+ title: Upload Options
3
+ ---
2
4
 
3
5
  The [`upload_options`][upload_options] plugin allows you to automatically pass
4
6
  additional upload options to storage on every upload:
@@ -11,8 +13,8 @@ Keys are names of the registered storages, and values are either hashes or
11
13
  blocks.
12
14
 
13
15
  ```rb
14
- plugin :upload_options, store: -> (io, context) do
15
- if [:original, :thumb].include?(context[:version])
16
+ plugin :upload_options, store: -> (io, options) do
17
+ if options[:derivative]
16
18
  { acl: "public-read" }
17
19
  else
18
20
  { acl: "private" }
@@ -27,4 +29,4 @@ the uploader.
27
29
  uploader.upload(file, upload_options: { acl: "public-read" })
28
30
  ```
29
31
 
30
- [upload_options]: /lib/shrine/plugins/upload_options.rb
32
+ [upload_options]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/upload_options.rb
@@ -1,11 +1,13 @@
1
- # Default URL Options
1
+ ---
2
+ title: URL Options
3
+ ---
2
4
 
3
- The [`default_url_options`][default_url_options] plugin allows you to specify
5
+ The [`url_options`][url_options] plugin allows you to specify
4
6
  URL options that will be applied by default for uploaded files of specified
5
- storages.
7
+ storages. `url_options` are parameters specific to the storage service.
6
8
 
7
9
  ```rb
8
- plugin :default_url_options, store: { expires_in: 24*60*60 }
10
+ plugin :url_options, store: { expires_in: 24*60*60 } # `expires_in` is a URL option for AWS S3
9
11
  ```
10
12
 
11
13
  You can also generate the default URL options dynamically by using a block,
@@ -13,8 +15,8 @@ which will receive the UploadedFile object along with any options that were
13
15
  passed to `UploadedFile#url`.
14
16
 
15
17
  ```rb
16
- plugin :default_url_options, store: -> (io, options) do
17
- { response_content_disposition: ContentDisposition.attachment(io.original_filename) }
18
+ plugin :url_options, store: -> (file, options) do
19
+ { response_content_disposition: ContentDisposition.attachment(file.original_filename) }
18
20
  end
19
21
  ```
20
22
 
@@ -22,4 +24,4 @@ In both cases the default options are merged with options passed to
22
24
  `UploadedFile#url`, and the latter will always have precedence over default
23
25
  options.
24
26
 
25
- [default_url_options]: /lib/shrine/plugins/default_url_options.rb
27
+ [url_options]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/url_options.rb
@@ -0,0 +1,97 @@
1
+ ---
2
+ title: Validation
3
+ ---
4
+
5
+ The [`validation`][validation] plugin provides a framework for validating
6
+ attached files. For some useful validators, see the
7
+ [`validation_helpers`][validation_helpers] plugin.
8
+
9
+ ```rb
10
+ plugin :validation
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ The `Attacher.validate` method is used to register a validation block, which
16
+ is called on attachment:
17
+
18
+ ```rb
19
+ class VideoUploader < Shrine
20
+ Attacher.validate do
21
+ if file.duration > 5*60*60
22
+ errors << "duration must not be longer than 5 hours"
23
+ end
24
+ end
25
+ end
26
+ ```
27
+ ```rb
28
+ attacher.assign(file)
29
+ attacher.errors #=> ["duration must not be longer than 5 hours"]
30
+ ```
31
+
32
+ The validation block is executed in context of a `Shrine::Attacher` instance:
33
+
34
+ ```rb
35
+ class VideoUploader < Shrine
36
+ Attacher.validate do
37
+ self #=> #<Shrine::Attacher>
38
+
39
+ file #=> #<Shrine::UploadedFile>
40
+ record #=> #<Movie>
41
+ name #=> :video
42
+ context #=> { ... }
43
+ end
44
+ end
45
+ ```
46
+
47
+ ## Inheritance
48
+
49
+ If you're subclassing an uploader that has validations defined, you can call
50
+ those validations via `super()`:
51
+
52
+ ```rb
53
+ class ApplicationUploader < Shrine
54
+ Attacher.validate { validate_max_size 5.megabytes }
55
+ end
56
+ ```
57
+ ```rb
58
+ class ImageUploader < ApplicationUploader
59
+ Attacher.validate do
60
+ super() # empty parentheses are required
61
+ validate_mime_type %w[image/jpeg image/png image/webp]
62
+ end
63
+ end
64
+ ```
65
+
66
+ ## Validation options
67
+
68
+ You can pass options to the validator via the `:validate` option:
69
+
70
+ ```rb
71
+ attacher.assign(file, validate: { foo: "bar" })
72
+ ```
73
+ ```rb
74
+ class MyUploader < Shrine
75
+ Attacher.validate do |**options|
76
+ options #=> { foo: "bar" }
77
+ end
78
+ end
79
+ ```
80
+
81
+ You can also skip validation by passing `validate: false`:
82
+
83
+ ```rb
84
+ attacher.assign(file, validate: false) # skips validation
85
+ ```
86
+
87
+ ## Manual validation
88
+
89
+ You can also run validation manually via `Attacher#validate`:
90
+
91
+ ```rb
92
+ attacher.set(uploaded_file) # doesn't trigger validation
93
+ attacher.validate # runs validation
94
+ ```
95
+
96
+ [validation]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/validation.rb
97
+ [validation_helpers]: https://shrinerb.com/docs/plugins/validation_helpers
@@ -1,4 +1,6 @@
1
- # Validation Helpers
1
+ ---
2
+ title: Validation Helpers
3
+ ---
2
4
 
3
5
  The [`validation_helpers`][validation_helpers] plugin provides helper methods
4
6
  for validating attached files based on extracted metadata.
@@ -7,8 +9,9 @@ for validating attached files based on extracted metadata.
7
9
  plugin :validation_helpers
8
10
 
9
11
  Attacher.validate do
10
- validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
11
- validate_max_size 5*1024*1024 if record.guest?
12
+ validate_mime_type %w[image/jpeg image/png image/webp]
13
+ validate_max_size 5*1024*1024 # bytes
14
+ # ...
12
15
  end
13
16
  ```
14
17
 
@@ -38,8 +41,8 @@ accept a list of MIME types, and validate that the `mime_type` metadata value
38
41
  is/is not a member of that list.
39
42
 
40
43
  ```rb
41
- validate_mime_type_inclusion %w[image/jpeg image/png image/gif] # file must be a JPEG, PNG or a GIF image
42
- validate_mime_type_exclusion %w[application/x-php] # file must not be a PHP script
44
+ validate_mime_type_inclusion %w[image/jpeg image/png image/webp] # file must be a JPEG, PNG or a WEBP image
45
+ validate_mime_type_exclusion %w[application/x-php] # file must not be a PHP script
43
46
  ```
44
47
 
45
48
  Instead of `#validate_mime_type_inclusion` you can also use just
@@ -52,8 +55,8 @@ accept a list of file extensions, and validate that the `filename` metadata
52
55
  value extension is/is not a member of that list.
53
56
 
54
57
  ```rb
55
- validate_extension_inclusion %w[jpg jpeg png gif] # file must have .jpg, .jpeg, .png, or .gif extension
56
- validate_extension_exclusion %w[php] # file must not have a .php extension
58
+ validate_extension_inclusion %w[jpg jpeg png webp] # file must have .jpg, .jpeg, .png, or .webp extension
59
+ validate_extension_exclusion %w[php] # file must not have a .php extension
57
60
  ```
58
61
 
59
62
  Instead of `#validate_extension_inclusion` you can also use just
@@ -132,7 +135,7 @@ easily do conditional validation:
132
135
 
133
136
  ```rb
134
137
  Attacher.validate do
135
- if validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
138
+ if validate_mime_type_inclusion %w[image/jpeg image/png image/webp]
136
139
  validate_max_width 2000
137
140
  validate_max_height 2000
138
141
  end
@@ -147,11 +150,11 @@ the `:default_messages` option to the plugin:
147
150
  ```rb
148
151
  plugin :validation_helpers, default_messages: {
149
152
  max_size: -> (max) { I18n.t("errors.file.max_size", max: max) },
150
- min_size: -> (max) { I18n.t("errors.file.min_size", min: min) },
153
+ min_size: -> (min) { I18n.t("errors.file.min_size", min: min) },
151
154
  max_width: -> (max) { I18n.t("errors.file.max_width", max: max) },
152
- min_width: -> (max) { I18n.t("errors.file.min_width", min: min) },
155
+ min_width: -> (min) { I18n.t("errors.file.min_width", min: min) },
153
156
  max_height: -> (max) { I18n.t("errors.file.max_height", max: max) },
154
- min_height: -> (max) { I18n.t("errors.file.min_height", min: min) },
157
+ min_height: -> (min) { I18n.t("errors.file.min_height", min: min) },
155
158
  max_dimensions: -> (dims) { I18n.t("errors.file.max_dimensions", dims: dims) },
156
159
  min_dimensions: -> (dims) { I18n.t("errors.file.min_dimensions", dims: dims) },
157
160
  mime_type_inclusion: -> (list) { I18n.t("errors.file.mime_type_inclusion", list: list) },
@@ -166,8 +169,8 @@ If you would like to change the error message inline, you can pass the
166
169
 
167
170
  ```rb
168
171
  Attacher.validate do
169
- validate_mime_type %w[image/jpeg image/png image/gif], message: "must be JPEG, PNG or GIF"
172
+ validate_mime_type %w[image/jpeg image/png image/webp], message: "must be JPEG, PNG or WEBP"
170
173
  end
171
174
  ```
172
175
 
173
- [validation_helpers]: /lib/shrine/plugins/validation_helpers.rb
176
+ [validation_helpers]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/validation_helpers.rb
@@ -1,4 +1,6 @@
1
- # Versions
1
+ ---
2
+ title: Versions
3
+ ---
2
4
 
3
5
  The [`versions`][versions] plugin enables your uploader to deal with versions,
4
6
  by allowing you to return a Hash of files when processing.
@@ -15,7 +17,7 @@ require "image_processing/mini_magick"
15
17
 
16
18
  plugin :processing
17
19
 
18
- process(:store) do |io, context|
20
+ process(:store) do |io, **options|
19
21
  versions = { original: io } # retain original
20
22
 
21
23
  io.download do |original|
@@ -47,10 +49,10 @@ user.avatar_data #=>
47
49
 
48
50
  user.avatar #=>
49
51
  # {
50
- # :original => #<Shrine::UploadedFile @data={"id"=>"0gsdf.jpg", ...}>,
51
- # :large => #<Shrine::UploadedFile @data={"id"=>"lg043.jpg", ...}>,
52
- # :medium => #<Shrine::UploadedFile @data={"id"=>"kd9fk.jpg", ...}>,
53
- # :small => #<Shrine::UploadedFile @data={"id"=>"932fl.jpg", ...}>,
52
+ # :original => #<Shrine::UploadedFile id=0gsdf.jpg" ...}>,
53
+ # :large => #<Shrine::UploadedFile id=lg043.jpg" ...}>,
54
+ # :medium => #<Shrine::UploadedFile id=kd9fk.jpg" ...}>,
55
+ # :small => #<Shrine::UploadedFile id=932fl.jpg" ...}>,
54
56
  # }
55
57
 
56
58
  user.avatar[:medium] #=> #<Shrine::UploadedFile>
@@ -118,7 +120,7 @@ In addition to Hashes, the plugin also supports Arrays of files. For example,
118
120
  you might want to split a PDf into pages:
119
121
 
120
122
  ```rb
121
- process(:store) do |io, context|
123
+ process(:store) do |io, **options|
122
124
  versions = { pages: [] }
123
125
 
124
126
  io.download do |pdf|
@@ -144,7 +146,7 @@ which you can do by adding the yielded `Shrine::UploadedFile` object as one of
144
146
  the versions, by convention named `:original`:
145
147
 
146
148
  ```rb
147
- process(:store) do |io, context|
149
+ process(:store) do |io, **options|
148
150
  # processing thumbnail
149
151
  { original: io, thumbnail: thumbnail }
150
152
  end
@@ -161,20 +163,14 @@ The version name will be available via `:version` when generating location or a
161
163
  default URL.
162
164
 
163
165
  ```rb
164
- def generate_location(io, context)
165
- "uploads/#{context[:version]}-#{super}"
166
+ def generate_location(io, version: nil, **)
167
+ "uploads/#{version}-#{super}"
166
168
  end
167
169
 
168
- Attacher.default_url do |options|
169
- "/images/defaults/#{options[:version]}.jpg"
170
+ Attacher.default_url do |version: nil, **|
171
+ "/images/defaults/#{version}.jpg"
170
172
  end
171
173
  ```
172
174
 
173
- ## Re-create Versions
174
-
175
- If you want to re-create a single or all versions, refer to the [reprocessing
176
- versions] guide for details.
177
-
178
- [versions]: /lib/shrine/plugins/versions.rb
179
- [reprocessing versions]: /doc/regenerating_versions.md#readme
175
+ [versions]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/versions.rb
180
176
  [image_processing]: https://github.com/janko/image_processing