shrine 2.19.4 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +485 -43
- data/LICENSE.txt +1 -1
- data/README.md +81 -977
- 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 +102 -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 +1115 -0
- data/doc/metadata.md +190 -109
- data/doc/multiple_files.md +62 -34
- 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 +162 -101
- data/doc/plugins/derivatives.md +829 -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 +14 -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 +185 -167
- 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 +4 -0
- 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/retrieving_uploads.md +4 -1
- 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 +117 -83
- data/doc/testing.md +124 -144
- data/doc/upgrading_to_3.md +710 -0
- data/doc/validation.md +54 -90
- data/lib/shrine/attacher.rb +287 -171
- 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 +89 -134
- data/lib/shrine/plugins/derivatives.rb +637 -0
- data/lib/shrine/plugins/determine_mime_type.rb +9 -21
- data/lib/shrine/plugins/download_endpoint.rb +109 -133
- data/lib/shrine/plugins/dynamic_storage.rb +5 -11
- data/lib/shrine/plugins/entity.rb +152 -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 +13 -20
- data/lib/shrine/plugins/instrumentation.rb +54 -42
- 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 +158 -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 +18 -22
- 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 +15 -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 +10 -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 +25 -23
- 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 +34 -57
- 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 +154 -158
- data/lib/shrine/uploaded_file.rb +28 -30
- data/lib/shrine/version.rb +3 -3
- data/lib/shrine.rb +86 -149
- data/shrine.gemspec +9 -10
- metadata +79 -83
- 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
|