shrine 3.2.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of shrine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/doc/attacher.md +2 -2
- data/doc/external/articles.md +56 -43
- data/doc/getting_started.md +9 -1
- data/doc/plugins/column.md +36 -7
- data/doc/plugins/default_url.md +3 -3
- data/doc/plugins/derivatives.md +10 -10
- data/doc/plugins/form_assign.md +5 -5
- data/doc/plugins/remote_url.md +6 -1
- data/doc/plugins/upload_endpoint.md +1 -1
- data/doc/plugins/upload_options.md +1 -1
- data/doc/plugins/validation.md +9 -0
- data/doc/plugins/versions.md +7 -7
- data/doc/processing.md +2 -3
- data/doc/release_notes/3.0.0.md +1 -1
- data/doc/release_notes/3.2.1.md +32 -0
- data/doc/securing_uploads.md +1 -1
- data/doc/storage/s3.md +9 -7
- data/lib/shrine.rb +4 -4
- data/lib/shrine/attachment.rb +2 -2
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/plugins/add_metadata.rb +1 -1
- data/lib/shrine/plugins/default_url.rb +1 -1
- data/lib/shrine/plugins/derivation_endpoint.rb +10 -6
- data/lib/shrine/plugins/derivatives.rb +4 -4
- data/lib/shrine/plugins/entity.rb +6 -6
- data/lib/shrine/plugins/model.rb +2 -2
- data/lib/shrine/plugins/presign_endpoint.rb +2 -2
- data/lib/shrine/plugins/pretty_location.rb +1 -1
- data/lib/shrine/plugins/processing.rb +1 -1
- data/lib/shrine/plugins/remote_url.rb +3 -3
- data/lib/shrine/plugins/upload_endpoint.rb +3 -3
- data/lib/shrine/plugins/upload_options.rb +2 -2
- data/lib/shrine/plugins/url_options.rb +2 -2
- data/lib/shrine/plugins/validation.rb +1 -1
- data/lib/shrine/storage/linter.rb +4 -4
- data/lib/shrine/storage/s3.rb +6 -2
- data/lib/shrine/version.rb +1 -1
- data/shrine.gemspec +6 -7
- metadata +16 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9762e59a3b310aecf9e4c2789e35df5b814826cf1db60e258faed44fdb1efe6
|
4
|
+
data.tar.gz: 857d1abbb026440d32e105cbbd248a89792e4f7b094b7e9509c2a735de32dfe0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b295b7d382c7e73384fcb69f3df1b049427ea2c40e5a84bd4505295cdc8e423aee7e8d76d7b153ecf7c5e0dbea6208d1a693448ee6e97037a9ebeff5fb9ebf46
|
7
|
+
data.tar.gz: 8263b3c88336b7ab9e7744ab3de1cae8cc00474af72e95d7c85fca96f89f900c6f347dc7ceaf440143ee5410bd7d00a8a85dab342644fb052ccdf81b974a185e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 3.2.1 (2020-01-12)
|
2
|
+
|
3
|
+
* `derivation_endpoint` – Use `Rack::Files` constant on Rack >= 2.1 (@janko)
|
4
|
+
|
5
|
+
* Fix Ruby 2.7 warnings regarding separation of positional and keyword arguments (@janko)
|
6
|
+
|
7
|
+
* `s3` – Make `S3#open` handle empty S3 objects (@janko)
|
8
|
+
|
1
9
|
## 3.2.0 (2019-12-17) [[release notes]](https://shrinerb.com/docs/release_notes/3.2.0)
|
2
10
|
|
3
11
|
* `validation` – Run validation on `Attacher#attach` & `Attacher#attach_cached` instead of `Attacher#change` (@janko)
|
data/doc/attacher.md
CHANGED
@@ -130,8 +130,8 @@ attacher.attach_cached(file)
|
|
130
130
|
|
131
131
|
# sets cached file
|
132
132
|
attacher.attach_cached('{"id":"asdf.jpg","storage":"cache","metadata":{...}}')
|
133
|
-
attacher.attach_cached("id" => "asdf.jpg", "storage" => "cache", "metadata" => { ... })
|
134
|
-
attacher.attach_cached(id: "asdf.jpg", storage: "cache", metadata: { ... })
|
133
|
+
attacher.attach_cached({ "id" => "asdf.jpg", "storage" => "cache", "metadata" => { ... } })
|
134
|
+
attacher.attach_cached({ id: "asdf.jpg", storage: "cache", metadata: { ... } })
|
135
135
|
|
136
136
|
# unsets attached file
|
137
137
|
attacher.attach_cached(nil)
|
data/doc/external/articles.md
CHANGED
@@ -4,49 +4,62 @@ title: Articles
|
|
4
4
|
|
5
5
|
## Official articles
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
7
|
+
| Article | Published |
|
8
|
+
| :------- | --------: |
|
9
|
+
| [Better File Uploads with Shrine: Eager Processing](https://twin.github.io/better-file-uploads-with-shrine-eager-processing) | 12 Dec 2019 |
|
10
|
+
| [Shrine 3.0 Released](https://twin.github.io/shrine-3-0-released/) | 14 Oct 2019 |
|
11
|
+
| [Upcoming Features in Shrine 3.0](https://twin.github.io/upcoming-features-in-shrine-3-0/) | 29 Aug 2019 |
|
12
|
+
| [Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads/) | 08 Jan 2018 |
|
13
|
+
| [Better File Uploads with Shrine: Metadata](https://twin.github.io/better-file-uploads-with-shrine-metadata/) | 07 Nov 2016 |
|
14
|
+
| [Better File Uploads with Shrine: Processing](https://twin.github.io/better-file-uploads-with-shrine-processing/) | 31 Oct 2016 |
|
15
|
+
| [Better File Uploads with Shrine: Attachment](https://twin.github.io/better-file-uploads-with-shrine-attachment/) | 17 Sep 2016 |
|
16
|
+
| [Better File Uploads with Shrine: Uploader](https://twin.github.io/better-file-uploads-with-shrine-uploader/) | 16 Sep 2016 |
|
17
|
+
| [Better File Uploads with Shrine: Motivation](https://twin.github.io/better-file-uploads-with-shrine-motivation/) | 11 Sep 2016 |
|
18
|
+
| [Resumable File Uploads in Ruby](https://twin.github.io/resumable-file-uploads-in-ruby/) | 04 Sep 2016 |
|
19
|
+
| [Shrine meets Transloadit](https://twin.github.io/shrine-meets-transloadit/) | 11 Jul 2016 |
|
20
|
+
| [Shrine 2.0 Released](https://twin.github.io/shrine-2-0-released/) | 20 May 2016 |
|
21
|
+
| [Asynchronous File Uploads](http://twin.github.io/file-uploads-asynchronous-world) | 18 Jan 2016 |
|
22
|
+
| [Introducing Shrine](http://twin.github.io/introducing-shrine) | 04 Oct 2015 |
|
22
23
|
|
23
24
|
## Other Articles
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
26
|
+
| Article | Published |
|
27
|
+
| :------ | --------: |
|
28
|
+
| [Microsoft Azure data storage library](https://syndicode.com/2019/12/17/microsoft-azure-data-storage-library-rewrite-the-existing-library-to-get-things-done/) | 17 Dec 2019 |
|
29
|
+
| [How to use REST clients / native apps to make Shrine client uploads and S3 work for you (no Javascript, just backend)](https://dev.to/rob117/how-to-use-rest-clients--native-apps-to-make-shrine-client-uploads-and-s3-work-for-you-no-javascript-just-backend-322h) | 16 Feb 2019 |
|
30
|
+
| [GraphQL file upload with Shrine](https://blog.stanko.io/graphql-file-upload-with-shrine-45fa26463c68) | 02 Jan 2019 |
|
31
|
+
| [Notes on study of shrine implementation](https://bibwild.wordpress.com/2018/09/12/notes-on-study-of-shrine-implementation/) | 12 Sep 2018 |
|
32
|
+
| [Happy users uploading files with Rails 5, Shrine, and Vue.js](https://itnext.io/happy-users-uploading-files-with-rails-5-shrine-and-vue-js-bbcc470a327f) | 04 Sep 2018 |
|
33
|
+
| [Rails 5 + Shrine + DropzoneJS](https://stephencodes.com/rails-5-shrine-dropzonejs/) | 20 Oct 2018 |
|
34
|
+
| [How to use Trix and Shrine for WYSIWYG Editing with Drag-and-Drop Image Uploading](http://headway.io/blog/how-to-use-trix-and-shrine-for-wysiwyg-editing-with-drag-and-drop-image-uploading/) | 26 Jan 2018 |
|
35
|
+
| [Store Your Files on S3: Uploading from a URL](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-3.html) | 28 Dec 2017 |
|
36
|
+
| [Store Your Files on S3: Direct Uploads](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-2.html) | 15 Dec 2017 |
|
37
|
+
| [Store Your Files on S3: Setup & Configuration](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-1.html) | 27 Nov 2017 |
|
38
|
+
| [Creating Streaming Radio With Rails and Icecast](https://scotch.io/tutorials/creating-online-streaming-radio-with-rails-and-icecast) | 06 Nov 2017 |
|
39
|
+
| [Multiple Photo Upload using Shrine](https://github.com/pyksoft/multi-photo-upload#multiple-photo-upload-using-shrine) | 02 Nov 2017 |
|
40
|
+
| [Uploading Files with Rails and ActionCable](https://scotch.io/tutorials/uploading-files-with-rails-and-actioncable) | 19 Oct 2017 |
|
41
|
+
| [Background file uploads to S3 using Shrine](https://elixirator.com/blog/background-file-uploads-to-s3-using-shrine/) | 21 Jul 2017 |
|
42
|
+
| [Upload images using Shrine.rb and Dropzone.js](https://codyeatworld.com/2017/04/18/rails-uploading-images-confidently-with-shrine-rb/) | 18 Apr 2017 |
|
43
|
+
| [Uploading Files With Rails and Shrine](https://code.tutsplus.com/tutorials/uploading-files-with-rails-and-shrine--cms-27596) | 26 Dec 2016 |
|
44
|
+
| [Rails File Uploading You Can Believe in with Shrine](http://www.sitepoint.com/rails-file-uploading-you-can-believe-in-with-shrine/) | 11 Apr 2016 |
|
45
|
+
| [Uploading files with Shrine in Hanami](http://katafrakt.me/2016/02/04/shrine-hanami-uploads/) | 04 Feb 2016 |
|
46
|
+
|
47
|
+
## Screencasts
|
48
|
+
|
49
|
+
| Screencast | Source | Published |
|
50
|
+
| :---- | :------ | --------: |
|
51
|
+
| [Uploading Files to DigitalOcean Spaces](https://gorails.com/episodes/digital-ocean-spaces-with-rails?autoplay=1) | GoRails | 31 Oct 2017 |
|
52
|
+
| [Trix WYSIWYG Editor And File Uploads](https://gorails.com/episodes/trix-editor?autoplay=1) | GoRails | 03 Oct 2017 |
|
53
|
+
| [Multiple File Uploads with Shrine](https://gorails.com/episodes/multiple-file-uploads-with-shrine?autoplay=1) | GoRails | 14 Dec 2016 |
|
54
|
+
| [Backgrounding and Video Transcoding](https://gorails.com/episodes/shrine-background-and-video-transcoding?autoplay=1) | GoRails | 03 Nov 2016 |
|
55
|
+
| [Direct File Uploads to S3: Part 3](https://gorails.com/episodes/direct-file-uploads-to-s3-part-3?autoplay=1) | GoRails | 05 Oct 2016 |
|
56
|
+
| [Direct File Uploads to S3: Part 2](https://gorails.com/episodes/direct-file-uploads-to-s3-part-2?autoplay=1) | GoRails | 05 Oct 2016 |
|
57
|
+
| [Direct File Uploads to S3: Part 1](https://gorails.com/episodes/direct-file-uploads-to-s3-part-1?autoplay=1) | GoRails | 05 Oct 2016 |
|
58
|
+
| [File Uploads in Rails with Shrine](https://gorails.com/episodes/file-uploading-with-shrine?autoplay=1) | GoRails | 23 Sep 2016 |
|
59
|
+
|
60
|
+
## Talks
|
61
|
+
|
62
|
+
| Talk | Source | Date |
|
63
|
+
| :---- | :------ | --------: |
|
64
|
+
| [Handling file uploads for a modern developer](https://www.youtube.com/watch?v=fP2JGjTZU2s) | wroc_love.rb | 24 Mar 2019 |
|
65
|
+
| [Shrine – Handle File Uploads like it's 2017](https://www.youtube.com/watch?v=plD-RkKEay0) | Melbourne Ruby | 27 Feb 2017 |
|
data/doc/getting_started.md
CHANGED
@@ -110,6 +110,14 @@ form @photo, action: "/photos", enctype: "multipart/form-data" do |f|
|
|
110
110
|
f.button "Create"
|
111
111
|
end
|
112
112
|
```
|
113
|
+
<!--HTML-->
|
114
|
+
```erb
|
115
|
+
<form action="/photos" method="post" enctype="multipart/form-data">
|
116
|
+
<input name="photo[image]" type="hidden" value="<%= @photo.cached_image_data %>" />
|
117
|
+
<input name="photo[image] "type="file" />
|
118
|
+
<input type="submit" value="Create" />
|
119
|
+
</form>
|
120
|
+
```
|
113
121
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
114
122
|
|
115
123
|
Note that the file field needs to go *after* the hidden field, so that
|
@@ -536,7 +544,7 @@ $ brew install imagemagick vips
|
|
536
544
|
|
537
545
|
### Eager processing
|
538
546
|
|
539
|
-
We can
|
547
|
+
We can use the [`derivatives`][derivatives plugin] plugin to generate a
|
540
548
|
pre-defined set of processed files (e.g. image thumbnails). We do this by
|
541
549
|
registering a derivatives processor block and then explicitly triggering
|
542
550
|
creation:
|
data/doc/plugins/column.md
CHANGED
@@ -66,23 +66,48 @@ If you want to load attachment from a Hash, use `Attacher.from_data` or
|
|
66
66
|
|
67
67
|
## Serializer
|
68
68
|
|
69
|
-
By default the `JSON` standard library is used
|
70
|
-
|
71
|
-
|
69
|
+
By default, the `JSON` standard library is used for serializing hash data. With
|
70
|
+
the [`model`][model] and [`entity`][entity] plugin, the data is serialized
|
71
|
+
before writing to and deserialized after reading from the data attribute.
|
72
|
+
|
73
|
+
You can also use your own serializer via the `:serializer` option. The
|
74
|
+
serializer object needs to implement `#dump` and `#load` methods:
|
75
|
+
|
76
|
+
```rb
|
77
|
+
class MyDataSerializer
|
78
|
+
def self.dump(data)
|
79
|
+
data #=> { "id" => "...", "storage" => "...", "metadata" => { ... } }
|
80
|
+
|
81
|
+
JSON.generate(data) # serialize data, e.g. into JSON
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.load(data)
|
85
|
+
data #=> '{"id":"...", "storage":"...", "metadata": {...}}'
|
86
|
+
|
87
|
+
JSON.parse(data) # deserialize data, e.g. from JSON
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
plugin :column, serializer: MyDataSerializer
|
92
|
+
```
|
93
|
+
|
94
|
+
Some serialization libraries such as [Oj] and [MessagePack] already implement
|
95
|
+
this interface, which simplifies the configuration:
|
72
96
|
|
73
97
|
```rb
|
74
|
-
require "oj"
|
98
|
+
require "oj" # https://github.com/ohler55/oj
|
75
99
|
|
76
|
-
plugin :column, serializer: Oj
|
100
|
+
plugin :column, serializer: Oj
|
77
101
|
```
|
78
102
|
|
79
|
-
If you want to disable serialization, you can set
|
103
|
+
If you want to disable serialization and work with hashes directly, you can set
|
104
|
+
`:serializer` to `nil`:
|
80
105
|
|
81
106
|
```rb
|
82
107
|
plugin :column, serializer: nil # disable serialization
|
83
108
|
```
|
84
109
|
|
85
|
-
|
110
|
+
The serializer can also be changed for a particular attacher instance:
|
86
111
|
|
87
112
|
```rb
|
88
113
|
Shrine::Attacher.new(column_serializer: Oj) # use custom serializer
|
@@ -90,3 +115,7 @@ Shrine::Attacher.new(column_serializer: nil) # disable serialization
|
|
90
115
|
```
|
91
116
|
|
92
117
|
[column]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/column.rb
|
118
|
+
[model]: https://shrinerb.com/docs/plugins/model
|
119
|
+
[entity]: https://shrinerb.com/docs/plugins/entity
|
120
|
+
[Oj]: https://github.com/ohler55/oj
|
121
|
+
[MessagePack]: https://github.com/msgpack/msgpack-ruby
|
data/doc/plugins/default_url.md
CHANGED
@@ -8,7 +8,7 @@ returned when there is no attached file.
|
|
8
8
|
```rb
|
9
9
|
plugin :default_url
|
10
10
|
|
11
|
-
Attacher.default_url do
|
11
|
+
Attacher.default_url do |**options|
|
12
12
|
"/#{name}/missing.jpg"
|
13
13
|
end
|
14
14
|
```
|
@@ -28,7 +28,7 @@ Any URL options passed will be available in the default URL block:
|
|
28
28
|
attacher.url(foo: "bar")
|
29
29
|
```
|
30
30
|
```rb
|
31
|
-
Attacher.default_url do
|
31
|
+
Attacher.default_url do |**options|
|
32
32
|
options #=> { foo: "bar" }
|
33
33
|
end
|
34
34
|
```
|
@@ -37,7 +37,7 @@ The default URL block is evaluated in the context of an instance of
|
|
37
37
|
`Shrine::Attacher`.
|
38
38
|
|
39
39
|
```rb
|
40
|
-
Attacher.default_url do
|
40
|
+
Attacher.default_url do |**options|
|
41
41
|
self #=> #<Shrine::Attacher>
|
42
42
|
|
43
43
|
file #=> #<Shrine::UploadedFile>
|
data/doc/plugins/derivatives.md
CHANGED
@@ -422,11 +422,11 @@ If you already have processed files that you want to save, you can do that with
|
|
422
422
|
`Attacher#add_derivatives`:
|
423
423
|
|
424
424
|
```rb
|
425
|
-
attacher.add_derivatives(
|
425
|
+
attacher.add_derivatives({
|
426
426
|
one: file_1,
|
427
427
|
two: file_2,
|
428
428
|
# ...
|
429
|
-
)
|
429
|
+
})
|
430
430
|
|
431
431
|
attacher.derivatives #=>
|
432
432
|
# {
|
@@ -440,7 +440,7 @@ New derivatives will be merged with existing ones:
|
|
440
440
|
|
441
441
|
```rb
|
442
442
|
attacher.derivatives #=> { one: #<Shrine::UploadedFile> }
|
443
|
-
attacher.add_derivatives(two: two_file)
|
443
|
+
attacher.add_derivatives({ two: two_file })
|
444
444
|
attacher.derivatives #=> { one: #<Shrine::UploadedFile>, two: #<Shrine::UploadedFile> }
|
445
445
|
```
|
446
446
|
|
@@ -448,7 +448,7 @@ The merging is deep, so the following will work as well:
|
|
448
448
|
|
449
449
|
```rb
|
450
450
|
attacher.derivatives #=> { nested: { one: #<Shrine::UploadedFile> } }
|
451
|
-
attacher.add_derivatives(nested: { two: two_file })
|
451
|
+
attacher.add_derivatives({ nested: { two: two_file } })
|
452
452
|
attacher.derivatives #=> { nested: { one: #<Shrine::UploadedFile>, two: #<Shrine::UploadedFile> } }
|
453
453
|
```
|
454
454
|
|
@@ -475,11 +475,11 @@ If you want to upload processed files without setting them, you can use
|
|
475
475
|
`Attacher#upload_derivatives`:
|
476
476
|
|
477
477
|
```rb
|
478
|
-
derivatives = attacher.upload_derivatives(
|
478
|
+
derivatives = attacher.upload_derivatives({
|
479
479
|
one: file_1,
|
480
480
|
two: file_2,
|
481
481
|
# ...
|
482
|
-
)
|
482
|
+
})
|
483
483
|
|
484
484
|
derivatives #=>
|
485
485
|
# {
|
@@ -555,7 +555,7 @@ If you want to save already uploaded derivatives, you can use
|
|
555
555
|
|
556
556
|
```rb
|
557
557
|
attacher.derivatives #=> { one: #<Shrine::UploadedFile> }
|
558
|
-
attacher.merge_derivatives attacher.upload_derivatives(two: two_file)
|
558
|
+
attacher.merge_derivatives attacher.upload_derivatives({ two: two_file })
|
559
559
|
attacher.derivatives #=> { one: #<Shrine::UploadedFile>, two: #<Shrine::UploadedFile> }
|
560
560
|
```
|
561
561
|
|
@@ -563,7 +563,7 @@ This does a deep merge, so the following will work as well:
|
|
563
563
|
|
564
564
|
```rb
|
565
565
|
attacher.derivatives #=> { nested: { one: #<Shrine::UploadedFile> } }
|
566
|
-
attacher.merge_derivatives attacher.upload_derivatives(nested: { two: two_file })
|
566
|
+
attacher.merge_derivatives attacher.upload_derivatives({ nested: { two: two_file } })
|
567
567
|
attacher.derivatives #=> { nested: { one: #<Shrine::UploadedFile>, two: #<Shrine::UploadedFile> } }
|
568
568
|
```
|
569
569
|
|
@@ -576,7 +576,7 @@ If instead of adding you want to *override* existing derivatives, you can use
|
|
576
576
|
|
577
577
|
```rb
|
578
578
|
attacher.derivatives #=> { one: #<Shrine::UploadedFile> }
|
579
|
-
attacher.set_derivatives attacher.upload_derivatives(two: two_file)
|
579
|
+
attacher.set_derivatives attacher.upload_derivatives({ two: two_file })
|
580
580
|
attacher.derivatives #=> { two: #<Shrine::UploadedFile> }
|
581
581
|
```
|
582
582
|
|
@@ -684,7 +684,7 @@ You can store derivatives even if there is no main attached file:
|
|
684
684
|
|
685
685
|
```rb
|
686
686
|
attacher.file #=> nil
|
687
|
-
attacher.add_derivatives(one: one_file, two: two_file)
|
687
|
+
attacher.add_derivatives({ one: one_file, two: two_file })
|
688
688
|
attacher.data #=>
|
689
689
|
# {
|
690
690
|
# "derivatives" => {
|
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/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:
|
@@ -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
|
```
|
@@ -13,7 +13,7 @@ Keys are names of the registered storages, and values are either hashes or
|
|
13
13
|
blocks.
|
14
14
|
|
15
15
|
```rb
|
16
|
-
plugin :upload_options, store: -> (io,
|
16
|
+
plugin :upload_options, store: -> (io, options) do
|
17
17
|
if options[:derivative]
|
18
18
|
{ acl: "public-read" }
|
19
19
|
else
|
data/doc/plugins/validation.md
CHANGED
@@ -84,5 +84,14 @@ You can also skip validation by passing `validate: false`:
|
|
84
84
|
attacher.assign(file, validate: false) # skips validation
|
85
85
|
```
|
86
86
|
|
87
|
+
## Manual validation
|
88
|
+
|
89
|
+
You can also run validation manually via `Attacher#validate`:
|
90
|
+
|
91
|
+
```rb
|
92
|
+
attacher.set(uploaded_file) # doesn't trigger validation
|
93
|
+
attacher.validate # runs validation
|
94
|
+
```
|
95
|
+
|
87
96
|
[validation]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/validation.rb
|
88
97
|
[validation_helpers]: https://shrinerb.com/docs/plugins/validation_helpers
|
data/doc/plugins/versions.md
CHANGED
@@ -17,7 +17,7 @@ require "image_processing/mini_magick"
|
|
17
17
|
|
18
18
|
plugin :processing
|
19
19
|
|
20
|
-
process(:store) do |io,
|
20
|
+
process(:store) do |io, **options|
|
21
21
|
versions = { original: io } # retain original
|
22
22
|
|
23
23
|
io.download do |original|
|
@@ -120,7 +120,7 @@ In addition to Hashes, the plugin also supports Arrays of files. For example,
|
|
120
120
|
you might want to split a PDf into pages:
|
121
121
|
|
122
122
|
```rb
|
123
|
-
process(:store) do |io,
|
123
|
+
process(:store) do |io, **options|
|
124
124
|
versions = { pages: [] }
|
125
125
|
|
126
126
|
io.download do |pdf|
|
@@ -146,7 +146,7 @@ which you can do by adding the yielded `Shrine::UploadedFile` object as one of
|
|
146
146
|
the versions, by convention named `:original`:
|
147
147
|
|
148
148
|
```rb
|
149
|
-
process(:store) do |io,
|
149
|
+
process(:store) do |io, **options|
|
150
150
|
# processing thumbnail
|
151
151
|
{ original: io, thumbnail: thumbnail }
|
152
152
|
end
|
@@ -163,12 +163,12 @@ The version name will be available via `:version` when generating location or a
|
|
163
163
|
default URL.
|
164
164
|
|
165
165
|
```rb
|
166
|
-
def generate_location(io,
|
167
|
-
"uploads/#{
|
166
|
+
def generate_location(io, version: nil, **)
|
167
|
+
"uploads/#{version}-#{super}"
|
168
168
|
end
|
169
169
|
|
170
|
-
Attacher.default_url do |
|
171
|
-
"/images/defaults/#{
|
170
|
+
Attacher.default_url do |version: nil, **|
|
171
|
+
"/images/defaults/#{version}.jpg"
|
172
172
|
end
|
173
173
|
```
|
174
174
|
|
data/doc/processing.md
CHANGED
@@ -114,9 +114,8 @@ Attacher.derivatives do |original|
|
|
114
114
|
end
|
115
115
|
```
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
methods for that.
|
117
|
+
The [`type_predicates`][type_predicates] plugin provides convenient predicate
|
118
|
+
methods for branching based on the file type.
|
120
119
|
|
121
120
|
### Backgrounding
|
122
121
|
|
data/doc/release_notes/3.0.0.md
CHANGED
@@ -366,7 +366,7 @@ end
|
|
366
366
|
```
|
367
367
|
```rb
|
368
368
|
attacher = photo.image_attacher
|
369
|
-
attacher.form_assign("image" => file, "title" => "...", "description" => "...")
|
369
|
+
attacher.form_assign({ "image" => file, "title" => "...", "description" => "..." })
|
370
370
|
attacher.file #=> #<Shrine::UploadedFile id="..." storage=:cache ...>
|
371
371
|
```
|
372
372
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
title: Shrine 3.2.1
|
3
|
+
---
|
4
|
+
|
5
|
+
## Ruby 2.7 compatibility
|
6
|
+
|
7
|
+
* Shrine doesn't trigger [Ruby 2.7 warnings for separation of positional and
|
8
|
+
keyword arguments][kwargs] anymore.
|
9
|
+
|
10
|
+
* Down 5.1.0 has been released, which resolves warnings and a `FrozenError`
|
11
|
+
exception on Ruby 2.7. Shrine now requires at least this version of Down.
|
12
|
+
|
13
|
+
If you're using `Down::Http`, make sure you're using http.rb 4.3.0 or newer.
|
14
|
+
|
15
|
+
* ImageProcessing 1.10.3 gem has been released which resolves Ruby 2.7 warnings
|
16
|
+
as well. If you're using it for image processing, make sure to upgrade to
|
17
|
+
this version:
|
18
|
+
|
19
|
+
```rb
|
20
|
+
gem "image_processing", ">= 1.10.3", "< 2"
|
21
|
+
```
|
22
|
+
|
23
|
+
## Rack 2.1.0 compatibility
|
24
|
+
|
25
|
+
* The `derivation_endpoint` plugin now uses `Rack::Files` on Rack 2.1.0 or
|
26
|
+
newer.
|
27
|
+
|
28
|
+
## Other improvements
|
29
|
+
|
30
|
+
* The `S3#open` method now handles empty S3 objects.
|
31
|
+
|
32
|
+
[kwargs]: https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
|
data/doc/securing_uploads.md
CHANGED
@@ -63,7 +63,7 @@ in the `:max_size` option to reject files that are larger than the specified
|
|
63
63
|
limit:
|
64
64
|
|
65
65
|
```rb
|
66
|
-
plugin :upload_endpoint, max_size: 100*1024*1024 #
|
66
|
+
plugin :upload_endpoint, max_size: 100*1024*1024 # 100 MB
|
67
67
|
```
|
68
68
|
|
69
69
|
If you're doing direct uploads to Amazon S3 using the `presign_endpoint`
|
data/doc/storage/s3.md
CHANGED
@@ -27,13 +27,15 @@ s3 = Shrine::Storage::S3.new(
|
|
27
27
|
)
|
28
28
|
```
|
29
29
|
|
30
|
-
The
|
31
|
-
|
30
|
+
> The storage requires the following AWS S3 permissions:
|
31
|
+
>
|
32
|
+
> * `s3:ListBucket` for the bucket resource
|
33
|
+
> * `s3:GetObject`, `s3:PutObject`, `s3:PutObjectAcl`, `s3:DeleteObject`,
|
34
|
+
> `s3:ListMultipartUploadParts` and `s3:AbortMultipartUpload` for the object
|
35
|
+
> resources
|
32
36
|
|
33
|
-
> The
|
34
|
-
|
35
|
-
have additional upload options configured such as setting object ACLs, then
|
36
|
-
additional permissions may be required.
|
37
|
+
> The `:access_key_id` and `:secret_access_key` options is just one form of
|
38
|
+
> authentication, see the [AWS SDK docs][credentials] for more options.
|
37
39
|
|
38
40
|
The storage exposes the underlying Aws objects:
|
39
41
|
|
@@ -312,7 +314,7 @@ s3.clear! { |object| object.last_modified < Time.now - 7*24*60*60 }
|
|
312
314
|
[object lifecycle]: http://docs.aws.amazon.com/AmazonS3/latest/UG/lifecycle-configuration-bucket-no-versioning.html
|
313
315
|
[serve private content via CloudFront]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
|
314
316
|
[`Aws::CloudFront::UrlSigner`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CloudFront/UrlSigner.html
|
315
|
-
[
|
317
|
+
[credentials]: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html
|
316
318
|
[`Aws::S3::Object#presigned_post`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_post-instance_method
|
317
319
|
[`Aws::S3::Object#presigned_url`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method
|
318
320
|
[#348]: https://github.com/shrinerb/shrine/issues/348
|
data/lib/shrine.rb
CHANGED
@@ -68,9 +68,9 @@ class Shrine
|
|
68
68
|
#
|
69
69
|
# Shrine.plugin MyPlugin
|
70
70
|
# Shrine.plugin :my_plugin
|
71
|
-
def plugin(plugin, *args, &block)
|
71
|
+
def plugin(plugin, *args, **kwargs, &block)
|
72
72
|
plugin = Plugins.load_plugin(plugin) if plugin.is_a?(Symbol)
|
73
|
-
|
73
|
+
Plugins.load_dependencies(plugin, self, *args, **kwargs, &block)
|
74
74
|
self.include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
|
75
75
|
self.extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
|
76
76
|
self::UploadedFile.include(plugin::FileMethods) if defined?(plugin::FileMethods)
|
@@ -79,7 +79,7 @@ class Shrine
|
|
79
79
|
self::Attachment.extend(plugin::AttachmentClassMethods) if defined?(plugin::AttachmentClassMethods)
|
80
80
|
self::Attacher.include(plugin::AttacherMethods) if defined?(plugin::AttacherMethods)
|
81
81
|
self::Attacher.extend(plugin::AttacherClassMethods) if defined?(plugin::AttacherClassMethods)
|
82
|
-
|
82
|
+
Plugins.configure(plugin, self, *args, **kwargs, &block)
|
83
83
|
plugin
|
84
84
|
end
|
85
85
|
|
@@ -297,7 +297,7 @@ class Shrine
|
|
297
297
|
# Retrieves the location for the given IO and context. First it looks
|
298
298
|
# for the `:location` option, otherwise it calls #generate_location.
|
299
299
|
def get_location(io, location: nil, **options)
|
300
|
-
location ||= generate_location(io, options)
|
300
|
+
location ||= generate_location(io, **options)
|
301
301
|
location or fail Error, "location generated for #{io.inspect} was nil"
|
302
302
|
end
|
303
303
|
|
data/lib/shrine/attachment.rb
CHANGED
data/lib/shrine/plugins.rb
CHANGED
@@ -18,6 +18,28 @@ class Shrine
|
|
18
18
|
plugin
|
19
19
|
end
|
20
20
|
|
21
|
+
# Delegate call to the plugin in a way that works across Ruby versions.
|
22
|
+
def self.load_dependencies(plugin, uploader, *args, **kwargs, &block)
|
23
|
+
return unless plugin.respond_to?(:load_dependencies)
|
24
|
+
|
25
|
+
if kwargs.any?
|
26
|
+
plugin.load_dependencies(uploader, *args, **kwargs, &block)
|
27
|
+
else
|
28
|
+
plugin.load_dependencies(uploader, *args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Delegate call to the plugin in a way that works across Ruby versions.
|
33
|
+
def self.configure(plugin, uploader, *args, **kwargs, &block)
|
34
|
+
return unless plugin.respond_to?(:configure)
|
35
|
+
|
36
|
+
if kwargs.any?
|
37
|
+
plugin.configure(uploader, *args, **kwargs, &block)
|
38
|
+
else
|
39
|
+
plugin.configure(uploader, *args, &block)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
21
43
|
# Register the given plugin with Shrine, so that it can be loaded using
|
22
44
|
# `Shrine.plugin` with a symbol. Should be used by plugin files. Example:
|
23
45
|
#
|
@@ -41,7 +41,7 @@ class Shrine
|
|
41
41
|
|
42
42
|
def extract_custom_metadata(io, **options)
|
43
43
|
opts[:add_metadata][:definitions].each do |name, block|
|
44
|
-
result = instance_exec(io, options, &block)
|
44
|
+
result = instance_exec(io, **options, &block)
|
45
45
|
|
46
46
|
if name
|
47
47
|
options[:metadata].merge! name.to_s => result
|
@@ -475,9 +475,9 @@ class Shrine
|
|
475
475
|
file_response(derivative, env)
|
476
476
|
end
|
477
477
|
|
478
|
-
# Generates a Rack response triple from a local file
|
479
|
-
#
|
480
|
-
#
|
478
|
+
# Generates a Rack response triple from a local file. Fills in
|
479
|
+
# `Content-Type` and `Content-Disposition` response headers from derivation
|
480
|
+
# options and file extension of the derivation result.
|
481
481
|
def file_response(file, env)
|
482
482
|
response = rack_file_response(file.path, env)
|
483
483
|
|
@@ -511,7 +511,7 @@ class Shrine
|
|
511
511
|
end
|
512
512
|
|
513
513
|
if upload_redirect
|
514
|
-
redirect_url = uploaded_file.url(upload_redirect_url_options)
|
514
|
+
redirect_url = uploaded_file.url(**upload_redirect_url_options)
|
515
515
|
|
516
516
|
[302, { "Location" => redirect_url }, []]
|
517
517
|
else
|
@@ -528,10 +528,14 @@ class Shrine
|
|
528
528
|
end
|
529
529
|
end
|
530
530
|
|
531
|
-
# We call `Rack::
|
531
|
+
# We call `Rack::Files` with no default `Content-Type`, and make sure we
|
532
532
|
# stay compatible with both Rack 2.x and 1.6.x.
|
533
533
|
def rack_file_response(path, env)
|
534
|
-
|
534
|
+
if Rack.release >= "2.1"
|
535
|
+
server = Rack::Files.new("", {}, nil)
|
536
|
+
else
|
537
|
+
server = Rack::File.new("", {}, nil)
|
538
|
+
end
|
535
539
|
|
536
540
|
if Rack.release > "2"
|
537
541
|
server.serving(Rack::Request.new(env), path)
|
@@ -40,8 +40,8 @@ class Shrine
|
|
40
40
|
def define_model_methods(name)
|
41
41
|
super if defined?(super)
|
42
42
|
|
43
|
-
define_method(:"#{name}_derivatives!") do |*args|
|
44
|
-
send(:"#{name}_attacher").create_derivatives(*args)
|
43
|
+
define_method(:"#{name}_derivatives!") do |*args, **options|
|
44
|
+
send(:"#{name}_attacher").create_derivatives(*args, **options)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -462,8 +462,8 @@ class Shrine
|
|
462
462
|
# Iterates through nested derivatives and maps results.
|
463
463
|
#
|
464
464
|
# attacher.map_derivative(derivatives) { |path, file| ... }
|
465
|
-
def map_derivative(
|
466
|
-
shrine_class.map_derivative(
|
465
|
+
def map_derivative(derivatives, **options, &block)
|
466
|
+
shrine_class.map_derivative(derivatives, **options, &block)
|
467
467
|
end
|
468
468
|
|
469
469
|
private
|
@@ -41,27 +41,27 @@ class Shrine
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# Returns the URL to the attached file.
|
44
|
-
define_method :"#{name}_url" do |*args|
|
45
|
-
send(:"#{name}_attacher").url(*args)
|
44
|
+
define_method :"#{name}_url" do |*args, **options|
|
45
|
+
send(:"#{name}_attacher").url(*args, **options)
|
46
46
|
end
|
47
47
|
|
48
48
|
# Returns an attacher instance.
|
49
49
|
define_method :"#{name}_attacher" do |**options|
|
50
|
-
attachment.send(:attacher, self, options)
|
50
|
+
attachment.send(:attacher, self, **options)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
# Returns the class attacher instance with loaded entity. It's not
|
55
55
|
# memoized because the entity object could be frozen.
|
56
|
-
def attacher(record, options)
|
57
|
-
attacher = class_attacher(options)
|
56
|
+
def attacher(record, **options)
|
57
|
+
attacher = class_attacher(**options)
|
58
58
|
attacher.load_entity(record, @name)
|
59
59
|
attacher
|
60
60
|
end
|
61
61
|
|
62
62
|
# Creates an instance of the corresponding attacher class with set
|
63
63
|
# name.
|
64
|
-
def class_attacher(options)
|
64
|
+
def class_attacher(**options)
|
65
65
|
attacher = shrine_class::Attacher.new(**@options, **options)
|
66
66
|
attacher.instance_variable_set(:@name, @name)
|
67
67
|
attacher
|
data/lib/shrine/plugins/model.rb
CHANGED
@@ -55,11 +55,11 @@ class Shrine
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Memoizes the attacher instance into an instance variable.
|
58
|
-
def attacher(record, options)
|
58
|
+
def attacher(record, **options)
|
59
59
|
return super unless model?
|
60
60
|
|
61
61
|
if !record.instance_variable_get(:"@#{@name}_attacher") || options.any?
|
62
|
-
attacher = class_attacher(options)
|
62
|
+
attacher = class_attacher(**options)
|
63
63
|
attacher.load_model(record, @name)
|
64
64
|
|
65
65
|
record.instance_variable_set(:"@#{@name}_attacher", attacher)
|
@@ -8,7 +8,7 @@ class Shrine
|
|
8
8
|
module Plugins
|
9
9
|
# Documentation can be found on https://shrinerb.com/docs/plugins/presign_endpoint
|
10
10
|
module PresignEndpoint
|
11
|
-
def self.configure(uploader, opts
|
11
|
+
def self.configure(uploader, **opts)
|
12
12
|
uploader.opts[:presign_endpoint] ||= {}
|
13
13
|
uploader.opts[:presign_endpoint].merge!(opts)
|
14
14
|
end
|
@@ -135,7 +135,7 @@ class Shrine
|
|
135
135
|
if @presign
|
136
136
|
data = @presign.call(location, options, request)
|
137
137
|
else
|
138
|
-
data = storage.presign(location, options)
|
138
|
+
data = storage.presign(location, **options)
|
139
139
|
end
|
140
140
|
|
141
141
|
{ fields: {}, headers: {} }.merge(data.to_h)
|
@@ -11,7 +11,7 @@ class Shrine
|
|
11
11
|
|
12
12
|
module InstanceMethods
|
13
13
|
def generate_location(io, **options)
|
14
|
-
pretty_location(io, options)
|
14
|
+
pretty_location(io, **options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def pretty_location(io, name: nil, record: nil, version: nil, derivative: nil, identifier: nil, metadata: {}, **)
|
@@ -33,7 +33,7 @@ class Shrine
|
|
33
33
|
def process(io, **options)
|
34
34
|
pipeline = processing_pipeline(options[:action])
|
35
35
|
pipeline.inject(io) do |input, processor|
|
36
|
-
instance_exec(input, options, &processor) || input
|
36
|
+
instance_exec(input, **options, &processor) || input
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -16,7 +16,7 @@ class Shrine
|
|
16
16
|
}.inspect}"
|
17
17
|
end
|
18
18
|
|
19
|
-
DOWNLOADER = -> (url, options) { Down.download(url, options) }
|
19
|
+
DOWNLOADER = -> (url, **options) { Down.download(url, **options) }
|
20
20
|
|
21
21
|
def self.load_dependencies(uploader, *)
|
22
22
|
uploader.plugin :validation
|
@@ -63,7 +63,7 @@ class Shrine
|
|
63
63
|
private
|
64
64
|
|
65
65
|
def download_remote_url(url, options)
|
66
|
-
opts[:remote_url][:downloader].call(url, options)
|
66
|
+
opts[:remote_url][:downloader].call(url, **options)
|
67
67
|
rescue Down::TooLarge
|
68
68
|
fail DownloadError, "remote file too large"
|
69
69
|
rescue Down::Error
|
@@ -87,7 +87,7 @@ class Shrine
|
|
87
87
|
def assign_remote_url(url, downloader: {}, **options)
|
88
88
|
return if url == "" || url.nil?
|
89
89
|
|
90
|
-
downloaded_file = shrine_class.remote_url(url, downloader)
|
90
|
+
downloaded_file = shrine_class.remote_url(url, **downloader)
|
91
91
|
attach_cached(downloaded_file, **options)
|
92
92
|
rescue DownloadError => error
|
93
93
|
errors.clear << remote_url_error_message(url, error)
|
@@ -9,11 +9,11 @@ class Shrine
|
|
9
9
|
module Plugins
|
10
10
|
# Documentation can be found on https://shrinerb.com/docs/plugins/upload_endpoint
|
11
11
|
module UploadEndpoint
|
12
|
-
def self.load_dependencies(uploader,
|
12
|
+
def self.load_dependencies(uploader, **)
|
13
13
|
uploader.plugin :rack_file
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.configure(uploader, opts
|
16
|
+
def self.configure(uploader, **opts)
|
17
17
|
uploader.opts[:upload_endpoint] ||= {}
|
18
18
|
uploader.opts[:upload_endpoint].merge!(opts)
|
19
19
|
end
|
@@ -156,7 +156,7 @@ class Shrine
|
|
156
156
|
if @upload
|
157
157
|
@upload.call(io, context, request)
|
158
158
|
else
|
159
|
-
uploader.upload(io, context)
|
159
|
+
uploader.upload(io, **context)
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
@@ -4,9 +4,9 @@ class Shrine
|
|
4
4
|
module Plugins
|
5
5
|
# Documentation can be found on https://shrinerb.com/docs/plugins/upload_options
|
6
6
|
module UploadOptions
|
7
|
-
def self.configure(uploader,
|
7
|
+
def self.configure(uploader, **opts)
|
8
8
|
uploader.opts[:upload_options] ||= {}
|
9
|
-
uploader.opts[:upload_options].merge!(
|
9
|
+
uploader.opts[:upload_options].merge!(opts)
|
10
10
|
end
|
11
11
|
|
12
12
|
module InstanceMethods
|
@@ -4,9 +4,9 @@ class Shrine
|
|
4
4
|
module Plugins
|
5
5
|
# Documentation can be found on https://shrinerb.com/docs/plugins/url_options
|
6
6
|
module UrlOptions
|
7
|
-
def self.configure(uploader, **
|
7
|
+
def self.configure(uploader, **opts)
|
8
8
|
uploader.opts[:url_options] ||= {}
|
9
|
-
uploader.opts[:url_options].merge!(
|
9
|
+
uploader.opts[:url_options].merge!(opts)
|
10
10
|
end
|
11
11
|
|
12
12
|
module FileMethods
|
@@ -54,7 +54,7 @@ class Shrine
|
|
54
54
|
# Calls validation appropriately based on the :validate value.
|
55
55
|
def validation(argument)
|
56
56
|
case argument
|
57
|
-
when Hash then validate(argument)
|
57
|
+
when Hash then validate(**argument)
|
58
58
|
when false then errors.clear # skip validation
|
59
59
|
else validate
|
60
60
|
end
|
@@ -35,7 +35,7 @@ class Shrine
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def call(io_factory = default_io_factory)
|
38
|
-
storage.upload(io_factory.call, id = "foo", {})
|
38
|
+
storage.upload(io_factory.call, id = "foo", shrine_metadata: { "foo" => "bar" })
|
39
39
|
|
40
40
|
lint_open(id)
|
41
41
|
lint_exists(id)
|
@@ -67,13 +67,13 @@ class Shrine
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def lint_open(id)
|
70
|
-
opened = storage.open(id
|
70
|
+
opened = storage.open(id)
|
71
71
|
error :open, "doesn't return a valid IO object" if !io?(opened)
|
72
72
|
error :open, "returns an empty IO object" if opened.read.empty?
|
73
73
|
opened.close
|
74
74
|
|
75
75
|
begin
|
76
|
-
storage.open(@nonexisting
|
76
|
+
storage.open(@nonexisting)
|
77
77
|
error :open, "should raise an exception on nonexisting file"
|
78
78
|
rescue Shrine::FileNotFound
|
79
79
|
rescue => exception
|
@@ -107,7 +107,7 @@ class Shrine
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def lint_presign(id)
|
110
|
-
data = storage.presign(id
|
110
|
+
data = storage.presign(id)
|
111
111
|
error :presign, "result should be a Hash" unless data.respond_to?(:to_h)
|
112
112
|
error :presign, "result should include :method key" unless data.to_h.key?(:method)
|
113
113
|
error :presign, "result should include :url key" unless data.to_h.key?(:url)
|
data/lib/shrine/storage/s3.rb
CHANGED
@@ -282,10 +282,14 @@ class Shrine
|
|
282
282
|
# Aws::S3::Object#get doesn't allow us to get the content length of the
|
283
283
|
# object before the content is downloaded, so we hack our way around it.
|
284
284
|
def get_object(object, params)
|
285
|
-
req = client.build_request(:get_object,
|
285
|
+
req = client.build_request(:get_object, bucket: bucket.name, key: object.key, **params)
|
286
286
|
|
287
287
|
body = req.enum_for(:send_request)
|
288
|
-
|
288
|
+
begin
|
289
|
+
body.peek # start the request
|
290
|
+
rescue StopIteration
|
291
|
+
# the S3 object is empty
|
292
|
+
end
|
289
293
|
|
290
294
|
content_length = Integer(req.context.http_response.headers["Content-Length"])
|
291
295
|
chunks = Enumerator.new { |y| loop { y << body.next } }
|
data/lib/shrine/version.rb
CHANGED
data/shrine.gemspec
CHANGED
@@ -33,18 +33,17 @@ direct uploads for fully asynchronous user experience.
|
|
33
33
|
gem.files = Dir["README.md", "LICENSE.txt", "CHANGELOG.md", "lib/**/*.rb", "shrine.gemspec", "doc/**/*.md"]
|
34
34
|
gem.require_path = "lib"
|
35
35
|
|
36
|
-
gem.add_dependency "down", "~> 5.
|
36
|
+
gem.add_dependency "down", "~> 5.1"
|
37
37
|
gem.add_dependency "content_disposition", "~> 1.0"
|
38
38
|
|
39
39
|
# general testing helpers
|
40
40
|
gem.add_development_dependency "rake", ">= 11.1"
|
41
41
|
gem.add_development_dependency "minitest", "~> 5.8"
|
42
|
-
gem.add_development_dependency "mocha", "~> 1.
|
43
|
-
gem.add_development_dependency "dry-initializer"
|
42
|
+
gem.add_development_dependency "mocha", "~> 1.11"
|
44
43
|
|
45
44
|
# for endpoint plugins
|
46
45
|
gem.add_development_dependency "rack", "~> 2.0"
|
47
|
-
gem.add_development_dependency "http-form_data", "~> 2.
|
46
|
+
gem.add_development_dependency "http-form_data", "~> 2.2"
|
48
47
|
gem.add_development_dependency "rack-test_app"
|
49
48
|
|
50
49
|
# for determine_mime_type plugin
|
@@ -67,10 +66,10 @@ direct uploads for fully asynchronous user experience.
|
|
67
66
|
|
68
67
|
# for instrumentation plugin
|
69
68
|
gem.add_development_dependency "dry-monitor"
|
70
|
-
gem.add_development_dependency "activesupport", "~> 5.2
|
69
|
+
gem.add_development_dependency "activesupport", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
|
71
70
|
|
72
71
|
# for ORM plugins
|
73
72
|
gem.add_development_dependency "sequel"
|
74
|
-
gem.add_development_dependency "activerecord", "~> 5.2
|
75
|
-
gem.add_development_dependency "sqlite3", "~> 1.
|
73
|
+
gem.add_development_dependency "activerecord", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
|
74
|
+
gem.add_development_dependency "sqlite3", "~> 1.4" unless RUBY_ENGINE == "jruby"
|
76
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shrine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janko Marohnić
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: down
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: content_disposition
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,28 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1.
|
75
|
+
version: '1.11'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '1.
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: dry-initializer
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
82
|
+
version: '1.11'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rack
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +100,14 @@ dependencies:
|
|
114
100
|
requirements:
|
115
101
|
- - "~>"
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: '2.
|
103
|
+
version: '2.2'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version: '2.
|
110
|
+
version: '2.2'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: rack-test_app
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -296,14 +282,14 @@ dependencies:
|
|
296
282
|
requirements:
|
297
283
|
- - "~>"
|
298
284
|
- !ruby/object:Gem::Version
|
299
|
-
version:
|
285
|
+
version: '6.0'
|
300
286
|
type: :development
|
301
287
|
prerelease: false
|
302
288
|
version_requirements: !ruby/object:Gem::Requirement
|
303
289
|
requirements:
|
304
290
|
- - "~>"
|
305
291
|
- !ruby/object:Gem::Version
|
306
|
-
version:
|
292
|
+
version: '6.0'
|
307
293
|
- !ruby/object:Gem::Dependency
|
308
294
|
name: sequel
|
309
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -324,28 +310,28 @@ dependencies:
|
|
324
310
|
requirements:
|
325
311
|
- - "~>"
|
326
312
|
- !ruby/object:Gem::Version
|
327
|
-
version:
|
313
|
+
version: '6.0'
|
328
314
|
type: :development
|
329
315
|
prerelease: false
|
330
316
|
version_requirements: !ruby/object:Gem::Requirement
|
331
317
|
requirements:
|
332
318
|
- - "~>"
|
333
319
|
- !ruby/object:Gem::Version
|
334
|
-
version:
|
320
|
+
version: '6.0'
|
335
321
|
- !ruby/object:Gem::Dependency
|
336
322
|
name: sqlite3
|
337
323
|
requirement: !ruby/object:Gem::Requirement
|
338
324
|
requirements:
|
339
325
|
- - "~>"
|
340
326
|
- !ruby/object:Gem::Version
|
341
|
-
version: 1.
|
327
|
+
version: '1.4'
|
342
328
|
type: :development
|
343
329
|
prerelease: false
|
344
330
|
version_requirements: !ruby/object:Gem::Requirement
|
345
331
|
requirements:
|
346
332
|
- - "~>"
|
347
333
|
- !ruby/object:Gem::Version
|
348
|
-
version: 1.
|
334
|
+
version: '1.4'
|
349
335
|
description: |
|
350
336
|
Shrine is a toolkit for file attachments in Ruby applications. It supports
|
351
337
|
uploading, downloading, processing and deleting IO objects, backed by various
|
@@ -470,6 +456,7 @@ files:
|
|
470
456
|
- doc/release_notes/3.0.1.md
|
471
457
|
- doc/release_notes/3.1.0.md
|
472
458
|
- doc/release_notes/3.2.0.md
|
459
|
+
- doc/release_notes/3.2.1.md
|
473
460
|
- doc/retrieving_uploads.md
|
474
461
|
- doc/securing_uploads.md
|
475
462
|
- doc/storage/file_system.md
|
@@ -564,7 +551,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
564
551
|
- !ruby/object:Gem::Version
|
565
552
|
version: '0'
|
566
553
|
requirements: []
|
567
|
-
rubygems_version: 3.1.
|
554
|
+
rubygems_version: 3.1.2
|
568
555
|
signing_key:
|
569
556
|
specification_version: 4
|
570
557
|
summary: Toolkit for file attachments in Ruby applications
|