shrine 2.19.3 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +523 -41
- data/LICENSE.txt +1 -1
- data/README.md +83 -979
- data/doc/advantages.md +231 -204
- data/doc/attacher.md +304 -153
- data/doc/carrierwave.md +297 -226
- data/doc/changing_derivatives.md +308 -0
- data/doc/changing_location.md +103 -21
- data/doc/changing_storage.md +110 -0
- data/doc/creating_persistence_plugins.md +132 -0
- data/doc/creating_plugins.md +43 -23
- data/doc/creating_storages.md +19 -5
- data/doc/design.md +147 -97
- data/doc/direct_s3.md +38 -28
- data/doc/external/articles.md +63 -0
- data/doc/external/extensions.md +53 -0
- data/doc/external/misc.md +32 -0
- data/doc/getting_started.md +1156 -0
- data/doc/metadata.md +190 -109
- data/doc/multiple_files.md +93 -30
- data/doc/paperclip.md +384 -262
- data/doc/plugins/activerecord.md +177 -46
- data/doc/plugins/add_metadata.md +139 -38
- data/doc/plugins/atomic_helpers.md +217 -0
- data/doc/plugins/backgrounding.md +156 -98
- data/doc/plugins/cached_attachment_data.md +7 -5
- data/doc/plugins/column.md +121 -0
- data/doc/plugins/data_uri.md +23 -22
- data/doc/plugins/default_storage.md +36 -10
- data/doc/plugins/default_url.md +30 -13
- data/doc/plugins/delete_raw.md +4 -2
- data/doc/plugins/derivation_endpoint.md +186 -101
- data/doc/plugins/derivatives.md +839 -0
- data/doc/plugins/determine_mime_type.md +4 -2
- data/doc/plugins/download_endpoint.md +64 -8
- data/doc/plugins/dynamic_storage.md +5 -3
- data/doc/plugins/entity.md +263 -0
- data/doc/plugins/form_assign.md +55 -0
- data/doc/plugins/included.md +31 -8
- data/doc/plugins/infer_extension.md +21 -10
- data/doc/plugins/instrumentation.md +38 -16
- data/doc/plugins/keep_files.md +16 -17
- data/doc/plugins/metadata_attributes.md +42 -13
- data/doc/plugins/mirroring.md +118 -0
- data/doc/plugins/model.md +210 -0
- data/doc/plugins/module_include.md +4 -2
- data/doc/plugins/multi_cache.md +24 -0
- data/doc/plugins/persistence.md +101 -0
- data/doc/plugins/presign_endpoint.md +9 -4
- data/doc/plugins/pretty_location.md +16 -3
- data/doc/plugins/processing.md +4 -2
- data/doc/plugins/rack_file.md +8 -2
- data/doc/plugins/rack_response.md +6 -2
- data/doc/plugins/recache.md +4 -2
- data/doc/plugins/refresh_metadata.md +49 -9
- data/doc/plugins/remote_url.md +84 -47
- data/doc/plugins/remove_attachment.md +27 -6
- data/doc/plugins/remove_invalid.md +21 -6
- data/doc/plugins/restore_cached_data.md +11 -3
- data/doc/plugins/sequel.md +159 -35
- data/doc/plugins/signature.md +16 -5
- data/doc/plugins/store_dimensions.md +14 -2
- data/doc/plugins/tempfile.md +4 -2
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +13 -13
- data/doc/plugins/upload_options.md +6 -4
- data/doc/plugins/{default_url_options.md → url_options.md} +9 -7
- data/doc/plugins/validation.md +97 -0
- data/doc/plugins/validation_helpers.md +16 -13
- data/doc/plugins/versions.md +15 -19
- data/doc/processing.md +438 -221
- data/doc/refile.md +188 -170
- data/doc/release_notes/1.0.0.md +4 -0
- data/doc/release_notes/1.1.0.md +6 -2
- data/doc/release_notes/1.2.0.md +4 -0
- data/doc/release_notes/1.3.0.md +4 -0
- data/doc/release_notes/1.4.0.md +4 -0
- data/doc/release_notes/1.4.1.md +4 -0
- data/doc/release_notes/1.4.2.md +4 -0
- data/doc/release_notes/2.0.0.md +4 -0
- data/doc/release_notes/2.0.1.md +4 -0
- data/doc/release_notes/2.1.0.md +5 -1
- data/doc/release_notes/2.1.1.md +4 -0
- data/doc/release_notes/2.10.0.md +4 -0
- data/doc/release_notes/2.10.1.md +4 -0
- data/doc/release_notes/2.11.0.md +4 -0
- data/doc/release_notes/2.12.0.md +4 -0
- data/doc/release_notes/2.13.0.md +4 -0
- data/doc/release_notes/2.14.0.md +5 -1
- data/doc/release_notes/2.15.0.md +11 -7
- data/doc/release_notes/2.16.0.md +4 -0
- data/doc/release_notes/2.17.0.md +4 -0
- data/doc/release_notes/2.18.0.md +4 -0
- data/doc/release_notes/2.19.0.md +6 -3
- data/doc/release_notes/2.2.0.md +4 -0
- data/doc/release_notes/2.3.0.md +4 -0
- data/doc/release_notes/2.3.1.md +4 -0
- data/doc/release_notes/2.4.0.md +4 -0
- data/doc/release_notes/2.4.1.md +4 -0
- data/doc/release_notes/2.5.0.md +4 -0
- data/doc/release_notes/2.6.0.md +4 -0
- data/doc/release_notes/2.6.1.md +4 -0
- data/doc/release_notes/2.7.0.md +4 -0
- data/doc/release_notes/2.8.0.md +4 -0
- data/doc/release_notes/2.9.0.md +4 -0
- data/doc/release_notes/3.0.0.md +981 -0
- data/doc/release_notes/3.0.1.md +22 -0
- data/doc/release_notes/3.1.0.md +73 -0
- data/doc/release_notes/3.2.0.md +96 -0
- data/doc/release_notes/3.2.1.md +31 -0
- data/doc/release_notes/3.2.2.md +14 -0
- data/doc/release_notes/3.3.0.md +105 -0
- data/doc/release_notes/3.4.0.md +35 -0
- data/doc/release_notes/3.5.0.md +63 -0
- data/doc/release_notes/3.6.0.md +23 -0
- data/doc/retrieving_uploads.md +5 -2
- data/doc/securing_uploads.md +60 -37
- data/doc/storage/file_system.md +20 -3
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +122 -78
- data/doc/testing.md +141 -133
- data/doc/upgrading_to_3.md +708 -0
- data/doc/validation.md +54 -90
- data/lib/shrine/attacher.rb +292 -169
- data/lib/shrine/attachment.rb +13 -46
- data/lib/shrine/plugins/_persistence.rb +93 -0
- data/lib/shrine/plugins/activerecord.rb +77 -34
- data/lib/shrine/plugins/add_metadata.rb +25 -17
- data/lib/shrine/plugins/atomic_helpers.rb +119 -0
- data/lib/shrine/plugins/backgrounding.rb +77 -113
- data/lib/shrine/plugins/cached_attachment_data.rb +6 -15
- data/lib/shrine/plugins/column.rb +102 -0
- data/lib/shrine/plugins/data_uri.rb +38 -36
- data/lib/shrine/plugins/default_storage.rb +45 -15
- data/lib/shrine/plugins/default_url.rb +12 -24
- data/lib/shrine/plugins/default_url_options.rb +3 -30
- data/lib/shrine/plugins/delete_raw.rb +10 -16
- data/lib/shrine/plugins/derivation_endpoint.rb +130 -171
- data/lib/shrine/plugins/derivatives.rb +645 -0
- data/lib/shrine/plugins/determine_mime_type.rb +9 -21
- data/lib/shrine/plugins/download_endpoint.rb +118 -133
- data/lib/shrine/plugins/dynamic_storage.rb +5 -11
- data/lib/shrine/plugins/entity.rb +158 -0
- data/lib/shrine/plugins/form_assign.rb +108 -0
- data/lib/shrine/plugins/included.rb +6 -6
- data/lib/shrine/plugins/infer_extension.rb +17 -20
- data/lib/shrine/plugins/instrumentation.rb +59 -43
- data/lib/shrine/plugins/keep_files.rb +3 -15
- data/lib/shrine/plugins/metadata_attributes.rb +28 -19
- data/lib/shrine/plugins/mirroring.rb +142 -0
- data/lib/shrine/plugins/model.rb +160 -0
- data/lib/shrine/plugins/module_include.rb +3 -3
- data/lib/shrine/plugins/multi_cache.rb +27 -0
- data/lib/shrine/plugins/presign_endpoint.rb +27 -28
- data/lib/shrine/plugins/pretty_location.rb +15 -9
- data/lib/shrine/plugins/processing.rb +22 -9
- data/lib/shrine/plugins/rack_file.rb +2 -42
- data/lib/shrine/plugins/rack_response.rb +21 -10
- data/lib/shrine/plugins/recache.rb +6 -5
- data/lib/shrine/plugins/refresh_metadata.rb +13 -11
- data/lib/shrine/plugins/remote_url.rb +49 -49
- data/lib/shrine/plugins/remove_attachment.rb +12 -6
- data/lib/shrine/plugins/remove_invalid.rb +19 -8
- data/lib/shrine/plugins/restore_cached_data.rb +13 -7
- data/lib/shrine/plugins/sequel.rb +86 -36
- data/lib/shrine/plugins/signature.rb +10 -16
- data/lib/shrine/plugins/store_dimensions.rb +35 -40
- data/lib/shrine/plugins/tempfile.rb +1 -3
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +28 -24
- data/lib/shrine/plugins/upload_options.rb +14 -15
- data/lib/shrine/plugins/url_options.rb +31 -0
- data/lib/shrine/plugins/validation.rb +80 -0
- data/lib/shrine/plugins/validation_helpers.rb +35 -58
- data/lib/shrine/plugins/versions.rb +107 -87
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/storage/file_system.rb +46 -64
- data/lib/shrine/storage/linter.rb +42 -7
- data/lib/shrine/storage/memory.rb +49 -0
- data/lib/shrine/storage/s3.rb +173 -160
- data/lib/shrine/uploaded_file.rb +32 -32
- data/lib/shrine/version.rb +3 -3
- data/lib/shrine.rb +87 -150
- data/shrine.gemspec +11 -12
- metadata +92 -82
- data/doc/migrating_storage.md +0 -76
- data/doc/plugins/backup.md +0 -31
- data/doc/plugins/copy.md +0 -24
- data/doc/plugins/delete_promoted.md +0 -12
- data/doc/plugins/direct_upload.md +0 -172
- data/doc/plugins/hooks.md +0 -58
- data/doc/plugins/logging.md +0 -42
- data/doc/plugins/migration_helpers.md +0 -60
- data/doc/plugins/moving.md +0 -19
- data/doc/plugins/multi_delete.md +0 -20
- data/doc/plugins/parallelize.md +0 -16
- data/doc/plugins/parsed_json.md +0 -23
- data/doc/regenerating_versions.md +0 -143
- data/lib/shrine/plugins/background_helpers.rb +0 -5
- data/lib/shrine/plugins/backup.rb +0 -90
- data/lib/shrine/plugins/copy.rb +0 -50
- data/lib/shrine/plugins/delete_promoted.rb +0 -20
- data/lib/shrine/plugins/direct_upload.rb +0 -217
- data/lib/shrine/plugins/hooks.rb +0 -90
- data/lib/shrine/plugins/logging.rb +0 -142
- data/lib/shrine/plugins/migration_helpers.rb +0 -70
- data/lib/shrine/plugins/moving.rb +0 -57
- data/lib/shrine/plugins/multi_delete.rb +0 -32
- data/lib/shrine/plugins/parallelize.rb +0 -78
- data/lib/shrine/plugins/parsed_json.rb +0 -29
|
@@ -1,34 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Derivation Endpoint
|
|
3
|
+
---
|
|
2
4
|
|
|
3
5
|
The [`derivation_endpoint`][derivation_endpoint] plugin provides a Rack app for
|
|
4
6
|
dynamically processing uploaded files on request. This allows you to create
|
|
5
7
|
URLs to files that might not have been generated yet, and have the endpoint
|
|
6
8
|
process them on-the-fly.
|
|
7
9
|
|
|
8
|
-
## Contents
|
|
9
|
-
|
|
10
|
-
* [Quick start](#quick-start)
|
|
11
|
-
* [How it works](#how-it-works)
|
|
12
|
-
- [Performance](#performance)
|
|
13
|
-
* [Derivation response](#derivation-response)
|
|
14
|
-
* [Dynamic settings](#dynamic-settings)
|
|
15
|
-
* [Host](#host)
|
|
16
|
-
* [Prefix](#prefix)
|
|
17
|
-
* [Expiration](#expiration)
|
|
18
|
-
* [Response headers](#response-headers)
|
|
19
|
-
- [Content Type](#content-type)
|
|
20
|
-
- [Content Disposition](#content-disposition)
|
|
21
|
-
- [Cache Control](#cache-control)
|
|
22
|
-
* [Uploading](#uploading)
|
|
23
|
-
- [Redirecting](#redirecting)
|
|
24
|
-
- [Deleting derivatives](#deleting-derivatives)
|
|
25
|
-
* [Cache busting](#cache-busting)
|
|
26
|
-
* [Accessing source file](#accessing-source-file)
|
|
27
|
-
* [Downloading](#downloading)
|
|
28
|
-
- [Skipping download](#skipping-download)
|
|
29
|
-
* [Derivation API](#derivation-api)
|
|
30
|
-
* [Plugin Options](#plugin-options)
|
|
31
|
-
|
|
32
10
|
## Quick start
|
|
33
11
|
|
|
34
12
|
We first load the plugin, providing a secret key and a path prefix to where the
|
|
@@ -57,7 +35,7 @@ apply to an attached file. For example, we can generate image thumbnails using
|
|
|
57
35
|
the [ImageProcessing] gem:
|
|
58
36
|
|
|
59
37
|
```rb
|
|
60
|
-
gem "image_processing", "~> 1.
|
|
38
|
+
gem "image_processing", "~> 1.8"
|
|
61
39
|
```
|
|
62
40
|
```rb
|
|
63
41
|
require "image_processing/mini_magick"
|
|
@@ -76,7 +54,7 @@ Now we can generate "derivation" URLs from attached files, which on request
|
|
|
76
54
|
will call the derivation block we defined.
|
|
77
55
|
|
|
78
56
|
```rb
|
|
79
|
-
photo.image.derivation_url(:thumbnail,
|
|
57
|
+
photo.image.derivation_url(:thumbnail, 600, 400)
|
|
80
58
|
#=> "/derivations/image/thumbnail/600/400/eyJpZCI6ImZvbyIsInN0b3JhZ2UiOiJzdG9yZSJ9?signature=..."
|
|
81
59
|
```
|
|
82
60
|
|
|
@@ -102,23 +80,26 @@ derivation URLs, preventing potential DoS attacks.
|
|
|
102
80
|
|
|
103
81
|
The derivation endpoint then extracts the source file data, derivation name and
|
|
104
82
|
arguments from the request URL, and calls the corresponding derivation block,
|
|
105
|
-
passing the downloaded source file and derivation arguments.
|
|
83
|
+
passing the downloaded source file and derivation arguments. The derivation
|
|
84
|
+
block is evaluated within the context of a
|
|
85
|
+
[`Shrine::Derivation`](#derivation-api) instance.
|
|
106
86
|
|
|
107
87
|
```rb
|
|
108
88
|
derivation :thumbnail do |file, arg1, arg2, ...|
|
|
89
|
+
self #=> #<Shrine::Derivation>
|
|
90
|
+
|
|
109
91
|
file #=> #<Tempfile:...> (source file downloaded to disk)
|
|
110
92
|
arg1 #=> "600" (first derivation argument in #derivation_url)
|
|
111
93
|
arg2 #=> "400" (second derivation argument in #derivation_url)
|
|
112
94
|
|
|
113
95
|
# ... do processing ...
|
|
114
96
|
|
|
115
|
-
# return result as a File
|
|
97
|
+
# return result as a File or Tempfile object
|
|
116
98
|
end
|
|
117
99
|
```
|
|
118
100
|
|
|
119
|
-
The derivation block is expected to return the processed file
|
|
120
|
-
`
|
|
121
|
-
then rendered in the HTTP response.
|
|
101
|
+
The derivation block is expected to return the processed file as a `File` or
|
|
102
|
+
`Tempfile` object. The resulting file is then rendered in the HTTP response.
|
|
122
103
|
|
|
123
104
|
### Performance
|
|
124
105
|
|
|
@@ -216,7 +197,8 @@ Rails.application.routes.draw do
|
|
|
216
197
|
end
|
|
217
198
|
end
|
|
218
199
|
end
|
|
219
|
-
|
|
200
|
+
```
|
|
201
|
+
```rb
|
|
220
202
|
# app/controllers/photos_controller.rb
|
|
221
203
|
class PhotosController < ApplicationController
|
|
222
204
|
def thumbnail
|
|
@@ -349,6 +331,29 @@ uploaded_file.derivation_url(:thumbnail, expires_in: 90)
|
|
|
349
331
|
#=> ".../thumbnail/eyJpZCI6ImZvbyIsInN?expires_at=1547843568&signature=..."
|
|
350
332
|
```
|
|
351
333
|
|
|
334
|
+
## Custom signer
|
|
335
|
+
|
|
336
|
+
The derivation URLs are signed by default, and the signature is checked when
|
|
337
|
+
the URLs are requested, which prevents tampering. If you have URL expiration
|
|
338
|
+
turned on, this may prevent your CDN from caching the response.
|
|
339
|
+
|
|
340
|
+
In this case, you may need to do custom CDN-specific URL signing. You can
|
|
341
|
+
bypass Shrine's default signing by passing a custom signer:
|
|
342
|
+
|
|
343
|
+
```rb
|
|
344
|
+
require "aws-sdk-cloudfront"
|
|
345
|
+
signer = Aws::CloudFront::UrlSigner.new(key_pair_id: "...", private_key: "...")
|
|
346
|
+
|
|
347
|
+
plugin :derivation_endpoint,
|
|
348
|
+
expires_in: 90,
|
|
349
|
+
signer: -> (url, expires_in:) do
|
|
350
|
+
signer.signed_url(url, expires: Time.now.to_i + expires_in)
|
|
351
|
+
end
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
When `:signer` option is used, the `:secret_key` option is not required, as
|
|
355
|
+
that secret is only used for default signing.
|
|
356
|
+
|
|
352
357
|
## Response headers
|
|
353
358
|
|
|
354
359
|
### Content Type
|
|
@@ -430,6 +435,8 @@ fetch the original uploaded file, call the derivation block, upload the
|
|
|
430
435
|
derivative to the storage, and serve the derivative. If the derivative does
|
|
431
436
|
exist on checking, the endpoint will download the derivative and serve it.
|
|
432
437
|
|
|
438
|
+
### Upload location
|
|
439
|
+
|
|
433
440
|
The default upload location for derivatives is `<source id>/<name>-<args>`.
|
|
434
441
|
This can be changed with the `:upload_location` option:
|
|
435
442
|
|
|
@@ -445,6 +452,8 @@ response won't know the appropriate `Content-Type` header value to set, and the
|
|
|
445
452
|
generic `application/octet-stream` will be used. It's recommended to use the
|
|
446
453
|
[`:type`](#content-type) option to set the appropriate `Content-Type` value.
|
|
447
454
|
|
|
455
|
+
### Upload storage
|
|
456
|
+
|
|
448
457
|
The target storage used is the same as for the source uploaded file. The
|
|
449
458
|
`:upload_storage` option can be used to specify a different Shrine storage:
|
|
450
459
|
|
|
@@ -453,6 +462,8 @@ plugin :derivation_endpoint, upload: true,
|
|
|
453
462
|
upload_storage: :thumbnail_storage
|
|
454
463
|
```
|
|
455
464
|
|
|
465
|
+
### Upload options
|
|
466
|
+
|
|
456
467
|
Additional storage-specific upload options can be passed via `:upload_options`:
|
|
457
468
|
|
|
458
469
|
```rb
|
|
@@ -460,6 +471,8 @@ plugin :derivation_endpoint, upload: true,
|
|
|
460
471
|
upload_options: { acl: "public-read" }
|
|
461
472
|
```
|
|
462
473
|
|
|
474
|
+
### Upload open options
|
|
475
|
+
|
|
463
476
|
Additional storage-specific download options for the uploaded derivation result
|
|
464
477
|
can be passed via `:upload_open_options`:
|
|
465
478
|
|
|
@@ -480,8 +493,7 @@ plugin :derivation_endpoint, upload: true,
|
|
|
480
493
|
upload_redirect: true
|
|
481
494
|
```
|
|
482
495
|
|
|
483
|
-
|
|
484
|
-
redirect URL:
|
|
496
|
+
Additional storage-specific URL options can be passed in for the redirect URL:
|
|
485
497
|
|
|
486
498
|
```rb
|
|
487
499
|
plugin :derivation_endpoint, upload: true,
|
|
@@ -489,20 +501,54 @@ plugin :derivation_endpoint, upload: true,
|
|
|
489
501
|
upload_redirect_url_options: { public: true }
|
|
490
502
|
```
|
|
491
503
|
|
|
492
|
-
|
|
493
|
-
|
|
504
|
+
Note that redirecting only makes sense if you're using remote storage services
|
|
505
|
+
such as AWS S3 or Google Cloud Storage.
|
|
494
506
|
|
|
495
507
|
### Deleting derivatives
|
|
496
508
|
|
|
497
|
-
When
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
509
|
+
When the original attachment is deleted, its uploaded derivatives will not be
|
|
510
|
+
automatically deleted, you will need to do the deletion manually. If you're
|
|
511
|
+
using [backgrounding], you can do this in your `DestroyJob`.
|
|
512
|
+
|
|
513
|
+
If your storage implements `#delete_prefixed`, and you're using the default
|
|
514
|
+
[`:upload_location`](#upload-location), you can delete the directory containing
|
|
515
|
+
derivatives:
|
|
516
|
+
|
|
517
|
+
```rb
|
|
518
|
+
class DestroyJob < ActiveJob::Base
|
|
519
|
+
def perform(attacher_class, data)
|
|
520
|
+
# ... destroy attached file ...
|
|
521
|
+
|
|
522
|
+
derivatives_directory = attacher.file.id + "/"
|
|
523
|
+
storage = attacher.store.storage
|
|
524
|
+
|
|
525
|
+
storage.delete_prefixed(derivatives_directory)
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
Alternatively, you can delete each derivative individually:
|
|
502
531
|
|
|
503
532
|
```rb
|
|
504
|
-
|
|
505
|
-
|
|
533
|
+
class ImageUploader < Shrine
|
|
534
|
+
DERIVATIONS = [
|
|
535
|
+
[:thumbnail, 800, 800],
|
|
536
|
+
[:thumbnail, 600, 400],
|
|
537
|
+
[:thumbnail, 400, 300],
|
|
538
|
+
...
|
|
539
|
+
]
|
|
540
|
+
end
|
|
541
|
+
```
|
|
542
|
+
```rb
|
|
543
|
+
class DestroyJob < ActiveJob::Base
|
|
544
|
+
def perform(attacher_class, data)
|
|
545
|
+
# ... destroy attached file ...
|
|
546
|
+
|
|
547
|
+
attacher.shrine_class::DERIVATIONS.each do |args|
|
|
548
|
+
attacher.file.derivation(*args).delete
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
end
|
|
506
552
|
```
|
|
507
553
|
|
|
508
554
|
## Cache busting
|
|
@@ -538,50 +584,38 @@ uploaded_file.derivation_url(:thumbnail, version: 1)
|
|
|
538
584
|
|
|
539
585
|
## Accessing source file
|
|
540
586
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
```rb
|
|
545
|
-
plugin :derivation_endpoint, include_uploaded_file: true
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
Now the source `UploadedFile` will be passed as the second argument of the
|
|
549
|
-
derivation block:
|
|
587
|
+
Inside the derivation block we can access the source `UploadedFile` object via
|
|
588
|
+
`Shrine::Derivation#source`:
|
|
550
589
|
|
|
551
590
|
```rb
|
|
552
|
-
derivation :thumbnail do |file,
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
591
|
+
derivation :thumbnail do |file, width, height|
|
|
592
|
+
source #=> #<Shrine::UploadedFile>
|
|
593
|
+
source.id #=> "9a7d1bfdad24a76f9cfaff137fe1b5c7.jpg"
|
|
594
|
+
source.storage_key #=> :store
|
|
595
|
+
source.metadata #=> {}
|
|
557
596
|
|
|
558
597
|
# ...
|
|
559
598
|
end
|
|
560
599
|
```
|
|
561
600
|
|
|
562
|
-
By default
|
|
563
|
-
available in the derivation block. This is because metadata
|
|
564
|
-
available would need to be serialized into the derivation
|
|
565
|
-
it longer.
|
|
566
|
-
|
|
601
|
+
By default, when using the derivation endpoint, original metadata of the source
|
|
602
|
+
file won't be available in the derivation block. This is because any metadata
|
|
603
|
+
we would want to have available would need to be serialized into the derivation
|
|
604
|
+
URL, which would make it longer. Instead, you can opt in for the metadata you
|
|
605
|
+
want to have available:
|
|
567
606
|
|
|
568
607
|
```rb
|
|
569
608
|
plugin :derivation_endpoint, metadata: ["filename", "mime_type"]
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
Now `filename` and `mime_type` metadata values will be available in the
|
|
573
|
-
derivation block:
|
|
574
609
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
uploaded_file.metadata #=>
|
|
610
|
+
derivation :thumbnail do |file, width, height|
|
|
611
|
+
source.metadata #=>
|
|
578
612
|
# {
|
|
579
613
|
# "filename" => "nature.jpg",
|
|
580
614
|
# "mime_type" => "image/jpeg"
|
|
581
615
|
# }
|
|
582
616
|
|
|
583
|
-
|
|
584
|
-
|
|
617
|
+
source.original_filename #=> "nature.jpg"
|
|
618
|
+
source.mime_type #=> "image/jpeg"
|
|
585
619
|
|
|
586
620
|
# ...
|
|
587
621
|
end
|
|
@@ -602,17 +636,9 @@ plugin :derivation_endpoint, download_options: {
|
|
|
602
636
|
}
|
|
603
637
|
```
|
|
604
638
|
|
|
605
|
-
If the source file
|
|
606
|
-
|
|
607
|
-
`
|
|
608
|
-
these errors converted to 404 responses by adding them to `:download_errors`:
|
|
609
|
-
|
|
610
|
-
```rb
|
|
611
|
-
plugin :derivation_endpoint, download_errors: [
|
|
612
|
-
Errno::ENOENT, # raised by Shrine::Storage::FileSystem
|
|
613
|
-
Aws::S3::Errors::NotFound, # raised by Shrine::Storage::S3
|
|
614
|
-
]
|
|
615
|
-
```
|
|
639
|
+
If the source file was not found, `Shrine::Derivation::SourceNotFound`
|
|
640
|
+
exception is raised. In a derivation response this is converted into a `404 Not
|
|
641
|
+
Found` response.
|
|
616
642
|
|
|
617
643
|
### Skipping download
|
|
618
644
|
|
|
@@ -621,15 +647,8 @@ disk for you, you can set `:download` to `false`.
|
|
|
621
647
|
|
|
622
648
|
```rb
|
|
623
649
|
plugin :derivation_endpoint, download: false
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
In this case the `UploadedFile` object is yielded to the derivation block
|
|
627
|
-
instead of the raw file:
|
|
628
|
-
|
|
629
|
-
```rb
|
|
630
|
-
derivation :thumbnail do |uploaded_file, width, height|
|
|
631
|
-
uploaded_file #=> #<Shrine::UploadedFile>
|
|
632
650
|
|
|
651
|
+
derivation :thumbnail do |width, height| # source file is not downloaded
|
|
633
652
|
# ...
|
|
634
653
|
end
|
|
635
654
|
```
|
|
@@ -639,10 +658,10 @@ One use case for this is delegating processing to a 3rd-party service:
|
|
|
639
658
|
```rb
|
|
640
659
|
require "down/http"
|
|
641
660
|
|
|
642
|
-
derivation :thumbnail do |
|
|
661
|
+
derivation :thumbnail do |width, height|
|
|
643
662
|
# generate the thumbnail using ImageOptim.com
|
|
644
663
|
down = Down::Http.new(method: :post)
|
|
645
|
-
down.download("https://im2.io/<USERNAME>/#{width}x#{height}/#{
|
|
664
|
+
down.download("https://im2.io/<USERNAME>/#{width}x#{height}/#{source.url}")
|
|
646
665
|
end
|
|
647
666
|
```
|
|
648
667
|
|
|
@@ -735,13 +754,20 @@ uploaded_file #=> #<Shrine::UploadedFile>
|
|
|
735
754
|
uploaded_file.id #=> "bcfd0d67e4a8ec2dc9a6d7ddcf3825a1/thumbnail-500-500"
|
|
736
755
|
```
|
|
737
756
|
|
|
738
|
-
|
|
757
|
+
It can also be called without arguments, in which case it will generate a new
|
|
758
|
+
derivative and upload it.
|
|
759
|
+
|
|
760
|
+
```rb
|
|
761
|
+
derivation.upload # generates derivative and uploads it
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Any additional options will be passed to the uploader.
|
|
739
765
|
|
|
740
766
|
### `#retrieve`
|
|
741
767
|
|
|
742
|
-
`Derivation#retrieve` method returns
|
|
743
|
-
|
|
744
|
-
returned.
|
|
768
|
+
`Derivation#retrieve` method returns `Shrine::UploadedFile` object pointing to
|
|
769
|
+
the uploaded derivative if it exists. If the uploaded derivative does not
|
|
770
|
+
exist, `nil` is returned.
|
|
745
771
|
|
|
746
772
|
```rb
|
|
747
773
|
uploaded_file = derivation.retrieve
|
|
@@ -749,6 +775,18 @@ uploaded_file #=> #<Shrine::UploadedFile>
|
|
|
749
775
|
uploaded_file.id #=> "bcfd0d67e4a8ec2dc9a6d7ddcf3825a1/thumbnail-500-500"
|
|
750
776
|
```
|
|
751
777
|
|
|
778
|
+
### `#opened`
|
|
779
|
+
|
|
780
|
+
`Derivation#opened` method returns opened `Shrine::UploadedFile` object pointing
|
|
781
|
+
to the uploaded derivative if it exists. If the uploaded derivative does not
|
|
782
|
+
exist, `nil` is returned.
|
|
783
|
+
|
|
784
|
+
```rb
|
|
785
|
+
uploaded_file = derivation.opened
|
|
786
|
+
uploaded_file #=> #<Shrine::UploadedFile>
|
|
787
|
+
uploaded_file.id #=> "bcfd0d67e4a8ec2dc9a6d7ddcf3825a1/thumbnail-500-500"
|
|
788
|
+
```
|
|
789
|
+
|
|
752
790
|
### `#delete`
|
|
753
791
|
|
|
754
792
|
`Derivation#delete` method deletes the uploaded derivative file from the
|
|
@@ -774,15 +812,14 @@ derivation.option(:upload_location)
|
|
|
774
812
|
| `:cache_control` | Hash of directives for the `Cache-Control` response header | `{ public: true, max_age: 365*24*60*60 }` |
|
|
775
813
|
| `:disposition` | Whether the browser should attempt to render the derivative (`inline`) or prompt the user to download the file to disk (`attachment`) | `inline` |
|
|
776
814
|
| `:download` | Whether the source uploaded file should be downloaded to disk when the derivation block is called | `true` |
|
|
777
|
-
| `:download_errors` | List of error classes that will be converted to a `404 Not Found` response by the derivation endpoint | `[]` |
|
|
778
815
|
| `:download_options` | Additional options to pass when downloading the source uploaded file | `{}` |
|
|
779
816
|
| `:expires_in` | Number of seconds after which the URL will not be available anymore | `nil` |
|
|
780
817
|
| `:filename` | Filename the browser will assume when the derivative is downloaded to disk | `<name>-<args>-<source id basename>` |
|
|
781
|
-
| `:host` | URL host to use when
|
|
782
|
-
| `:include_uploaded_file` | Whether to include the source uploaded file in the derivation block arguments | `false` |
|
|
818
|
+
| `:host` | URL host to use when for URLs | `nil` |
|
|
783
819
|
| `:metadata` | List of metadata keys the source uploaded file should include in the derivation block | `[]` |
|
|
784
820
|
| `:prefix` | Path prefix added to the URLs | `nil` |
|
|
785
821
|
| `:secret_key` | Key used to sign derivation URLs in order to prevent tampering | required |
|
|
822
|
+
| `:signer` | Proc accepting URL and query params used for custom signing of URLs. | `nil` |
|
|
786
823
|
| `:type` | Media type returned in the `Content-Type` response header in the derivation response | determined from derivative's extension when possible |
|
|
787
824
|
| `:upload` | Whether the generated derivatives will be cached on the storage | `false` |
|
|
788
825
|
| `:upload_location` | Location to which the derivatives will be uploaded on the storage | `<source id>/<name>-<args>` |
|
|
@@ -793,8 +830,56 @@ derivation.option(:upload_location)
|
|
|
793
830
|
| `:upload_storage` | Storage to which the derivations will be uploaded | same storage as the source file |
|
|
794
831
|
| `:version` | Version number to append to the URL for cache busting | `nil` |
|
|
795
832
|
|
|
796
|
-
|
|
833
|
+
## Instrumentation
|
|
834
|
+
|
|
835
|
+
If the `instrumentation` plugin has been loaded, the `determine_mime_type` plugin
|
|
836
|
+
adds instrumentation around derivation processing.
|
|
837
|
+
|
|
838
|
+
```rb
|
|
839
|
+
# instrumentation plugin needs to be loaded *before* derivation_endpoint
|
|
840
|
+
plugin :instrumentation
|
|
841
|
+
plugin :derivation_endpoint
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
Derivation processing will trigger a `derivation.shrine` event with the
|
|
845
|
+
following payload:
|
|
846
|
+
|
|
847
|
+
| Key | Description |
|
|
848
|
+
| :-- | :---- |
|
|
849
|
+
| `:derivation` | `Shrine::Derivation` object for this processing |
|
|
850
|
+
| `:uploader` | The uploader class that sent the event |
|
|
851
|
+
|
|
852
|
+
A default log subscriber is added as well which logs these events:
|
|
853
|
+
|
|
854
|
+
```
|
|
855
|
+
Derivation (492ms) – {:name=>:thumbnail, :args=>[600, 600], :uploader=>Shrine}
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
You can also use your own log subscriber:
|
|
859
|
+
|
|
860
|
+
```rb
|
|
861
|
+
plugin :derivation_endpoint, log_subscriber: -> (event) {
|
|
862
|
+
Shrine.logger.info JSON.generate(
|
|
863
|
+
name: event.name,
|
|
864
|
+
duration: event.duration,
|
|
865
|
+
name: event[:derivation].name,
|
|
866
|
+
args: event[:derivation].args,
|
|
867
|
+
)
|
|
868
|
+
}
|
|
869
|
+
```
|
|
870
|
+
```
|
|
871
|
+
{"name":"derivation","duration":492,"name":"thumbnail","args":[600,600],"uploader":"Shrine"}
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
Or disable logging altogether:
|
|
875
|
+
|
|
876
|
+
```rb
|
|
877
|
+
plugin :derivation_endpoint, log_subscriber: nil
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
[derivation_endpoint]: https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/derivation_endpoint.rb
|
|
797
881
|
[ImageProcessing]: https://github.com/janko/image_processing
|
|
798
882
|
[`Content-Type`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
|
|
799
883
|
[`Content-Disposition`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
|
|
800
884
|
[`Cache-Control`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
|
|
885
|
+
[backgrounding]: https://shrinerb.com/docs/plugins/backgrounding
|