shrine 3.1.0 → 3.4.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/README.md +11 -4
- data/doc/advantages.md +4 -4
- data/doc/attacher.md +2 -2
- data/doc/carrierwave.md +24 -12
- data/doc/changing_derivatives.md +1 -1
- data/doc/changing_location.md +6 -5
- data/doc/design.md +134 -85
- data/doc/direct_s3.md +26 -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 +156 -85
- data/doc/metadata.md +80 -44
- data/doc/multiple_files.md +1 -1
- data/doc/paperclip.md +28 -9
- 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/default_url.md +6 -3
- data/doc/plugins/derivatives.md +83 -44
- data/doc/plugins/download_endpoint.md +5 -5
- data/doc/plugins/dynamic_storage.md +1 -1
- data/doc/plugins/entity.md +12 -4
- data/doc/plugins/form_assign.md +5 -5
- data/doc/plugins/included.md +25 -5
- data/doc/plugins/infer_extension.md +9 -0
- data/doc/plugins/instrumentation.md +1 -1
- data/doc/plugins/metadata_attributes.md +1 -0
- data/doc/plugins/mirroring.md +1 -1
- data/doc/plugins/model.md +8 -3
- data/doc/plugins/persistence.md +10 -1
- data/doc/plugins/remote_url.md +6 -1
- data/doc/plugins/remove_invalid.md +9 -1
- data/doc/plugins/sequel.md +1 -1
- data/doc/plugins/store_dimensions.md +10 -0
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +1 -1
- 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/versions.md +7 -7
- data/doc/processing.md +287 -123
- data/doc/refile.md +9 -9
- 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.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/release_notes/3.4.0.md +35 -0
- data/doc/securing_uploads.md +2 -2
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +104 -77
- data/doc/testing.md +12 -2
- data/doc/upgrading_to_3.md +99 -53
- data/lib/shrine.rb +9 -8
- data/lib/shrine/attacher.rb +20 -10
- data/lib/shrine/attachment.rb +2 -2
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/plugins/activerecord.rb +3 -3
- data/lib/shrine/plugins/add_metadata.rb +20 -5
- data/lib/shrine/plugins/backgrounding.rb +2 -2
- data/lib/shrine/plugins/default_url.rb +1 -1
- data/lib/shrine/plugins/derivation_endpoint.rb +13 -8
- data/lib/shrine/plugins/derivatives.rb +59 -30
- data/lib/shrine/plugins/determine_mime_type.rb +5 -3
- data/lib/shrine/plugins/entity.rb +12 -11
- data/lib/shrine/plugins/instrumentation.rb +12 -18
- 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/store_dimensions.rb +4 -2
- 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/version.rb +1 -1
- data/shrine.gemspec +8 -8
- metadata +42 -34
@@ -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/entity.md
CHANGED
@@ -22,7 +22,9 @@ These methods read attachment data from the `#<name>_data` attribute on the
|
|
22
22
|
entity instance.
|
23
23
|
|
24
24
|
```rb
|
25
|
-
class Photo
|
25
|
+
class Photo
|
26
|
+
attr_reader :image_data
|
27
|
+
|
26
28
|
include ImageUploader::Attachment(:image)
|
27
29
|
end
|
28
30
|
```
|
@@ -94,7 +96,9 @@ You can also specify default attacher options when including
|
|
94
96
|
`Shrine::Attachment`:
|
95
97
|
|
96
98
|
```rb
|
97
|
-
class Photo
|
99
|
+
class Photo
|
100
|
+
attr_reader :image_data
|
101
|
+
|
98
102
|
include ImageUploader::Attachment(:image, store: :other_store)
|
99
103
|
end
|
100
104
|
```
|
@@ -123,7 +127,8 @@ You can also use `Shrine::Attacher` directly (with or without the
|
|
123
127
|
`Shrine::Attachment` module):
|
124
128
|
|
125
129
|
```rb
|
126
|
-
class Photo
|
130
|
+
class Photo
|
131
|
+
attr_reader :image_data
|
127
132
|
end
|
128
133
|
```
|
129
134
|
```rb
|
@@ -191,7 +196,7 @@ attacher.file #=> nil
|
|
191
196
|
### Reloading
|
192
197
|
|
193
198
|
The `Attacher#reload` method reloads attached file from the attachment data on
|
194
|
-
the entity attribute.
|
199
|
+
the entity attribute and resets dirty tracking.
|
195
200
|
|
196
201
|
```rb
|
197
202
|
photo = Photo.new
|
@@ -206,6 +211,9 @@ attacher.reload
|
|
206
211
|
attacher.file #=> #<ImageUploader::UploadedFile>
|
207
212
|
```
|
208
213
|
|
214
|
+
If you want to reload attachment data while retaining dirty tracking state, use
|
215
|
+
`Attacher#read` instead.
|
216
|
+
|
209
217
|
### Column values
|
210
218
|
|
211
219
|
The `Attacher#column_values` method returns a hash with the entity attribute as
|
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
|
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/model.md
CHANGED
@@ -17,7 +17,9 @@ Including a `Shrine::Attachment` module into a model class will:
|
|
17
17
|
* add `#<name>=` and `#<name>_changed?` methods
|
18
18
|
|
19
19
|
```rb
|
20
|
-
class Photo
|
20
|
+
class Photo
|
21
|
+
attr_accessor :image_data
|
22
|
+
|
21
23
|
include ImageUploader::Attachment(:image)
|
22
24
|
end
|
23
25
|
```
|
@@ -107,7 +109,9 @@ If you still want to include `Shrine::Attachment` modules to immutable
|
|
107
109
|
entities, you can disable "model" behaviour by passing `model: false`:
|
108
110
|
|
109
111
|
```rb
|
110
|
-
class Photo
|
112
|
+
class Photo
|
113
|
+
attr_reader :image_data
|
114
|
+
|
111
115
|
include ImageUploader::Attachment(:image, model: false)
|
112
116
|
end
|
113
117
|
```
|
@@ -118,7 +122,8 @@ You can also use `Shrine::Attacher` directly (with or without the
|
|
118
122
|
`Shrine::Attachment` module):
|
119
123
|
|
120
124
|
```rb
|
121
|
-
class Photo
|
125
|
+
class Photo
|
126
|
+
attr_accessor :image_data
|
122
127
|
end
|
123
128
|
```
|
124
129
|
```rb
|
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,4 +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
|
92
101
|
[backgrounding]: https://shrinerb.com/docs/plugins/backgrounding
|
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:
|
@@ -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/sequel.md
CHANGED
@@ -172,7 +172,7 @@ attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
|
|
172
172
|
photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
|
173
173
|
```
|
174
174
|
|
175
|
-
###
|
175
|
+
### Persistence
|
176
176
|
|
177
177
|
The following persistence methods are added to `Shrine::Attacher`:
|
178
178
|
|
@@ -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
|
@@ -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
|
@@ -113,7 +113,7 @@ upload happens independently of a database record.
|
|
113
113
|
You can also customize the upload itself via the `:upload` option:
|
114
114
|
|
115
115
|
```rb
|
116
|
-
plugin :upload_endpoint, upload: -> (io,
|
116
|
+
plugin :upload_endpoint, upload: -> (io, options, request) do
|
117
117
|
Shrine.upload(io, :cache, **options)
|
118
118
|
end
|
119
119
|
```
|