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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +523 -41
- data/LICENSE.txt +1 -1
- data/README.md +83 -979
- data/doc/advantages.md +231 -204
- data/doc/attacher.md +304 -153
- data/doc/carrierwave.md +297 -226
- data/doc/changing_derivatives.md +308 -0
- data/doc/changing_location.md +103 -21
- data/doc/changing_storage.md +110 -0
- data/doc/creating_persistence_plugins.md +132 -0
- data/doc/creating_plugins.md +43 -23
- data/doc/creating_storages.md +19 -5
- data/doc/design.md +147 -97
- data/doc/direct_s3.md +38 -28
- data/doc/external/articles.md +63 -0
- data/doc/external/extensions.md +53 -0
- data/doc/external/misc.md +32 -0
- data/doc/getting_started.md +1156 -0
- data/doc/metadata.md +190 -109
- data/doc/multiple_files.md +93 -30
- data/doc/paperclip.md +384 -262
- data/doc/plugins/activerecord.md +177 -46
- data/doc/plugins/add_metadata.md +139 -38
- data/doc/plugins/atomic_helpers.md +217 -0
- data/doc/plugins/backgrounding.md +156 -98
- data/doc/plugins/cached_attachment_data.md +7 -5
- data/doc/plugins/column.md +121 -0
- data/doc/plugins/data_uri.md +23 -22
- data/doc/plugins/default_storage.md +36 -10
- data/doc/plugins/default_url.md +30 -13
- data/doc/plugins/delete_raw.md +4 -2
- data/doc/plugins/derivation_endpoint.md +186 -101
- data/doc/plugins/derivatives.md +839 -0
- data/doc/plugins/determine_mime_type.md +4 -2
- data/doc/plugins/download_endpoint.md +64 -8
- data/doc/plugins/dynamic_storage.md +5 -3
- data/doc/plugins/entity.md +263 -0
- data/doc/plugins/form_assign.md +55 -0
- data/doc/plugins/included.md +31 -8
- data/doc/plugins/infer_extension.md +21 -10
- data/doc/plugins/instrumentation.md +38 -16
- data/doc/plugins/keep_files.md +16 -17
- data/doc/plugins/metadata_attributes.md +42 -13
- data/doc/plugins/mirroring.md +118 -0
- data/doc/plugins/model.md +210 -0
- data/doc/plugins/module_include.md +4 -2
- data/doc/plugins/multi_cache.md +24 -0
- data/doc/plugins/persistence.md +101 -0
- data/doc/plugins/presign_endpoint.md +9 -4
- data/doc/plugins/pretty_location.md +16 -3
- data/doc/plugins/processing.md +4 -2
- data/doc/plugins/rack_file.md +8 -2
- data/doc/plugins/rack_response.md +6 -2
- data/doc/plugins/recache.md +4 -2
- data/doc/plugins/refresh_metadata.md +49 -9
- data/doc/plugins/remote_url.md +84 -47
- data/doc/plugins/remove_attachment.md +27 -6
- data/doc/plugins/remove_invalid.md +21 -6
- data/doc/plugins/restore_cached_data.md +11 -3
- data/doc/plugins/sequel.md +159 -35
- data/doc/plugins/signature.md +16 -5
- data/doc/plugins/store_dimensions.md +14 -2
- data/doc/plugins/tempfile.md +4 -2
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +13 -13
- data/doc/plugins/upload_options.md +6 -4
- data/doc/plugins/{default_url_options.md → url_options.md} +9 -7
- data/doc/plugins/validation.md +97 -0
- data/doc/plugins/validation_helpers.md +16 -13
- data/doc/plugins/versions.md +15 -19
- data/doc/processing.md +438 -221
- data/doc/refile.md +188 -170
- data/doc/release_notes/1.0.0.md +4 -0
- data/doc/release_notes/1.1.0.md +6 -2
- data/doc/release_notes/1.2.0.md +4 -0
- data/doc/release_notes/1.3.0.md +4 -0
- data/doc/release_notes/1.4.0.md +4 -0
- data/doc/release_notes/1.4.1.md +4 -0
- data/doc/release_notes/1.4.2.md +4 -0
- data/doc/release_notes/2.0.0.md +4 -0
- data/doc/release_notes/2.0.1.md +4 -0
- data/doc/release_notes/2.1.0.md +5 -1
- data/doc/release_notes/2.1.1.md +4 -0
- data/doc/release_notes/2.10.0.md +4 -0
- data/doc/release_notes/2.10.1.md +4 -0
- data/doc/release_notes/2.11.0.md +4 -0
- data/doc/release_notes/2.12.0.md +4 -0
- data/doc/release_notes/2.13.0.md +4 -0
- data/doc/release_notes/2.14.0.md +5 -1
- data/doc/release_notes/2.15.0.md +11 -7
- data/doc/release_notes/2.16.0.md +4 -0
- data/doc/release_notes/2.17.0.md +4 -0
- data/doc/release_notes/2.18.0.md +4 -0
- data/doc/release_notes/2.19.0.md +6 -3
- data/doc/release_notes/2.2.0.md +4 -0
- data/doc/release_notes/2.3.0.md +4 -0
- data/doc/release_notes/2.3.1.md +4 -0
- data/doc/release_notes/2.4.0.md +4 -0
- data/doc/release_notes/2.4.1.md +4 -0
- data/doc/release_notes/2.5.0.md +4 -0
- data/doc/release_notes/2.6.0.md +4 -0
- data/doc/release_notes/2.6.1.md +4 -0
- data/doc/release_notes/2.7.0.md +4 -0
- data/doc/release_notes/2.8.0.md +4 -0
- data/doc/release_notes/2.9.0.md +4 -0
- data/doc/release_notes/3.0.0.md +981 -0
- data/doc/release_notes/3.0.1.md +22 -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/release_notes/3.4.0.md +35 -0
- data/doc/release_notes/3.5.0.md +63 -0
- data/doc/release_notes/3.6.0.md +23 -0
- data/doc/retrieving_uploads.md +5 -2
- data/doc/securing_uploads.md +60 -37
- data/doc/storage/file_system.md +20 -3
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +122 -78
- data/doc/testing.md +141 -133
- data/doc/upgrading_to_3.md +708 -0
- data/doc/validation.md +54 -90
- data/lib/shrine/attacher.rb +292 -169
- data/lib/shrine/attachment.rb +13 -46
- data/lib/shrine/plugins/_persistence.rb +93 -0
- data/lib/shrine/plugins/activerecord.rb +77 -34
- data/lib/shrine/plugins/add_metadata.rb +25 -17
- data/lib/shrine/plugins/atomic_helpers.rb +119 -0
- data/lib/shrine/plugins/backgrounding.rb +77 -113
- data/lib/shrine/plugins/cached_attachment_data.rb +6 -15
- data/lib/shrine/plugins/column.rb +102 -0
- data/lib/shrine/plugins/data_uri.rb +38 -36
- data/lib/shrine/plugins/default_storage.rb +45 -15
- data/lib/shrine/plugins/default_url.rb +12 -24
- data/lib/shrine/plugins/default_url_options.rb +3 -30
- data/lib/shrine/plugins/delete_raw.rb +10 -16
- data/lib/shrine/plugins/derivation_endpoint.rb +130 -171
- data/lib/shrine/plugins/derivatives.rb +645 -0
- data/lib/shrine/plugins/determine_mime_type.rb +9 -21
- data/lib/shrine/plugins/download_endpoint.rb +118 -133
- data/lib/shrine/plugins/dynamic_storage.rb +5 -11
- data/lib/shrine/plugins/entity.rb +158 -0
- data/lib/shrine/plugins/form_assign.rb +108 -0
- data/lib/shrine/plugins/included.rb +6 -6
- data/lib/shrine/plugins/infer_extension.rb +17 -20
- data/lib/shrine/plugins/instrumentation.rb +59 -43
- data/lib/shrine/plugins/keep_files.rb +3 -15
- data/lib/shrine/plugins/metadata_attributes.rb +28 -19
- data/lib/shrine/plugins/mirroring.rb +142 -0
- data/lib/shrine/plugins/model.rb +160 -0
- data/lib/shrine/plugins/module_include.rb +3 -3
- data/lib/shrine/plugins/multi_cache.rb +27 -0
- data/lib/shrine/plugins/presign_endpoint.rb +27 -28
- data/lib/shrine/plugins/pretty_location.rb +15 -9
- data/lib/shrine/plugins/processing.rb +22 -9
- data/lib/shrine/plugins/rack_file.rb +2 -42
- data/lib/shrine/plugins/rack_response.rb +21 -10
- data/lib/shrine/plugins/recache.rb +6 -5
- data/lib/shrine/plugins/refresh_metadata.rb +13 -11
- data/lib/shrine/plugins/remote_url.rb +49 -49
- data/lib/shrine/plugins/remove_attachment.rb +12 -6
- data/lib/shrine/plugins/remove_invalid.rb +19 -8
- data/lib/shrine/plugins/restore_cached_data.rb +13 -7
- data/lib/shrine/plugins/sequel.rb +86 -36
- data/lib/shrine/plugins/signature.rb +10 -16
- data/lib/shrine/plugins/store_dimensions.rb +35 -40
- data/lib/shrine/plugins/tempfile.rb +1 -3
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +28 -24
- data/lib/shrine/plugins/upload_options.rb +14 -15
- data/lib/shrine/plugins/url_options.rb +31 -0
- data/lib/shrine/plugins/validation.rb +80 -0
- data/lib/shrine/plugins/validation_helpers.rb +35 -58
- data/lib/shrine/plugins/versions.rb +107 -87
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/storage/file_system.rb +46 -64
- data/lib/shrine/storage/linter.rb +42 -7
- data/lib/shrine/storage/memory.rb +49 -0
- data/lib/shrine/storage/s3.rb +173 -160
- data/lib/shrine/uploaded_file.rb +32 -32
- data/lib/shrine/version.rb +3 -3
- data/lib/shrine.rb +87 -150
- data/shrine.gemspec +11 -12
- metadata +92 -82
- data/doc/migrating_storage.md +0 -76
- data/doc/plugins/backup.md +0 -31
- data/doc/plugins/copy.md +0 -24
- data/doc/plugins/delete_promoted.md +0 -12
- data/doc/plugins/direct_upload.md +0 -172
- data/doc/plugins/hooks.md +0 -58
- data/doc/plugins/logging.md +0 -42
- data/doc/plugins/migration_helpers.md +0 -60
- data/doc/plugins/moving.md +0 -19
- data/doc/plugins/multi_delete.md +0 -20
- data/doc/plugins/parallelize.md +0 -16
- data/doc/plugins/parsed_json.md +0 -23
- data/doc/regenerating_versions.md +0 -143
- data/lib/shrine/plugins/background_helpers.rb +0 -5
- data/lib/shrine/plugins/backup.rb +0 -90
- data/lib/shrine/plugins/copy.rb +0 -50
- data/lib/shrine/plugins/delete_promoted.rb +0 -20
- data/lib/shrine/plugins/direct_upload.rb +0 -217
- data/lib/shrine/plugins/hooks.rb +0 -90
- data/lib/shrine/plugins/logging.rb +0 -142
- data/lib/shrine/plugins/migration_helpers.rb +0 -70
- data/lib/shrine/plugins/moving.rb +0 -57
- data/lib/shrine/plugins/multi_delete.rb +0 -32
- data/lib/shrine/plugins/parallelize.rb +0 -78
- data/lib/shrine/plugins/parsed_json.rb +0 -29
data/doc/plugins/rack_file.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Rack File
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`rack_file`][rack_file] plugin enables uploaders to accept Rack uploaded
|
|
4
6
|
file hashes for uploading.
|
|
@@ -7,6 +9,8 @@ file hashes for uploading.
|
|
|
7
9
|
plugin :rack_file
|
|
8
10
|
```
|
|
9
11
|
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
10
14
|
When a file is uploaded to your Rack application using the
|
|
11
15
|
`multipart/form-data` parameter encoding, Rack converts the uploaded file to a
|
|
12
16
|
hash.
|
|
@@ -33,6 +37,8 @@ user.avatar = file_hash
|
|
|
33
37
|
attacher.assign(file_hash)
|
|
34
38
|
```
|
|
35
39
|
|
|
40
|
+
## API
|
|
41
|
+
|
|
36
42
|
Internally the Rack uploaded file hash will be converted into an IO object
|
|
37
43
|
using `Shrine.rack_file`, which you can also use directly:
|
|
38
44
|
|
|
@@ -48,4 +54,4 @@ Note that this plugin is not needed in Rails applications, as Rails already
|
|
|
48
54
|
wraps the Rack uploaded file hash into an `ActionDispatch::Http::UploadedFile`
|
|
49
55
|
object.
|
|
50
56
|
|
|
51
|
-
[rack_file]: /lib/shrine/plugins/rack_file.rb
|
|
57
|
+
[rack_file]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/rack_file.rb
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Rack Response
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`rack_response`][rack_response] plugin allows you to convert an
|
|
4
6
|
`UploadedFile` object into a triple consisting of status, headers, and body,
|
|
@@ -8,6 +10,8 @@ suitable for returning as a response in a Rack-based application.
|
|
|
8
10
|
plugin :rack_response
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
11
15
|
To convert a `Shrine::UploadedFile` into a Rack response, simply call
|
|
12
16
|
`#to_rack_response`:
|
|
13
17
|
|
|
@@ -107,6 +111,6 @@ uploaded_file.open(
|
|
|
107
111
|
uploaded_file.to_rack_response
|
|
108
112
|
```
|
|
109
113
|
|
|
110
|
-
[rack_response]: /lib/shrine/plugins/rack_response.rb
|
|
114
|
+
[rack_response]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/rack_response.rb
|
|
111
115
|
[range requests]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
|
|
112
116
|
[Rack::Sendfile]: https://www.rubydoc.info/github/rack/rack/Rack/Sendfile
|
data/doc/plugins/recache.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Re-cache
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`recache`][recache] plugin allows you to process your attachment after
|
|
4
6
|
validations succeed, but before the attachment is promoted. This is useful for
|
|
@@ -26,4 +28,4 @@ you're using the attacher directly, you can call it manually:
|
|
|
26
28
|
attacher.recache if attacher.changed?
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
[recache]: /lib/shrine/plugins/recache.rb
|
|
31
|
+
[recache]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/recache.rb
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Refresh Metadata
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`refresh_metadata`][refresh_metadata] plugin allows you to re-extract
|
|
4
6
|
metadata from an uploaded file.
|
|
@@ -7,27 +9,65 @@ metadata from an uploaded file.
|
|
|
7
9
|
plugin :refresh_metadata
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
It provides
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
It provides `#refresh_metadata!` method, which triggers metadata extraction
|
|
13
|
+
(calls `Shrine#extract_metadata`) with the uploaded file opened for reading,
|
|
14
|
+
and updates the existing metadata hash with the results. This can be done
|
|
15
|
+
on the `Shrine::Attacher` or the `Shrine::UploadedFile` level.
|
|
16
|
+
|
|
17
|
+
## Attacher
|
|
18
|
+
|
|
19
|
+
Calling `#refresh_metadata!` on a `Shrine::Attacher` object will re-extract
|
|
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
|
+
|
|
23
|
+
```rb
|
|
24
|
+
attacher.refresh_metadata!
|
|
25
|
+
attacher.file.metadata # re-extracted metadata
|
|
26
|
+
attacher.record.file_data #=> '{ ... data with updated metadata ... }'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The `Attacher#context` hash will be forwarded to metadata extraction, as well
|
|
30
|
+
as any options that you pass in.
|
|
31
|
+
|
|
32
|
+
```rb
|
|
33
|
+
# via context
|
|
34
|
+
attacher.context[:foo] = "bar"
|
|
35
|
+
attacher.refresh_metadata! # passes `{ foo: "bar" }` options to metadata extraction
|
|
36
|
+
|
|
37
|
+
# via arguments
|
|
38
|
+
attacher.refresh_metadata!(foo: "bar") # passes `{ foo: "bar" }` options to metadata extraction
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Uploaded File
|
|
42
|
+
|
|
43
|
+
The `#refresh_metadata!` method can be called on a `Shrine::UploadedFile` object
|
|
44
|
+
as well.
|
|
13
45
|
|
|
14
46
|
```rb
|
|
15
47
|
uploaded_file.refresh_metadata!
|
|
16
48
|
uploaded_file.metadata # re-extracted metadata
|
|
17
49
|
```
|
|
18
50
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
51
|
+
If the uploaded file is not open, it is opened before and closed after metadata
|
|
52
|
+
extraction. For remote storage services this will make an HTTP request.
|
|
53
|
+
However, only the portion of the file needed for extracting metadata will be
|
|
54
|
+
downloaded.
|
|
22
55
|
|
|
23
56
|
If the uploaded file is already open, it is passed to metadata extraction as
|
|
24
57
|
is.
|
|
25
58
|
|
|
26
59
|
```rb
|
|
27
60
|
uploaded_file.open do
|
|
28
|
-
uploaded_file.refresh_metadata!
|
|
61
|
+
uploaded_file.refresh_metadata! # uses the already opened file
|
|
29
62
|
# ...
|
|
30
63
|
end
|
|
31
64
|
```
|
|
32
65
|
|
|
33
|
-
|
|
66
|
+
Any options passed in will be forwarded to metadata extraction:
|
|
67
|
+
|
|
68
|
+
```rb
|
|
69
|
+
uploaded_file.refresh_metadata!(foo: "bar") # passes `{ foo: "bar" }` options to metadata extraction
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
[refresh_metadata]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/refresh_metadata.rb
|
|
73
|
+
[model]: https://shrinerb.com/docs/plugins/model
|
data/doc/plugins/remote_url.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Remote URL
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`remote_url`][remote_url] plugin allows you to attach files from a remote
|
|
4
6
|
location.
|
|
@@ -7,82 +9,117 @@ location.
|
|
|
7
9
|
plugin :remote_url, max_size: 20*1024*1024
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
`#avatar_remote_url` and `#avatar_remote_url=` methods to your model.
|
|
12
|
+
## Usage
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
user.avatar_remote_url = "http://example.com/cool-image.png"
|
|
16
|
-
user.avatar #=> #<Shrine::UploadedFile>
|
|
14
|
+
The plugin will add the `#<name>_remote_url` writer to your model, which
|
|
15
|
+
downloads the remote file and uploads it to temporary storage.
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
```rb
|
|
18
|
+
photo.image_remote_url = "http://example.com/cool-image.png"
|
|
19
|
+
photo.image.mime_type #=> "image/png"
|
|
20
|
+
photo.image.size #=> 43423
|
|
21
|
+
photo.image.original_filename #=> "cool-image.png"
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
`
|
|
24
|
+
If you're using `Shrine::Attacher` directly, you can use
|
|
25
|
+
`Attacher#assign_remote_url`:
|
|
25
26
|
|
|
26
27
|
```rb
|
|
27
|
-
attacher.
|
|
28
|
+
attacher.assign_remote_url("http://example.com/cool-image.png")
|
|
29
|
+
attacher.file.mime_type #=> "image/png"
|
|
30
|
+
attacher.file.size #=> 43423
|
|
31
|
+
attacher.file.original_filename #=> "cool-image.png"
|
|
28
32
|
```
|
|
29
33
|
|
|
34
|
+
## Downloader
|
|
35
|
+
|
|
30
36
|
By default, the file will be downloaded using `Down.download` from the [Down]
|
|
31
|
-
gem. This will use the
|
|
37
|
+
gem. This will use the [Down::NetHttp] backend by default, which is a wrapper
|
|
32
38
|
around [open-uri].
|
|
33
39
|
|
|
34
|
-
|
|
40
|
+
You can pass options to the downloader via the `:downloader` option:
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
```rb
|
|
43
|
+
attacher.assign_remote_url url, downloader: {
|
|
44
|
+
headers: { "Authorization" => "Basic ..." },
|
|
45
|
+
read_timeout: 30, open_timeout: 30,
|
|
46
|
+
max_redirects: 5,
|
|
47
|
+
# ...
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
You can also change the downloader:
|
|
38
52
|
|
|
39
53
|
```rb
|
|
40
|
-
|
|
54
|
+
# Gemfile
|
|
55
|
+
gem "http"
|
|
56
|
+
```
|
|
57
|
+
```rb
|
|
58
|
+
require "down/http"
|
|
59
|
+
|
|
60
|
+
plugin :remote_url, downloader: -> (url, **options) {
|
|
61
|
+
Down::Http.download(url, **options) do |client|
|
|
62
|
+
client.follow(max_hops: 2).timeout(connect: 2, read: 2)
|
|
63
|
+
end
|
|
64
|
+
}
|
|
41
65
|
```
|
|
42
66
|
|
|
43
|
-
|
|
67
|
+
Any `Down::NotFound` and `Down::TooLarge` exceptions will be rescued and
|
|
68
|
+
converted into validation errors. If you want to convert any other exceptions
|
|
69
|
+
into validation errors, you can raise them as
|
|
70
|
+
`Shrine::Plugins::RemoteUrl::DownloadError`:
|
|
44
71
|
|
|
45
72
|
```rb
|
|
46
|
-
|
|
73
|
+
plugin :remote_url, downloader: -> (url, **options) {
|
|
74
|
+
begin
|
|
75
|
+
RestClient.get(url)
|
|
76
|
+
rescue RestClient::ExceptionWithResponse => error
|
|
77
|
+
raise Shrine::Plugins::RemoteUrl::DownloadError, "remote file not found"
|
|
78
|
+
end
|
|
79
|
+
}
|
|
47
80
|
```
|
|
48
81
|
|
|
49
|
-
|
|
82
|
+
### Calling downloader
|
|
50
83
|
|
|
51
|
-
|
|
84
|
+
You can call the downloader directly with `Shrine.remote_url`:
|
|
52
85
|
|
|
53
86
|
```rb
|
|
54
|
-
|
|
87
|
+
# or YourUploader.remote_url(...)
|
|
88
|
+
file = Shrine.remote_url("https://example.com/image.jpg")
|
|
89
|
+
file #=> #<Tempfile:...>
|
|
55
90
|
```
|
|
56
91
|
|
|
57
|
-
|
|
58
|
-
as soon as it gets the "Content-Length" header, or the size of currently
|
|
59
|
-
downloaded content surpasses the maximum size. However, if for whatever reason
|
|
60
|
-
you don't want to limit the maximum file size, you can set `:max_size` to nil:
|
|
92
|
+
You can pass additional options as well:
|
|
61
93
|
|
|
62
94
|
```rb
|
|
63
|
-
|
|
95
|
+
# or YourUploader.remote_url(...)
|
|
96
|
+
Shrine.remote_url("https://example.com/image.jpg", headers: { "Cookie" => "..." })
|
|
64
97
|
```
|
|
65
98
|
|
|
66
|
-
##
|
|
99
|
+
## Uploader options
|
|
67
100
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
can use the [http.rb] Down backend for downloading:
|
|
101
|
+
Any additional options passed to `Attacher#assign_remote_url` will be forwarded
|
|
102
|
+
to `Attacher#assign` (and `Shrine#upload`):
|
|
71
103
|
|
|
72
104
|
```rb
|
|
73
|
-
|
|
74
|
-
gem "http"
|
|
105
|
+
attacher.assign_remote_url(url, metadata: { "mime_type" => "text/plain" })
|
|
75
106
|
```
|
|
107
|
+
|
|
108
|
+
## Maximum size
|
|
109
|
+
|
|
110
|
+
It's a good practice to limit the maximum filesize of the remote file:
|
|
111
|
+
|
|
76
112
|
```rb
|
|
77
|
-
|
|
113
|
+
plugin :remote_url, max_size: 20*1024*1024 # 20 MB
|
|
114
|
+
```
|
|
78
115
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
end
|
|
116
|
+
Now if a file that is bigger than 20MB is assigned, download will be terminated
|
|
117
|
+
as soon as it gets the "Content-Length" header, or the size of currently
|
|
118
|
+
downloaded content surpasses the maximum size. However, if for whatever reason
|
|
119
|
+
you don't want to limit the maximum file size, you can set `:max_size` to nil:
|
|
84
120
|
|
|
85
|
-
|
|
121
|
+
```rb
|
|
122
|
+
plugin :remote_url, max_size: nil
|
|
86
123
|
```
|
|
87
124
|
|
|
88
125
|
## Errors
|
|
@@ -103,11 +140,10 @@ file ID, and pair that with the `backgrounding` plugin.
|
|
|
103
140
|
|
|
104
141
|
## File extension
|
|
105
142
|
|
|
106
|
-
When attaching from a remote URL, the uploaded file location will
|
|
107
|
-
extension
|
|
108
|
-
|
|
109
|
-
extension
|
|
110
|
-
load the `infer_extension` plugin to infer it from the MIME type.
|
|
143
|
+
When attaching from a remote URL, the uploaded file location will inherit the
|
|
144
|
+
extension from the URL. However, some URLs might not have an extension. To
|
|
145
|
+
handle this case, you can use the `infer_extension` plugin to infer the
|
|
146
|
+
extension from the MIME type.
|
|
111
147
|
|
|
112
148
|
```rb
|
|
113
149
|
plugin :infer_extension
|
|
@@ -156,8 +192,9 @@ Or disable logging altogether:
|
|
|
156
192
|
plugin :remote_url, log_subscriber: nil
|
|
157
193
|
```
|
|
158
194
|
|
|
159
|
-
[remote_url]: /lib/shrine/plugins/remote_url.rb
|
|
195
|
+
[remote_url]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/remote_url.rb
|
|
160
196
|
[Down]: https://github.com/janko/down
|
|
197
|
+
[Down::NetHttp]: https://github.com/janko/down#downnethttp
|
|
161
198
|
[open-uri]: https://ruby-doc.org/stdlib/libdoc/open-uri/rdoc/OpenURI.html
|
|
162
199
|
[http.rb]: https://github.com/httprb/http
|
|
163
200
|
[shrine-url]: https://github.com/shrinerb/shrine-url
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Remove Attachment
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`remove_attachment`][remove_attachment] plugin allows you to delete
|
|
4
6
|
attachments through checkboxes on the web form.
|
|
@@ -7,12 +9,31 @@ attachments through checkboxes on the web form.
|
|
|
7
9
|
plugin :remove_attachment
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
to add a form field for removing attachments:
|
|
12
|
+
The plugin adds the `#remove_<name>` accessor to your model, which removes the
|
|
13
|
+
attached file if it receives a truthy value:
|
|
13
14
|
|
|
14
15
|
```rb
|
|
15
|
-
|
|
16
|
+
photo.image #=> #<Shrine::UploadedFile>
|
|
17
|
+
photo.remove_image = 'true'
|
|
18
|
+
photo.image #=> nil
|
|
16
19
|
```
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
This allows you to add a checkbox form field for removing attachments:
|
|
22
|
+
|
|
23
|
+
```rb
|
|
24
|
+
form_for photo do |f|
|
|
25
|
+
# ...
|
|
26
|
+
f.check_box :remove_image
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you're using the `Shrine::Attacher` directly, you can use the
|
|
31
|
+
`Attacher#remove` accessor:
|
|
32
|
+
|
|
33
|
+
```rb
|
|
34
|
+
attacher.file #=> #<Shrine::UploadedFile>
|
|
35
|
+
attacher.remove = '1'
|
|
36
|
+
attacher.file #=> nil
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
[remove_attachment]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/remove_attachment.rb
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Remove Invalid
|
|
3
|
+
---
|
|
2
4
|
|
|
3
|
-
The [`remove_invalid`][remove_invalid] plugin automatically deletes
|
|
4
|
-
assigned file if it was invalid
|
|
5
|
-
|
|
6
|
-
will be assigned.
|
|
5
|
+
The [`remove_invalid`][remove_invalid] plugin automatically deletes and
|
|
6
|
+
deassigns a new assigned file if it was invalid. If there was a previous file
|
|
7
|
+
attached, it will be assigned back.
|
|
7
8
|
|
|
8
9
|
```rb
|
|
9
10
|
plugin :remove_invalid
|
|
10
11
|
```
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
```rb
|
|
14
|
+
# without previous file
|
|
15
|
+
photo.image #=> nil
|
|
16
|
+
photo.image = file # validation fails, assignment is reverted
|
|
17
|
+
photo.valid? #=> false
|
|
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" ...>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
[remove_invalid]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/remove_invalid.rb
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Restore Cached Data
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`restore_cached_data`][restore_cached_data] plugin re-extracts metadata
|
|
4
6
|
when assigning already cached files, i.e. when the attachment has been retained
|
|
@@ -10,7 +12,13 @@ extracted on the client side.
|
|
|
10
12
|
```rb
|
|
11
13
|
plugin :restore_cached_data
|
|
12
14
|
```
|
|
15
|
+
```rb
|
|
16
|
+
photo.image = { "id" => "path/to/image.jpg", "storage" => "cache", "metadata" => {} }
|
|
17
|
+
photo.image.metadata #=> { "size" => 4823763, "mime_type" => "image/jpeg", ... }
|
|
18
|
+
```
|
|
13
19
|
|
|
14
|
-
It uses the `refresh_metadata` plugin to re-extract
|
|
20
|
+
It uses the [`refresh_metadata`][refresh_metadata] plugin to re-extract
|
|
21
|
+
metadata.
|
|
15
22
|
|
|
16
|
-
[restore_cached_data]: /lib/shrine/plugins/restore_cached_data.rb
|
|
23
|
+
[restore_cached_data]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/restore_cached_data.rb
|
|
24
|
+
[refresh_metadata]: https://shrinerb.com/docs/plugins/refresh_metadata
|
data/doc/plugins/sequel.md
CHANGED
|
@@ -1,67 +1,191 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Sequel
|
|
3
|
+
---
|
|
2
4
|
|
|
3
|
-
The [`sequel`][sequel] plugin
|
|
4
|
-
|
|
5
|
+
The [`sequel`][sequel] plugin adds [Sequel] integration to the attachment
|
|
6
|
+
interface. It is built on top of the [`model`][model] plugin.
|
|
5
7
|
|
|
6
8
|
```rb
|
|
7
|
-
plugin :sequel
|
|
9
|
+
Shrine.plugin :sequel
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
##
|
|
12
|
+
## Attachment
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Including a `Shrine::Attachment` module into a `Sequel::Model` subclass will:
|
|
13
15
|
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
16
|
+
* add [model] attachment methods
|
|
17
|
+
* add [validations](#validations) and [hooks](#hooks) to tie attachment process
|
|
18
|
+
to the record lifecycle
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
`
|
|
20
|
+
```rb
|
|
21
|
+
class Photo < Sequel::Model # has `image_data` column
|
|
22
|
+
include ImageUploader::Attachment(:image) # adds methods, callbacks & validations
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
```rb
|
|
26
|
+
photo = Photo.new
|
|
27
|
+
|
|
28
|
+
photo.image = file # cache attachment
|
|
29
|
+
|
|
30
|
+
photo.image #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:cache ...>
|
|
31
|
+
photo.image_data #=> '{"id":"bc2e13.jpg","storage":"cache","metadata":{...}}'
|
|
32
|
+
|
|
33
|
+
photo.save # persist, promote attachment, then persist again
|
|
34
|
+
|
|
35
|
+
photo.image #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
|
|
36
|
+
photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
|
|
20
37
|
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
photo.destroy # delete attachment
|
|
39
|
+
|
|
40
|
+
photo.image.exists? #=> false
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Hooks
|
|
44
|
+
|
|
45
|
+
#### After Save
|
|
46
|
+
|
|
47
|
+
After a record is saved and the transaction is committed, `Attacher#finalize`
|
|
48
|
+
is called, which promotes cached file to permanent storage and deletes previous
|
|
49
|
+
file if any.
|
|
23
50
|
|
|
24
51
|
```rb
|
|
25
|
-
|
|
26
|
-
include ImageUploader::Attachment.new(:avatar)
|
|
52
|
+
photo = Photo.new
|
|
27
53
|
|
|
28
|
-
|
|
29
|
-
|
|
54
|
+
photo.image = file
|
|
55
|
+
photo.image.storage_key #=> :cache
|
|
30
56
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
57
|
+
photo.save
|
|
58
|
+
photo.image.storage_key #=> :store
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### After Destroy
|
|
62
|
+
|
|
63
|
+
After a record is destroyed and the transaction is committed,
|
|
64
|
+
`Attacher#destroy_attached` method is called, which deletes stored attached
|
|
65
|
+
file if any.
|
|
66
|
+
|
|
67
|
+
```rb
|
|
68
|
+
photo = Photo.find(photo_id)
|
|
69
|
+
photo.image #=> #<Shrine::UploadedFile>
|
|
70
|
+
photo.image.exists? #=> true
|
|
71
|
+
|
|
72
|
+
photo.destroy
|
|
73
|
+
photo.image.exists? #=> false
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Overriding hooks
|
|
77
|
+
|
|
78
|
+
You can override any of the following attacher methods to modify callback
|
|
79
|
+
behaviour:
|
|
80
|
+
|
|
81
|
+
* `Attacher#sequel_before_save`
|
|
82
|
+
* `Attacher#sequel_after_save`
|
|
83
|
+
* `Attacher#sequel_after_destroy`
|
|
84
|
+
|
|
85
|
+
```rb
|
|
86
|
+
class Shrine::Attacher
|
|
87
|
+
def sequel_after_save
|
|
88
|
+
super
|
|
89
|
+
# ...
|
|
36
90
|
end
|
|
37
91
|
end
|
|
38
92
|
```
|
|
39
93
|
|
|
40
|
-
|
|
41
|
-
|
|
94
|
+
#### Skipping Hooks
|
|
95
|
+
|
|
96
|
+
If you don't want the attachment module to add any hooks to your model, you can
|
|
97
|
+
set `:hooks` to `false`:
|
|
98
|
+
|
|
99
|
+
```rb
|
|
100
|
+
plugin :sequel, hooks: false
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Validations
|
|
104
|
+
|
|
105
|
+
If you're using the [`validation`][validation] plugin, the attachment module
|
|
106
|
+
will automatically merge attacher errors with model errors.
|
|
42
107
|
|
|
43
108
|
```rb
|
|
44
|
-
|
|
109
|
+
class ImageUploader < Shrine
|
|
110
|
+
plugin :validation_helpers
|
|
111
|
+
|
|
112
|
+
Attacher.validate do
|
|
113
|
+
validate_max_size 10 * 1024 * 1024
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
```
|
|
117
|
+
```rb
|
|
118
|
+
photo = Photo.new
|
|
119
|
+
photo.image = file
|
|
120
|
+
photo.valid?
|
|
121
|
+
photo.errors #=> { image: ["size must not be greater than 10.0 MB"] }
|
|
45
122
|
```
|
|
46
123
|
|
|
47
|
-
|
|
124
|
+
#### Attachment Presence
|
|
48
125
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
can do it directly on the model.
|
|
126
|
+
If you want to validate presence of the attachment, you can use Sequel's
|
|
127
|
+
presence validator:
|
|
52
128
|
|
|
53
129
|
```rb
|
|
54
|
-
class
|
|
55
|
-
include ImageUploader::Attachment
|
|
56
|
-
|
|
130
|
+
class Photo < Sequel::Model
|
|
131
|
+
include ImageUploader::Attachment(:image)
|
|
132
|
+
|
|
133
|
+
def validate
|
|
134
|
+
super
|
|
135
|
+
validates_presence :image
|
|
136
|
+
end
|
|
57
137
|
end
|
|
58
138
|
```
|
|
59
139
|
|
|
60
|
-
|
|
61
|
-
|
|
140
|
+
#### Skipping Validations
|
|
141
|
+
|
|
142
|
+
If don't want the attachment module to merge file validations errors into
|
|
143
|
+
model errors, you can set `:validations` to `false`:
|
|
62
144
|
|
|
63
145
|
```rb
|
|
64
146
|
plugin :sequel, validations: false
|
|
65
147
|
```
|
|
66
148
|
|
|
67
|
-
|
|
149
|
+
## Attacher
|
|
150
|
+
|
|
151
|
+
You can also use `Shrine::Attacher` directly (with or without the
|
|
152
|
+
`Shrine::Attachment` module):
|
|
153
|
+
|
|
154
|
+
```rb
|
|
155
|
+
class Photo < Sequel::Model # has `image_data` column
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
```rb
|
|
159
|
+
photo = Photo.new
|
|
160
|
+
attacher = ImageUploader::Attacher.from_model(photo, :image)
|
|
161
|
+
|
|
162
|
+
attacher.assign(file) # cache
|
|
163
|
+
|
|
164
|
+
attacher.file #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:cache ...>
|
|
165
|
+
photo.image_data #=> '{"id":"bc2e13.jpg","storage":"cache","metadata":{...}}'
|
|
166
|
+
|
|
167
|
+
photo.save # persist
|
|
168
|
+
attacher.finalize # promote
|
|
169
|
+
photo.save # persist
|
|
170
|
+
|
|
171
|
+
attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
|
|
172
|
+
photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Persistence
|
|
176
|
+
|
|
177
|
+
The following persistence methods are added to `Shrine::Attacher`:
|
|
178
|
+
|
|
179
|
+
| Method | Description |
|
|
180
|
+
| :----- | :---------- |
|
|
181
|
+
| `Attacher#atomic_promote` | calls `Attacher#promote` and persists if the attachment hasn't changed |
|
|
182
|
+
| `Attacher#atomic_persist` | saves changes if the attachment hasn't changed |
|
|
183
|
+
| `Attacher#persist` | saves any changes to the underlying record |
|
|
184
|
+
|
|
185
|
+
See [persistence] docs for more details.
|
|
186
|
+
|
|
187
|
+
[sequel]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/sequel.rb
|
|
188
|
+
[Sequel]: https://sequel.jeremyevans.net/
|
|
189
|
+
[model]: https://shrinerb.com/docs/plugins/model
|
|
190
|
+
[validation]: https://shrinerb.com/docs/plugins/validation
|
|
191
|
+
[persistence]: https://shrinerb.com/docs/plugins/persistence
|