shrine 3.2.2 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/README.md +5 -0
- data/doc/advantages.md +1 -1
- data/doc/carrierwave.md +7 -4
- data/doc/direct_s3.md +1 -0
- data/doc/external/articles.md +6 -8
- data/doc/external/extensions.md +3 -0
- data/doc/external/misc.md +23 -8
- data/doc/getting_started.md +4 -8
- data/doc/multiple_files.md +1 -1
- data/doc/paperclip.md +14 -5
- data/doc/plugins/add_metadata.md +20 -0
- data/doc/plugins/atomic_helpers.md +41 -3
- data/doc/plugins/derivatives.md +43 -12
- data/doc/plugins/download_endpoint.md +5 -5
- data/doc/plugins/dynamic_storage.md +1 -1
- data/doc/plugins/infer_extension.md +9 -0
- data/doc/plugins/metadata_attributes.md +1 -0
- data/doc/plugins/mirroring.md +1 -1
- data/doc/plugins/persistence.md +10 -1
- data/doc/plugins/store_dimensions.md +10 -0
- data/doc/plugins/url_options.md +2 -2
- data/doc/processing.md +7 -8
- data/doc/release_notes/2.8.0.md +1 -1
- data/doc/release_notes/3.2.1.md +2 -3
- data/doc/release_notes/3.3.0.md +105 -0
- data/doc/storage/s3.md +9 -5
- data/doc/upgrading_to_3.md +11 -27
- data/lib/shrine/attacher.rb +6 -1
- data/lib/shrine/plugins/activerecord.rb +1 -1
- data/lib/shrine/plugins/add_metadata.rb +6 -4
- data/lib/shrine/plugins/backgrounding.rb +2 -2
- data/lib/shrine/plugins/derivation_endpoint.rb +2 -1
- data/lib/shrine/plugins/derivatives.rb +45 -15
- data/lib/shrine/plugins/mirroring.rb +8 -8
- data/lib/shrine/plugins/presign_endpoint.rb +14 -2
- data/lib/shrine/plugins/remove_attachment.rb +5 -0
- data/lib/shrine/plugins/sequel.rb +1 -1
- data/lib/shrine/plugins/store_dimensions.rb +4 -2
- data/lib/shrine/plugins/upload_endpoint.rb +7 -2
- data/lib/shrine/storage/memory.rb +5 -3
- data/lib/shrine/storage/s3.rb +61 -6
- data/lib/shrine/version.rb +2 -2
- data/shrine.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cfa59ed1f6143ee9298ede17eeda07dba85f0f9c3309a5b7a9e7f6c41399f29
|
4
|
+
data.tar.gz: 67a64a3a4f40c34797ca04279af73829acf4071eb118f78addefdbaa15e048da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e87a3dbb80a304f8af559b9c3d4e8badf8e47e4377afd74fe08d570042d65358d44878c4a0366fa3cded98fe166083275e86c61f3b51d28d35e070e0233dea35
|
7
|
+
data.tar.gz: 83c93e76bf5513ab317ccabbdda86ce90f760e7b898dc9f40036af3e7ec915f48e55bd6f8efcf8661dacea672ce6b24b450db217815b062881169c8c90fd0cd3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
## 3.3.0 (2020-10-04)
|
2
|
+
|
3
|
+
* `s3` - Support new `Aws::S3::EncryptionV2::Client` for client-side encryption (@janko)
|
4
|
+
|
5
|
+
* `derivation_endpoint` – Reduce possibility of timing attacks when comparing signatures (@esparta)
|
6
|
+
|
7
|
+
* `derivatives` – Avoid downloading the attached file when calling default no-op processor (@janko)
|
8
|
+
|
9
|
+
* `derivatives` – Add `:download` processor setting for skipping downloading source file (@jrochkind, @janko)
|
10
|
+
|
11
|
+
* `derivatives` – Copy non-file source IO objects into local file before passing them to the processor (@jrochkind)
|
12
|
+
|
13
|
+
* `sequel` – Call `Attacher#reload` in `Sequel::Model#reload`, which keeps rest of attacher state (@janko, @jrochkind)
|
14
|
+
|
15
|
+
* `activerecord` – Call `Attacher#reload` in `ActiveRecord::Base#reload`, which keeps rest of attacher state (@janko, @jrochkind)
|
16
|
+
|
17
|
+
* `add_metadata` – Add `:skip_nil` option for excluding metadata keys whose values are nil (@renchap)
|
18
|
+
|
19
|
+
* `store_dimensions` – Add `:auto_extraction` option for disabling automatically extracting dimensions on upload (@renchap)
|
20
|
+
|
21
|
+
* `mirroring` – Forward original upload options when mirroring upload (@corneverbruggen)
|
22
|
+
|
23
|
+
* `derivation_endpoint` – Apply `version` URL option in derivation endpoint (@janko)
|
24
|
+
|
25
|
+
* `remove_attachment` – Delete removed file if a new file was attached right after removal (@janko)
|
26
|
+
|
27
|
+
* `upload_endpoint` – Fix `Shrine.upload_response` not working in a Rails controller (@pldavid2)
|
28
|
+
|
29
|
+
* `presign_endpoint` – Add `OPTIONS` route that newer versions of Uppy check (@janko)
|
30
|
+
|
31
|
+
* `derivatives` – Add `:create_on_promote` option for auto-creating derivatives on promotion (@janko)
|
32
|
+
|
33
|
+
* `s3` – Add back support for client-side encryption (@janko)
|
34
|
+
|
35
|
+
* `memory` – Ensure `Memory#open` returns content in original encoding (@jrochkind)
|
36
|
+
|
1
37
|
## 3.2.2 (2020-08-05)
|
2
38
|
|
3
39
|
* `s3` – Fix `S3#open` not working on aws-sdk-core 3.104 and above (@janko)
|
data/README.md
CHANGED
@@ -127,6 +127,10 @@ system.
|
|
127
127
|
* Refile
|
128
128
|
* Active Storage
|
129
129
|
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
Please refer to the [contributing page][Contributing].
|
133
|
+
|
130
134
|
## Code of Conduct
|
131
135
|
|
132
136
|
Everyone interacting in the Shrine project’s codebases, issue trackers, and
|
@@ -170,3 +174,4 @@ The gem is available as open source under the terms of the [MIT License].
|
|
170
174
|
[Roda]: https://github.com/jeremyevans/roda
|
171
175
|
[CoC]: /CODE_OF_CONDUCT.md
|
172
176
|
[MIT License]: /LICENSE.txt
|
177
|
+
[Contributing]: https://github.com/shrinerb/shrine/blob/master/CONTRIBUTING.md
|
data/doc/advantages.md
CHANGED
@@ -93,7 +93,7 @@ low-level abstractions that give you the flexibility to build your own flow.
|
|
93
93
|
```rb
|
94
94
|
uploaded_file = ImageUploader.upload(image, :store) # metadata extraction, upload location generation
|
95
95
|
uploaded_file.id #=> "44ccafc10ce6a4ff22829e8f579ee6b9.jpg"
|
96
|
-
|
96
|
+
uploaded_file.metadata #=> { ... extracted metadata ... }
|
97
97
|
|
98
98
|
data = uploaded_file.to_json # serialization
|
99
99
|
# ...
|
data/doc/carrierwave.md
CHANGED
@@ -322,19 +322,22 @@ module CarrierwaveShrineSynchronization
|
|
322
322
|
|
323
323
|
private
|
324
324
|
|
325
|
-
# If you'll be using `:prefix` on your Shrine storage, make sure to
|
326
|
-
# subtract it from the path assigned as `:id`.
|
327
325
|
def shrine_file(uploader)
|
328
326
|
name = uploader.mounted_as
|
329
327
|
filename = read_attribute(name)
|
330
|
-
|
328
|
+
location = uploader.store_path(filename)
|
329
|
+
location = location.sub(%r{^#{storage.prefix}/}, "") if storage.prefix
|
331
330
|
|
332
331
|
Shrine.uploaded_file(
|
333
332
|
storage: :store,
|
334
|
-
id:
|
333
|
+
id: location,
|
335
334
|
metadata: { "filename" => filename },
|
336
335
|
)
|
337
336
|
end
|
337
|
+
|
338
|
+
def storage
|
339
|
+
Shrine.storages[:store]
|
340
|
+
end
|
338
341
|
end
|
339
342
|
```
|
340
343
|
```rb
|
data/doc/direct_s3.md
CHANGED
@@ -76,6 +76,7 @@ If you're using [Uppy], this is the recommended CORS configuration for the
|
|
76
76
|
<AllowedHeader>x-amz-content-sha256</AllowedHeader>
|
77
77
|
<AllowedHeader>content-type</AllowedHeader>
|
78
78
|
<AllowedHeader>content-disposition</AllowedHeader>
|
79
|
+
<ExposeHeader>ETag</ExposeHeader>
|
79
80
|
</CORSRule>
|
80
81
|
<CORSRule>
|
81
82
|
<AllowedOrigin>*</AllowedOrigin>
|
data/doc/external/articles.md
CHANGED
@@ -21,7 +21,7 @@ title: Articles
|
|
21
21
|
| [Asynchronous File Uploads](http://twin.github.io/file-uploads-asynchronous-world) | 18 Jan 2016 |
|
22
22
|
| [Introducing Shrine](http://twin.github.io/introducing-shrine) | 04 Oct 2015 |
|
23
23
|
|
24
|
-
##
|
24
|
+
## Community articles
|
25
25
|
|
26
26
|
| Article | Published |
|
27
27
|
| :------ | --------: |
|
@@ -32,9 +32,9 @@ title: Articles
|
|
32
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
33
|
| [Rails 5 + Shrine + DropzoneJS](https://stephencodes.com/rails-5-shrine-dropzonejs/) | 20 Oct 2018 |
|
34
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 |
|
35
|
+
| [Store Your Files on S3: Part 3 – 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: Part 2 – 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: Part 1 – Setup & Configuration](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-1.html) | 27 Nov 2017 |
|
38
38
|
| [Creating Streaming Radio With Rails and Icecast](https://scotch.io/tutorials/creating-online-streaming-radio-with-rails-and-icecast) | 06 Nov 2017 |
|
39
39
|
| [Multiple Photo Upload using Shrine](https://github.com/pyksoft/multi-photo-upload#multiple-photo-upload-using-shrine) | 02 Nov 2017 |
|
40
40
|
| [Uploading Files with Rails and ActionCable](https://scotch.io/tutorials/uploading-files-with-rails-and-actioncable) | 19 Oct 2017 |
|
@@ -48,14 +48,12 @@ title: Articles
|
|
48
48
|
|
49
49
|
| Screencast | Source | Published |
|
50
50
|
| :---- | :------ | --------: |
|
51
|
+
| [Testing File Uploads in Rails with Shrine](https://gorails.com/episodes/testing-file-uploads-with-shrine?autoplay=1) | GoRails | 23 Mar 2020 |
|
52
|
+
| [File Uploads in Rails with Shrine](https://gorails.com/episodes/rails-file-uploads-with-shrine?autoplay=1) | GoRails | 16 Mar 2020 |
|
51
53
|
| [Uploading Files to DigitalOcean Spaces](https://gorails.com/episodes/digital-ocean-spaces-with-rails?autoplay=1) | GoRails | 31 Oct 2017 |
|
52
54
|
| [Trix WYSIWYG Editor And File Uploads](https://gorails.com/episodes/trix-editor?autoplay=1) | GoRails | 03 Oct 2017 |
|
53
55
|
| [Multiple File Uploads with Shrine](https://gorails.com/episodes/multiple-file-uploads-with-shrine?autoplay=1) | GoRails | 14 Dec 2016 |
|
54
56
|
| [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
57
|
|
60
58
|
## Talks
|
61
59
|
|
data/doc/external/extensions.md
CHANGED
@@ -28,6 +28,8 @@ title: Extensions
|
|
28
28
|
| :---- | :-------- |
|
29
29
|
| [administrate-field-shrine](https://github.com/catsky/administrate-field-shrine) | Plugin for [Administrate](https://github.com/thoughtbot/administrate) |
|
30
30
|
| [rails_admin_shrine](https://github.com/iquest/rails_admin_shrine) | Plugin for [RailsAdmin](https://github.com/sferik/rails_admin) |
|
31
|
+
| [shrine-blurhash](https://github.com/renchap/shrine-blurhash) | Plugin for computing [Blurhash](https://blurha.sh/) on images |
|
32
|
+
| [shrine-cloudimage](https://github.com/janklimo/shrine-cloudimage) | Plugin for [Cloudimage](https://www.cloudimage.io/) |
|
31
33
|
| [shrine-color](https://github.com/jnylen/shrine-color) | Plugin for finding dominant color in an image |
|
32
34
|
| [shrine-configurable_storage](https://github.com/SleeplessByte/shrine-configurable_storage) | Plugin for lazy storage registration |
|
33
35
|
| [shrine-content_addressable](https://github.com/SleeplessByte/shrine-content_addressable) | Plugin for generating content addressable locations |
|
@@ -45,6 +47,7 @@ title: Extensions
|
|
45
47
|
| Gem | Description |
|
46
48
|
| :----- | :------- |
|
47
49
|
| [ckeditor](https://github.com/galetahub/ckeditor) | Integration for [CKEditor](https://ckeditor.com/ckeditor-4/) |
|
50
|
+
| [faster_s3_url](https://github.com/jrochkind/faster_s3_url) | Optimized generation of public and presigned AWS S3 GET URLs |
|
48
51
|
| [imgproxy](https://github.com/imgproxy/imgproxy.rb) | Integration for [imgproxy](https://github.com/imgproxy/imgproxy) |
|
49
52
|
| [rails_admin](https://github.com/sferik/rails_admin) | Integration for [RailsAdmin](https://github.com/sferik/rails_admin) |
|
50
53
|
| [uppy-s3_multipart](https://github.com/janko/uppy-s3_multipart) | Integration for [Uppy AWS S3 Multipart](https://uppy.io/docs/aws-s3-multipart/) |
|
data/doc/external/misc.md
CHANGED
@@ -4,14 +4,29 @@ title: Miscellaneous
|
|
4
4
|
|
5
5
|
## Demos
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
| Demo | Description |
|
8
|
+
| :--- | :---------- |
|
9
|
+
| [Dropzone demo](https://github.com/codyeatworld/example-shrine-dropzone) | Shows direct upload using [Dropzone.js] |
|
10
|
+
| [Hanami demo](https://github.com/katafrakt/hanami-shrine-example) | Shows file attachment in [Hanami] |
|
11
|
+
| [Crop demo](https://github.com/shrinerb/shrine-crop-example) | Shows image cropping using [Cropper.js] |
|
12
|
+
| [Rails demo](https://github.com/erikdahlstrand/shrine-rails-example) | Shows direct upload in [Rails] |
|
13
|
+
| [Resumable uploads demo](https://github.com/shrinerb/shrine-tus-demo) | Shows resumable direct upload on [tus] |
|
14
|
+
| [Roda demo (official)](https://github.com/shrinerb/shrine/tree/master/demo) | Shows direct upload in [Roda] |
|
15
|
+
| [rom-rb & dry-rb demo](https://github.com/shrinerb/shrine-rom/tree/master/demo) | Shows file attachment with [rom-rb] and [dry-rb] |
|
16
|
+
| [Transloadit demo](https://github.com/shrinerb/shrine-transloadit/tree/master/demo) | Shows file processing using [Transloadit] |
|
14
17
|
|
15
18
|
## Projects
|
16
19
|
|
17
|
-
|
20
|
+
| Project | Description |
|
21
|
+
| :------ | :---------- |
|
22
|
+
| [CortexCMS](https://docs.cortexcms.org) | An open source, enterprise content management and distribution platform |
|
23
|
+
|
24
|
+
[Dropzone.js]: https://www.dropzonejs.com/
|
25
|
+
[Hanami]: https://hanamirb.org/
|
26
|
+
[Cropper.js]: https://github.com/fengyuanchen/cropperjs
|
27
|
+
[Rails]: https://rubyonrails.org/
|
28
|
+
[tus]: https://tus.io/
|
29
|
+
[Roda]: https://roda.jeremyevans.net/
|
30
|
+
[rom-rb]: https://rom-rb.org/
|
31
|
+
[dry-rb]: https://dry-rb.org/
|
32
|
+
[Transloadit]: https://transloadit.com/
|
data/doc/getting_started.md
CHANGED
@@ -554,7 +554,7 @@ creation:
|
|
554
554
|
gem "image_processing", "~> 1.8"
|
555
555
|
```
|
556
556
|
```rb
|
557
|
-
Shrine.plugin :derivatives
|
557
|
+
Shrine.plugin :derivatives, create_on_promote: true
|
558
558
|
```
|
559
559
|
```rb
|
560
560
|
require "image_processing/mini_magick"
|
@@ -573,11 +573,7 @@ end
|
|
573
573
|
```
|
574
574
|
```rb
|
575
575
|
photo = Photo.new(image: file)
|
576
|
-
|
577
|
-
if photo.valid?
|
578
|
-
photo.image_derivatives! if photo.image_changed? # create derivatives
|
579
|
-
photo.save
|
580
|
-
end
|
576
|
+
photo.save # automatically creates derivatives on promotion
|
581
577
|
```
|
582
578
|
|
583
579
|
You can then retrieve the URL of a processed derivative:
|
@@ -711,7 +707,7 @@ photo/
|
|
711
707
|
...
|
712
708
|
```
|
713
709
|
|
714
|
-
|
710
|
+
But you can also override `Shrine#generate_location` with a custom
|
715
711
|
implementation, for example:
|
716
712
|
|
717
713
|
```rb
|
@@ -903,7 +899,7 @@ resumable uploads from scratch, it includes a complete JavaScript example
|
|
903
899
|
|
904
900
|
## Backgrounding
|
905
901
|
|
906
|
-
The [`backgrounding`][backgrounding plugin] allows you to move file promotion
|
902
|
+
The [`backgrounding`][backgrounding plugin] plugin allows you to move file promotion
|
907
903
|
and deletion into a background job, using the backgrounding library [of your
|
908
904
|
choice][Backgrounding Libraries]:
|
909
905
|
|
data/doc/multiple_files.md
CHANGED
@@ -228,7 +228,7 @@ photos_attributes = album_params[:photos_attributes].to_h.merge(new_photos_attri
|
|
228
228
|
album_attributes = album_params.merge(photos_attributes: photos_attributes)
|
229
229
|
|
230
230
|
# create the album with photos
|
231
|
-
Album.create(
|
231
|
+
Album.create(album_attributes)
|
232
232
|
```
|
233
233
|
|
234
234
|
In this case you need to make sure your form tag has
|
data/doc/paperclip.md
CHANGED
@@ -358,13 +358,14 @@ module PaperclipShrineSynchronization
|
|
358
358
|
end
|
359
359
|
end
|
360
360
|
|
361
|
-
# If you'll be using a `:prefix` on your Shrine storage, or you're storing
|
362
|
-
# files on the filesystem, make sure to subtract the appropriate part
|
363
|
-
# from the path assigned to `:id`.
|
364
361
|
def shrine_attachment_file(attachment)
|
362
|
+
location = attachment.path
|
363
|
+
# if you're storing files on disk, make sure to subtract the absolute path
|
364
|
+
location = location.sub(%r{^#{storage.prefix}/}, "") if storage.prefix
|
365
|
+
|
365
366
|
Shrine.uploaded_file(
|
366
367
|
storage: :store,
|
367
|
-
id:
|
368
|
+
id: location,
|
368
369
|
metadata: {
|
369
370
|
"size" => attachment.size,
|
370
371
|
"filename" => attachment.original_filename,
|
@@ -377,12 +378,20 @@ module PaperclipShrineSynchronization
|
|
377
378
|
# files on the filesystem, make sure to subtract the appropriate part
|
378
379
|
# from the path assigned to `:id`.
|
379
380
|
def shrine_style_file(style)
|
381
|
+
location = style.attachment.path(style.name)
|
382
|
+
# if you're storing files on disk, make sure to subtract the absolute path
|
383
|
+
location = location.sub(%r{^#{storage.prefix}/}, "") if storage.prefix
|
384
|
+
|
380
385
|
Shrine.uploaded_file(
|
381
386
|
storage: :store,
|
382
|
-
id:
|
387
|
+
id: location,
|
383
388
|
metadata: {},
|
384
389
|
)
|
385
390
|
end
|
391
|
+
|
392
|
+
def storage
|
393
|
+
Shrine.storages[:store]
|
394
|
+
end
|
386
395
|
end
|
387
396
|
```
|
388
397
|
```rb
|
data/doc/plugins/add_metadata.md
CHANGED
@@ -34,6 +34,26 @@ uploaded_file.metadata["page_count"] #=> 30
|
|
34
34
|
uploaded_file.page_count #=> 30
|
35
35
|
```
|
36
36
|
|
37
|
+
### Skipping nil values
|
38
|
+
|
39
|
+
By default, if your block returns `nil` then the `nil` value will be stored into
|
40
|
+
metadata. If you do not want to store anything when your block returns nil, you
|
41
|
+
can use the `skip_nil: true` option:
|
42
|
+
|
43
|
+
```rb
|
44
|
+
class PdfUploader < Shrine
|
45
|
+
add_metadata :pages, skip_nil: true do |io|
|
46
|
+
if is_pdf?(io)
|
47
|
+
reader = PDF::Reader.new(io)
|
48
|
+
reader.page_count
|
49
|
+
else
|
50
|
+
# If this is not a PDF, then the pages metadata will not be stored
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
37
57
|
### Multiple values
|
38
58
|
|
39
59
|
You can also extract multiple metadata values at once, by using `add_metadata`
|
@@ -3,14 +3,48 @@ title: Atomic Helpers
|
|
3
3
|
---
|
4
4
|
|
5
5
|
The [`atomic_helpers`][atomic_helpers] plugin provides API for retrieving and
|
6
|
-
persisting attachments in a concurrency-safe way, which is useful
|
7
|
-
the `backgrounding` plugin. The database plugins (`activerecord`
|
8
|
-
implement atomic promotion and atomic persistence on top of this
|
6
|
+
persisting attachments in a concurrency-safe way, which is especially useful
|
7
|
+
when using the `backgrounding` plugin. The database plugins (`activerecord`
|
8
|
+
and `sequel`) implement atomic promotion and atomic persistence on top of this
|
9
|
+
plugin.
|
9
10
|
|
10
11
|
```rb
|
11
12
|
plugin :atomic_helpers
|
12
13
|
```
|
13
14
|
|
15
|
+
## Problem Statement
|
16
|
+
|
17
|
+
What happens if two different processors (web workers, background jobs,
|
18
|
+
command-line executions, whatever) try to edit a shrine attachment
|
19
|
+
concurrently? The kinds of edits typically made include: "promoting a file",
|
20
|
+
moving it to a different storage and persisting that change in the model;
|
21
|
+
adding or changing a derivative; adding or changing a metadata element.
|
22
|
+
|
23
|
+
There are two main categories of "race condition":
|
24
|
+
|
25
|
+
1. The file could be switched out from under you. If you were promoting a file,
|
26
|
+
but some other process has *changed* the attachment, you don't want to
|
27
|
+
overwrite it with the promomoted version of the *prior* attacchment. Likewise,
|
28
|
+
if you were adding metadata or a derivative, they would be corresponding to a
|
29
|
+
certain attachment, and you don't want to accidentally add them to a now changed
|
30
|
+
attacchment for which they are inappropriate.
|
31
|
+
|
32
|
+
2. Overwriting each other's edits. Since all shrine (meta)data is stored in a
|
33
|
+
single JSON hash, standard implementations will write the entire JSON hash at
|
34
|
+
once to a rdbms column or other store. If two processes both read in the hash,
|
35
|
+
make a change to different keys in it, and then write it back out, the second
|
36
|
+
process to write will 'win' and overwrite changes made by the first.
|
37
|
+
|
38
|
+
The atomic helpers give you tools to avoid both of these sorts of race
|
39
|
+
conditions, under conditions of concurrent editing.
|
40
|
+
|
41
|
+
## High-level ORM helpers
|
42
|
+
|
43
|
+
If you are using the `sequel` or `activerecord` plugins, they give you two
|
44
|
+
higher-level helpers: `atomic_persist` and `atomic_promote`. See the
|
45
|
+
[persistence] documentation for more.
|
46
|
+
|
47
|
+
|
14
48
|
## Retrieving
|
15
49
|
|
16
50
|
The `Attacher.retrieve` method provided by the plugin instantiates an attacher
|
@@ -177,3 +211,7 @@ end
|
|
177
211
|
```
|
178
212
|
|
179
213
|
[atomic_helpers]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/atomic_helpers.rb
|
214
|
+
|
215
|
+
[persistence]: https://shrinerb.com/docs/plugins/persistence
|
216
|
+
|
217
|
+
[backgrounding]: https://shrinerb.com/docs/plugins/backgrounding
|
data/doc/plugins/derivatives.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
title: Derivatives
|
3
3
|
---
|
4
4
|
|
5
|
-
The derivatives plugin allows storing processed files ("derivatives") alongside
|
5
|
+
The [`derivatives`][derivatives] plugin allows storing processed files ("derivatives") alongside
|
6
6
|
the main attached file. The processed file data will be saved together with the
|
7
7
|
main attachment data in the same record attribute.
|
8
8
|
|
@@ -38,17 +38,9 @@ class ImageUploader < Shrine
|
|
38
38
|
end
|
39
39
|
```
|
40
40
|
```rb
|
41
|
-
class Photo < Model(:image_data)
|
42
|
-
include ImageUploader::Attachment(:image)
|
43
|
-
end
|
44
|
-
```
|
45
|
-
```rb
|
46
41
|
photo = Photo.new(image: file)
|
47
|
-
|
48
|
-
|
49
|
-
photo.image_derivatives! if photo.image_changed? # create derivatives
|
50
|
-
photo.save
|
51
|
-
end
|
42
|
+
photo.image_derivatives! # creates derivatives
|
43
|
+
photo.save
|
52
44
|
```
|
53
45
|
|
54
46
|
You can then retrieve the URL of a processed derivative:
|
@@ -205,6 +197,19 @@ attacher.create_derivatives(different_source) # pass a different source file
|
|
205
197
|
attacher.create_derivatives(foo: "bar") # pass custom options to the processor
|
206
198
|
```
|
207
199
|
|
200
|
+
### Create on promote
|
201
|
+
|
202
|
+
You can also have derivatives created automatically on promotion:
|
203
|
+
|
204
|
+
```rb
|
205
|
+
Shrine.plugin :derivatives, create_on_promote: true
|
206
|
+
```
|
207
|
+
```rb
|
208
|
+
attacher.assign(file)
|
209
|
+
attacher.finalize # creates derivatives on promotion
|
210
|
+
attacher.derivatives #=> { small: ..., medium: ..., large: ... }
|
211
|
+
```
|
212
|
+
|
208
213
|
### Naming processors
|
209
214
|
|
210
215
|
If you want to have multiple processors for an uploader, you can assign each
|
@@ -396,7 +401,8 @@ attacher.process_derivatives(:my_processor) # downloads attached file and passes
|
|
396
401
|
|
397
402
|
If you want to use a different source file, you can pass it in to the process
|
398
403
|
call. Typically you'd pass a local file on disk. If you pass a
|
399
|
-
`Shrine::UploadedFile` object, it will be
|
404
|
+
`Shrine::UploadedFile` object or another IO-like object, it will be
|
405
|
+
automatically downloaded/copied to a local TempFile on disk.
|
400
406
|
|
401
407
|
```rb
|
402
408
|
# named processor:
|
@@ -416,6 +422,20 @@ attacher.file.download do |original|
|
|
416
422
|
end
|
417
423
|
```
|
418
424
|
|
425
|
+
If a processor might not always need a local source file, you avoid a
|
426
|
+
potentially expensive download/copy by registering the processor with
|
427
|
+
`download: false`, in which case the source file will be passed to the
|
428
|
+
processor as is.
|
429
|
+
|
430
|
+
```rb
|
431
|
+
Attacher.derivatives :my_processor, download: false do |source|
|
432
|
+
source #=> Could be File, Shrine::UploadedFile, or other IO-like object
|
433
|
+
shrine_class.with_file(source) do |file|
|
434
|
+
# can force download/copy if necessary with `with_file`,
|
435
|
+
end
|
436
|
+
end
|
437
|
+
```
|
438
|
+
|
419
439
|
## Adding derivatives
|
420
440
|
|
421
441
|
If you already have processed files that you want to save, you can do that with
|
@@ -459,6 +479,11 @@ For adding a single derivative, you can also use the singular
|
|
459
479
|
attacher.add_derivative(:thumb, thumbnail_file)
|
460
480
|
```
|
461
481
|
|
482
|
+
> Note that new derivatives will replace any existing derivatives living under
|
483
|
+
the same key, but won't delete them. If this is your case, make sure to save a
|
484
|
+
reference to the old derivatives before assigning new ones, and then delete
|
485
|
+
them after persisting the change.
|
486
|
+
|
462
487
|
Any options passed to `Attacher#add_derivative(s)` will be forwarded to
|
463
488
|
[`Attacher#upload_derivatives`](#uploading-derivatives).
|
464
489
|
|
@@ -567,6 +592,11 @@ attacher.merge_derivatives attacher.upload_derivatives({ nested: { two: two_file
|
|
567
592
|
attacher.derivatives #=> { nested: { one: #<Shrine::UploadedFile>, two: #<Shrine::UploadedFile> } }
|
568
593
|
```
|
569
594
|
|
595
|
+
> Note that new derivatives will replace any existing derivatives living under
|
596
|
+
the same key, but won't delete them. If this is your case, make sure to save a
|
597
|
+
reference to the old derivatives before assigning new ones, and then delete
|
598
|
+
them after persisting the change.
|
599
|
+
|
570
600
|
The `Attacher#merge_derivatives` method is thread-safe.
|
571
601
|
|
572
602
|
### Setting derivatives
|
@@ -793,6 +823,7 @@ Or disable logging altogether:
|
|
793
823
|
plugin :derivatives, log_subscriber: nil
|
794
824
|
```
|
795
825
|
|
826
|
+
[derivatives]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/derivatives.rb
|
796
827
|
[default_url]: https://shrinerb.com/docs/plugins/default_url
|
797
828
|
[entity]: https://shrinerb.com/docs/plugins/entity
|
798
829
|
[model]: https://shrinerb.com/docs/plugins/model
|