shrine 3.0.1 → 3.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -0
- data/LICENSE.txt +1 -1
- data/README.md +15 -5
- data/doc/advantages.md +33 -16
- data/doc/attacher.md +2 -2
- data/doc/carrierwave.md +78 -34
- data/doc/changing_derivatives.md +39 -39
- data/doc/design.md +134 -85
- data/doc/direct_s3.md +1 -0
- data/doc/external/articles.md +57 -45
- data/doc/external/extensions.md +41 -35
- data/doc/external/misc.md +23 -8
- data/doc/getting_started.md +177 -112
- data/doc/metadata.md +79 -43
- data/doc/multiple_files.md +6 -4
- data/doc/paperclip.md +119 -42
- data/doc/plugins/activerecord.md +1 -1
- data/doc/plugins/add_metadata.md +112 -35
- data/doc/plugins/atomic_helpers.md +41 -3
- data/doc/plugins/backgrounding.md +12 -2
- data/doc/plugins/column.md +36 -7
- data/doc/plugins/data_uri.md +2 -2
- data/doc/plugins/default_url.md +6 -3
- data/doc/plugins/derivation_endpoint.md +26 -28
- data/doc/plugins/derivatives.md +238 -171
- data/doc/plugins/determine_mime_type.md +2 -2
- data/doc/plugins/download_endpoint.md +5 -5
- data/doc/plugins/dynamic_storage.md +1 -1
- data/doc/plugins/form_assign.md +5 -5
- data/doc/plugins/included.md +25 -5
- data/doc/plugins/infer_extension.md +11 -2
- data/doc/plugins/instrumentation.md +1 -1
- data/doc/plugins/metadata_attributes.md +22 -10
- data/doc/plugins/mirroring.md +1 -1
- data/doc/plugins/persistence.md +11 -1
- data/doc/plugins/refresh_metadata.md +5 -4
- data/doc/plugins/remote_url.md +8 -3
- data/doc/plugins/remove_invalid.md +9 -1
- data/doc/plugins/signature.md +11 -2
- data/doc/plugins/store_dimensions.md +12 -2
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +7 -11
- data/doc/plugins/upload_options.md +1 -1
- data/doc/plugins/url_options.md +4 -4
- data/doc/plugins/validation.md +14 -4
- data/doc/plugins/validation_helpers.md +3 -3
- data/doc/plugins/versions.md +7 -7
- data/doc/processing.md +290 -127
- data/doc/refile.md +39 -18
- data/doc/release_notes/2.19.0.md +1 -1
- data/doc/release_notes/2.8.0.md +1 -1
- data/doc/release_notes/3.0.0.md +1 -1
- data/doc/release_notes/3.0.1.md +4 -0
- data/doc/release_notes/3.1.0.md +73 -0
- data/doc/release_notes/3.2.0.md +96 -0
- data/doc/release_notes/3.2.1.md +31 -0
- data/doc/release_notes/3.2.2.md +14 -0
- data/doc/release_notes/3.3.0.md +105 -0
- data/doc/securing_uploads.md +3 -3
- data/doc/storage/file_system.md +1 -1
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +105 -82
- data/doc/testing.md +2 -2
- data/doc/upgrading_to_3.md +97 -49
- data/doc/validation.md +3 -2
- data/lib/shrine.rb +8 -8
- data/lib/shrine/attacher.rb +24 -14
- data/lib/shrine/attachment.rb +5 -5
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/plugins/activerecord.rb +1 -1
- data/lib/shrine/plugins/add_metadata.rb +18 -7
- data/lib/shrine/plugins/backgrounding.rb +2 -2
- data/lib/shrine/plugins/default_storage.rb +6 -6
- data/lib/shrine/plugins/default_url.rb +1 -1
- data/lib/shrine/plugins/derivation_endpoint.rb +12 -7
- data/lib/shrine/plugins/derivatives.rb +61 -29
- data/lib/shrine/plugins/determine_mime_type.rb +3 -3
- data/lib/shrine/plugins/entity.rb +6 -6
- data/lib/shrine/plugins/mirroring.rb +8 -8
- data/lib/shrine/plugins/model.rb +3 -3
- data/lib/shrine/plugins/presign_endpoint.rb +16 -4
- data/lib/shrine/plugins/pretty_location.rb +1 -1
- data/lib/shrine/plugins/processing.rb +1 -1
- data/lib/shrine/plugins/refresh_metadata.rb +2 -2
- data/lib/shrine/plugins/remote_url.rb +3 -3
- data/lib/shrine/plugins/remove_attachment.rb +5 -0
- data/lib/shrine/plugins/remove_invalid.rb +10 -5
- data/lib/shrine/plugins/sequel.rb +1 -1
- data/lib/shrine/plugins/signature.rb +7 -6
- data/lib/shrine/plugins/store_dimensions.rb +22 -11
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +10 -5
- data/lib/shrine/plugins/upload_options.rb +2 -2
- data/lib/shrine/plugins/url_options.rb +2 -2
- data/lib/shrine/plugins/validation.rb +9 -7
- data/lib/shrine/storage/linter.rb +4 -4
- data/lib/shrine/storage/memory.rb +5 -3
- data/lib/shrine/storage/s3.rb +117 -38
- data/lib/shrine/uploaded_file.rb +0 -1
- data/lib/shrine/version.rb +2 -2
- data/shrine.gemspec +7 -8
- metadata +25 -31
@@ -106,7 +106,7 @@ payload:
|
|
106
106
|
|
107
107
|
A default log subscriber is added as well which logs these events:
|
108
108
|
|
109
|
-
```
|
109
|
+
```
|
110
110
|
MIME Type (33ms) – {:io=>StringIO, :uploader=>Shrine}
|
111
111
|
```
|
112
112
|
|
@@ -117,7 +117,7 @@ plugin :determine_mime_type, log_subscriber: -> (event) {
|
|
117
117
|
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
|
118
118
|
}
|
119
119
|
```
|
120
|
-
```
|
120
|
+
```
|
121
121
|
{"name":"mime_type","duration":24,"io":"#<StringIO:0x00007fb7c5b08b80>","uploader":"Shrine"}
|
122
122
|
```
|
123
123
|
|
@@ -87,6 +87,10 @@ class DownloadsController < ApplicationController
|
|
87
87
|
end
|
88
88
|
```
|
89
89
|
|
90
|
+
If you want to create an endpoint with a custom path, you can use the
|
91
|
+
[`rack_response`][rack_response] plugin directly, which this plugin uses
|
92
|
+
internally.
|
93
|
+
|
90
94
|
## Host
|
91
95
|
|
92
96
|
You can specify download URL host via the `:host` plugin option:
|
@@ -155,11 +159,6 @@ You can override any of the options above when creating the endpoint:
|
|
155
159
|
Shrine.download_endpoint(disposition: "attachment")
|
156
160
|
```
|
157
161
|
|
158
|
-
## Custom endpoint
|
159
|
-
|
160
|
-
If you want to have more control on download requests, you can use the
|
161
|
-
`rack_response` plugin which this plugin uses internally.
|
162
|
-
|
163
162
|
## Plugin options
|
164
163
|
|
165
164
|
| Name | Description | Default |
|
@@ -171,3 +170,4 @@ If you want to have more control on download requests, you can use the
|
|
171
170
|
| `:redirect` | Whether to redirect to uploaded files on the storage | `false` |
|
172
171
|
|
173
172
|
[download_endpoint]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/download_endpoint.rb
|
173
|
+
[rack_response]: https://shrinerb.com/docs/plugins/rack_response
|
data/doc/plugins/form_assign.md
CHANGED
@@ -14,7 +14,7 @@ the attacher:
|
|
14
14
|
|
15
15
|
```rb
|
16
16
|
attacher = photo.image_attacher
|
17
|
-
attacher.form_assign("image" => file, "title" => "...", "description" => "...")
|
17
|
+
attacher.form_assign({ "image" => file, "title" => "...", "description" => "..." })
|
18
18
|
attacher.file #=> #<Shrine::UploadedFile>
|
19
19
|
```
|
20
20
|
|
@@ -22,17 +22,17 @@ It works with `remote_url`, `data_uri`, and `remove_attachment` plugins:
|
|
22
22
|
|
23
23
|
```rb
|
24
24
|
# remote_url plugin
|
25
|
-
attacher.form_assign("image_remote_url" => "https://example.com/...")
|
25
|
+
attacher.form_assign({ "image_remote_url" => "https://example.com/..." })
|
26
26
|
attacher.file #=> #<Shrine::UploadedFile>
|
27
27
|
```
|
28
28
|
```rb
|
29
29
|
# data_uri plugin
|
30
|
-
attacher.form_assign("image_data_uri" => "data:image/jpeg;base64,...")
|
30
|
+
attacher.form_assign({ "image_data_uri" => "data:image/jpeg;base64,..." })
|
31
31
|
attacher.file #=> #<Shrine::UploadedFile>
|
32
32
|
```
|
33
33
|
```rb
|
34
34
|
# remove_attachment plugin
|
35
|
-
attacher.form_assign("remove_image" => "1")
|
35
|
+
attacher.form_assign({ "remove_image" => "1" })
|
36
36
|
attacher.file #=> nil
|
37
37
|
```
|
38
38
|
|
@@ -40,7 +40,7 @@ The return value is a hash with form params, with file param replaced with
|
|
40
40
|
cached file data, which can later be assigned again to the record.
|
41
41
|
|
42
42
|
```rb
|
43
|
-
attacher.form_assign("image" => file, "title" => "...", "description" => "...")
|
43
|
+
attacher.form_assign({ "image" => file, "title" => "...", "description" => "..." })
|
44
44
|
#=> { :image => '{"id":"...","storage":"...","metadata":"..."}', "title" => "...", "description" => "..." }
|
45
45
|
```
|
46
46
|
|
data/doc/plugins/included.md
CHANGED
@@ -7,15 +7,35 @@ of the attachment module, and call additional methods on the model that
|
|
7
7
|
includes it.
|
8
8
|
|
9
9
|
```rb
|
10
|
-
|
11
|
-
|
10
|
+
class ImageUploader < Shrine
|
11
|
+
plugin :included do |name|
|
12
|
+
# called when attachment module is included into a model
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
self #=> Photo (the model class)
|
15
|
+
name #=> :image
|
16
|
+
end
|
15
17
|
end
|
16
18
|
```
|
17
19
|
```rb
|
18
|
-
Photo
|
20
|
+
class Photo
|
21
|
+
include ImageUploader::Attachment(:image) # triggers the included block
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
For example, you can use it to define additional methods on the model:
|
26
|
+
|
27
|
+
```rb
|
28
|
+
class ImageUploader < Shrine
|
29
|
+
plugin :included do |name|
|
30
|
+
define_method(:"#{name}_width") { send(name)&.width }
|
31
|
+
define_method(:"#{name}_height") { send(name)&.height }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
```
|
35
|
+
```rb
|
36
|
+
photo = Photo.new(image: file)
|
37
|
+
photo.image_width #=> 1200
|
38
|
+
photo.image_height #=> 800
|
19
39
|
```
|
20
40
|
|
21
41
|
[included]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/included.rb
|
@@ -11,6 +11,15 @@ extension might not be known.
|
|
11
11
|
plugin :infer_extension
|
12
12
|
```
|
13
13
|
|
14
|
+
By default an extension will only be inferred if needed to supply an otherwise
|
15
|
+
missing extension. But option `force: true` will normalize even an already
|
16
|
+
present extension to the extension inferred from MIME type. This could be used
|
17
|
+
to fix incorrect or malicious extensions on user-submitted files.
|
18
|
+
|
19
|
+
```rb
|
20
|
+
plugin :infer_extension, force: true
|
21
|
+
```
|
22
|
+
|
14
23
|
## Inferrers
|
15
24
|
|
16
25
|
By default, the [mini_mime] gem will be used for inferring the extension, but
|
@@ -70,7 +79,7 @@ payload:
|
|
70
79
|
|
71
80
|
A default log subscriber is added as well which logs these events:
|
72
81
|
|
73
|
-
```
|
82
|
+
```
|
74
83
|
Extension (5ms) – {:mime_type=>"image/jpeg", :uploader=>Shrine}
|
75
84
|
```
|
76
85
|
|
@@ -81,7 +90,7 @@ plugin :infer_extension, log_subscriber: -> (event) {
|
|
81
90
|
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
|
82
91
|
}
|
83
92
|
```
|
84
|
-
```
|
93
|
+
```
|
85
94
|
{"name":"extension","duration":5,"mime_type":"image/jpeg","uploader":"Shrine"}
|
86
95
|
```
|
87
96
|
|
@@ -34,7 +34,7 @@ uploaded_file.exists?
|
|
34
34
|
uploaded_file.download
|
35
35
|
uploaded_file.delete
|
36
36
|
```
|
37
|
-
```
|
37
|
+
```
|
38
38
|
Metadata (32ms) – {:storage=>:store, :io=>StringIO, :uploader=>Shrine}
|
39
39
|
Upload (1523ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :io=>StringIO, :upload_options=>{}, :uploader=>Shrine}
|
40
40
|
Exists (755ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}
|
@@ -2,21 +2,18 @@
|
|
2
2
|
title: Metadata Attributes
|
3
3
|
---
|
4
4
|
|
5
|
-
The [`metadata_attributes`][metadata_attributes] plugin allows you to
|
6
|
-
attachment metadata to additional record attributes. You can
|
7
|
-
|
8
|
-
method:
|
5
|
+
The [`metadata_attributes`][metadata_attributes] plugin allows you to write
|
6
|
+
attachment metadata to additional record attributes. You can configure the
|
7
|
+
plugin with a hash of mappings:
|
9
8
|
|
10
9
|
```rb
|
11
10
|
plugin :metadata_attributes, :size => :size, :mime_type => :type
|
12
|
-
|
13
11
|
# or
|
14
|
-
|
15
12
|
plugin :metadata_attributes
|
16
13
|
Attacher.metadata_attributes :size => :size, :mime_type => :type
|
17
14
|
```
|
18
15
|
|
19
|
-
The above configuration will
|
16
|
+
The above configuration will write `size` metadata field to `<attachment>_size`
|
20
17
|
record attribute, and `mime_type` metadata field to `<attachment>_type` record
|
21
18
|
attribute.
|
22
19
|
|
@@ -32,6 +29,18 @@ user.avatar_size #=> nil
|
|
32
29
|
user.avatar_type #=> nil
|
33
30
|
```
|
34
31
|
|
32
|
+
## Model and Entity
|
33
|
+
|
34
|
+
With the [`model`][model] plugin, any method that internally calls
|
35
|
+
`Attacher#write` will trigger metadata attributes writing (`Attacher#assign`,
|
36
|
+
`Attacher#attach`, `Attacher#change`, `Attacher#set`).
|
37
|
+
|
38
|
+
```rb
|
39
|
+
attacher.file.metadata["mime_type"] = "other/type"
|
40
|
+
attacher.write
|
41
|
+
attacher.record.avatar_type #=> "other/type"
|
42
|
+
```
|
43
|
+
|
35
44
|
If you're using the [`entity`][entity] plugin, metadata attributes will be
|
36
45
|
added to `Attacher#column_values`:
|
37
46
|
|
@@ -45,6 +54,11 @@ attacher.column_values #=>
|
|
45
54
|
# }
|
46
55
|
```
|
47
56
|
|
57
|
+
Any metadata attributes that were declared but are missing on the record will
|
58
|
+
be skipped.
|
59
|
+
|
60
|
+
## Full attribute name
|
61
|
+
|
48
62
|
If you want to specify the full record attribute name, pass the record
|
49
63
|
attribute name as a string instead of a symbol.
|
50
64
|
|
@@ -56,8 +70,6 @@ photo.image = image
|
|
56
70
|
photo.original_filename #=> "nature.jpg"
|
57
71
|
```
|
58
72
|
|
59
|
-
Any metadata attributes that were declared but are missing on the record will
|
60
|
-
be skipped.
|
61
|
-
|
62
73
|
[metadata_attributes]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/metadata_attributes.rb
|
63
74
|
[entity]: https://shrinerb.com/docs/plugins/entity
|
75
|
+
[model]: https://shrinerb.com/docs/plugins/model
|
data/doc/plugins/mirroring.md
CHANGED
@@ -50,7 +50,7 @@ Shrine.plugin :mirroring, mirror: { ... }, delete: false
|
|
50
50
|
You can have mirroring performed in a background job:
|
51
51
|
|
52
52
|
```rb
|
53
|
-
Shrine.mirror_upload_block do |file|
|
53
|
+
Shrine.mirror_upload_block do |file, **options|
|
54
54
|
MirrorUploadJob.perform_async(file.shrine_class.name, file.data)
|
55
55
|
end
|
56
56
|
|
data/doc/plugins/persistence.md
CHANGED
@@ -6,6 +6,10 @@ This is an internal plugin that provides uniform persistence interface across
|
|
6
6
|
different persistence plugins (e.g. [`activerecord`][activerecord],
|
7
7
|
[`sequel`][sequel]).
|
8
8
|
|
9
|
+
For these activerecord and sequel, atomic persistence is implemented in terms
|
10
|
+
of database locks, eg "SELECT... FOR UPDATE". For more discussion of concurrency
|
11
|
+
challenges, see the [atomic_helpers] documentation.
|
12
|
+
|
9
13
|
## Atomic promotion
|
10
14
|
|
11
15
|
If you're promoting cached file to permanent storage
|
@@ -65,11 +69,15 @@ changed, and if it hasn't the attachment is persisted. If the attachment has
|
|
65
69
|
changed, `Shrine::AttachmentChanged` exception is raised.
|
66
70
|
|
67
71
|
If you want to execute code after the attachment change check but before
|
68
|
-
persistence, you can pass a block
|
72
|
+
persistence, you can pass a block. For instance, one way to allow concurrent
|
73
|
+
changes to metadata, perhaps in different background workers, without
|
74
|
+
overwriting each other might be:
|
69
75
|
|
70
76
|
```rb
|
71
77
|
attacher.atomic_persist do |reloaded_attacher|
|
72
78
|
# run code after attachment change check but before persistence
|
79
|
+
attacher.file.metadata.merge!(reloaded_attacher.file.metadata)
|
80
|
+
attacher.file.metadata["some_key"] = "changed_value"
|
73
81
|
end
|
74
82
|
```
|
75
83
|
|
@@ -89,3 +97,5 @@ attacher.persist # saves the underlying record
|
|
89
97
|
|
90
98
|
[activerecord]: https://shrinerb.com/docs/plugins/activerecord
|
91
99
|
[sequel]: https://shrinerb.com/docs/plugins/sequel
|
100
|
+
[atomic_helpers]: https://shrinerb.com/docs/plugins/atomic_helpers
|
101
|
+
[backgrounding]: https://shrinerb.com/docs/plugins/backgrounding
|
@@ -12,17 +12,18 @@ plugin :refresh_metadata
|
|
12
12
|
It provides `#refresh_metadata!` method, which triggers metadata extraction
|
13
13
|
(calls `Shrine#extract_metadata`) with the uploaded file opened for reading,
|
14
14
|
and updates the existing metadata hash with the results. This can be done
|
15
|
-
on the
|
15
|
+
on the `Shrine::Attacher` or the `Shrine::UploadedFile` level.
|
16
16
|
|
17
17
|
## Attacher
|
18
18
|
|
19
19
|
Calling `#refresh_metadata!` on a `Shrine::Attacher` object will re-extract
|
20
|
-
metadata of the attached file
|
21
|
-
data back into the attachment attribute.
|
20
|
+
metadata of the attached file, and when used with a [model], it will write new
|
21
|
+
file data back into the attachment attribute.
|
22
22
|
|
23
23
|
```rb
|
24
24
|
attacher.refresh_metadata!
|
25
|
-
attacher.file.metadata
|
25
|
+
attacher.file.metadata # re-extracted metadata
|
26
|
+
attacher.record.file_data #=> '{ ... data with updated metadata ... }'
|
26
27
|
```
|
27
28
|
|
28
29
|
The `Attacher#context` hash will be forwarded to metadata extraction, as well
|
data/doc/plugins/remote_url.md
CHANGED
@@ -40,7 +40,12 @@ around [open-uri].
|
|
40
40
|
You can pass options to the downloader via the `:downloader` option:
|
41
41
|
|
42
42
|
```rb
|
43
|
-
attacher.assign_remote_url
|
43
|
+
attacher.assign_remote_url url, downloader: {
|
44
|
+
headers: { "Authorization" => "Basic ..." },
|
45
|
+
read_timeout: 30, open_timeout: 30,
|
46
|
+
max_redirects: 5,
|
47
|
+
# ...
|
48
|
+
}
|
44
49
|
```
|
45
50
|
|
46
51
|
You can also change the downloader:
|
@@ -166,7 +171,7 @@ following payload:
|
|
166
171
|
|
167
172
|
A default log subscriber is added as well which logs these events:
|
168
173
|
|
169
|
-
```
|
174
|
+
```
|
170
175
|
Remote URL (1550ms) – {:remote_url=>"https://example.com/image.jpg",:download_options=>{},:uploader=>Shrine}
|
171
176
|
```
|
172
177
|
|
@@ -177,7 +182,7 @@ plugin :remote_url, log_subscriber: -> (event) {
|
|
177
182
|
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
|
178
183
|
}
|
179
184
|
```
|
180
|
-
```
|
185
|
+
```
|
181
186
|
{"name":"remote_url","duration":5,"remote_url":"https://example.com/image.jpg","download_options":{},"uploader":"Shrine"}
|
182
187
|
```
|
183
188
|
|
@@ -11,9 +11,17 @@ plugin :remove_invalid
|
|
11
11
|
```
|
12
12
|
|
13
13
|
```rb
|
14
|
-
|
14
|
+
# without previous file
|
15
|
+
photo.image #=> nil
|
16
|
+
photo.image = file # validation fails, assignment is reverted
|
15
17
|
photo.valid? #=> false
|
16
18
|
photo.image #=> nil
|
19
|
+
|
20
|
+
# with previous file
|
21
|
+
photo.image #=> #<Shrine::UploadedFile id="foo" ...>
|
22
|
+
photo.image = file # validation fails, assignment is reverted
|
23
|
+
photo.valid? #=> false
|
24
|
+
photo.image #=> #<Shrine::UploadedFile id="foo" ...>
|
17
25
|
```
|
18
26
|
|
19
27
|
[remove_invalid]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/remove_invalid.rb
|
data/doc/plugins/signature.md
CHANGED
@@ -55,6 +55,15 @@ add_metadata :md5 do |io, action: nil, **|
|
|
55
55
|
end
|
56
56
|
```
|
57
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
|
+
|
58
67
|
## Instrumentation
|
59
68
|
|
60
69
|
If the `instrumentation` plugin has been loaded, the `signature` plugin adds
|
@@ -76,7 +85,7 @@ following payload:
|
|
76
85
|
|
77
86
|
A default log subscriber is added as well which logs these events:
|
78
87
|
|
79
|
-
```
|
88
|
+
```
|
80
89
|
MIME Type (33ms) – {:io=>StringIO, :uploader=>Shrine}
|
81
90
|
```
|
82
91
|
|
@@ -87,7 +96,7 @@ plugin :signature, log_subscriber: -> (event) {
|
|
87
96
|
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
|
88
97
|
}
|
89
98
|
```
|
90
|
-
```
|
99
|
+
```
|
91
100
|
{"name":"signature","duration":24,"io":"#<StringIO:0x00007fb7c5b08b80>","uploader":"Shrine"}
|
92
101
|
```
|
93
102
|
|
@@ -72,6 +72,16 @@ Shrine.dimensions(io) #=> [300, 400] (calls the defined analyzer)
|
|
72
72
|
Shrine.dimensions_analyzers[:fastimage].call(io) #=> [300, 400] (calls a built-in analyzer)
|
73
73
|
```
|
74
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
|
+
|
75
85
|
## Errors
|
76
86
|
|
77
87
|
By default, any exceptions that the analyzer raises while extracting dimensions
|
@@ -110,7 +120,7 @@ following payload:
|
|
110
120
|
|
111
121
|
A default log subscriber is added as well which logs these events:
|
112
122
|
|
113
|
-
```
|
123
|
+
```
|
114
124
|
Image Dimensions (108ms) – {:io=>File, :uploader=>Shrine}
|
115
125
|
```
|
116
126
|
|
@@ -121,7 +131,7 @@ plugin :store_dimensions, log_subscriber: -> (event) {
|
|
121
131
|
Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, **event.payload)
|
122
132
|
}
|
123
133
|
```
|
124
|
-
```
|
134
|
+
```
|
125
135
|
{"name":"image_dimensions","duration":114,"io":"#<File:0x00007fc445371d90>","uploader":"Shrine"}
|
126
136
|
```
|
127
137
|
|
@@ -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
|