shrine 2.14.0 → 2.15.0
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 +384 -374
- data/README.md +132 -63
- data/doc/advantages.md +191 -109
- data/doc/attacher.md +1 -1
- data/doc/carrierwave.md +4 -4
- data/doc/creating_storages.md +2 -2
- data/doc/design.md +2 -2
- data/doc/direct_s3.md +3 -3
- data/doc/metadata.md +1 -1
- data/doc/multiple_files.md +2 -2
- data/doc/paperclip.md +3 -3
- data/doc/plugins/activerecord.md +92 -0
- data/doc/plugins/add_metadata.md +93 -0
- data/doc/plugins/backgrounding.md +148 -0
- data/doc/plugins/backup.md +29 -0
- data/doc/plugins/cached_attachment_data.md +23 -0
- data/doc/plugins/copy.md +22 -0
- data/doc/plugins/data_uri.md +92 -0
- data/doc/plugins/default_storage.md +16 -0
- data/doc/plugins/default_url.md +33 -0
- data/doc/plugins/default_url_options.md +22 -0
- data/doc/plugins/delete_promoted.md +10 -0
- data/doc/plugins/delete_raw.md +16 -0
- data/doc/plugins/derivation_endpoint.md +747 -0
- data/doc/plugins/determine_mime_type.md +64 -0
- data/doc/plugins/direct_upload.md +170 -0
- data/doc/plugins/download_endpoint.md +83 -0
- data/doc/plugins/dynamic_storage.md +20 -0
- data/doc/plugins/hooks.md +56 -0
- data/doc/plugins/included.md +15 -0
- data/doc/plugins/infer_extension.md +57 -0
- data/doc/plugins/keep_files.md +20 -0
- data/doc/plugins/logging.md +39 -0
- data/doc/plugins/metadata_attribues.md +43 -0
- data/doc/plugins/migration_helpers.md +58 -0
- data/doc/plugins/module_include.md +40 -0
- data/doc/plugins/moving.md +17 -0
- data/doc/plugins/multi_delete.md +18 -0
- data/doc/plugins/parallelize.md +14 -0
- data/doc/plugins/parsed_json.md +9 -0
- data/doc/plugins/presign_endpoint.md +133 -0
- data/doc/plugins/pretty_location.md +29 -0
- data/doc/plugins/processing.md +68 -0
- data/doc/plugins/rack_file.md +49 -0
- data/doc/plugins/rack_response.md +96 -0
- data/doc/plugins/recache.md +27 -0
- data/doc/plugins/refresh_metadata.md +31 -0
- data/doc/plugins/remote_url.md +104 -0
- data/doc/plugins/remove_attachment.md +16 -0
- data/doc/plugins/remove_invalid.md +9 -0
- data/doc/plugins/restore_cached_data.md +14 -0
- data/doc/plugins/sequel.md +64 -0
- data/doc/plugins/signature.md +49 -0
- data/doc/plugins/store_dimensions.md +68 -0
- data/doc/plugins/tempfile.md +40 -0
- data/doc/plugins/upload_endpoint.md +123 -0
- data/doc/plugins/upload_options.md +28 -0
- data/doc/plugins/validation_helpers.md +129 -0
- data/doc/plugins/versions.md +179 -0
- data/doc/processing.md +217 -247
- data/doc/refile.md +3 -3
- data/doc/release_notes/1.0.0.md +143 -0
- data/doc/release_notes/1.1.0.md +184 -0
- data/doc/release_notes/1.2.0.md +37 -0
- data/doc/release_notes/1.3.0.md +90 -0
- data/doc/release_notes/1.4.0.md +167 -0
- data/doc/release_notes/1.4.1.md +9 -0
- data/doc/release_notes/1.4.2.md +20 -0
- data/doc/release_notes/2.0.0.md +173 -0
- data/doc/release_notes/2.0.1.md +12 -0
- data/doc/release_notes/2.1.0.md +59 -0
- data/doc/release_notes/2.1.1.md +8 -0
- data/doc/release_notes/2.10.0.md +52 -0
- data/doc/release_notes/2.10.1.md +6 -0
- data/doc/release_notes/2.11.0.md +69 -0
- data/doc/release_notes/2.12.0.md +65 -0
- data/doc/release_notes/2.13.0.md +146 -0
- data/doc/release_notes/2.14.0.md +278 -0
- data/doc/release_notes/2.15.0.md +82 -0
- data/doc/release_notes/2.2.0.md +98 -0
- data/doc/release_notes/2.3.0.md +50 -0
- data/doc/release_notes/2.3.1.md +10 -0
- data/doc/release_notes/2.4.0.md +87 -0
- data/doc/release_notes/2.4.1.md +29 -0
- data/doc/release_notes/2.5.0.md +130 -0
- data/doc/release_notes/2.6.0.md +254 -0
- data/doc/release_notes/2.6.1.md +14 -0
- data/doc/release_notes/2.7.0.md +180 -0
- data/doc/release_notes/2.8.0.md +95 -0
- data/doc/release_notes/2.9.0.md +82 -0
- data/doc/retrieving_uploads.md +1 -1
- data/doc/storage/file_system.md +96 -0
- data/doc/storage/s3.md +293 -0
- data/doc/validation.md +1 -1
- data/lib/shrine/plugins/_urlsafe_serialization.rb +33 -125
- data/lib/shrine/plugins/activerecord.rb +0 -78
- data/lib/shrine/plugins/add_metadata.rb +0 -80
- data/lib/shrine/plugins/backgrounding.rb +0 -134
- data/lib/shrine/plugins/backup.rb +0 -22
- data/lib/shrine/plugins/cached_attachment_data.rb +0 -15
- data/lib/shrine/plugins/copy.rb +0 -14
- data/lib/shrine/plugins/data_uri.rb +0 -73
- data/lib/shrine/plugins/default_storage.rb +0 -11
- data/lib/shrine/plugins/default_url.rb +0 -25
- data/lib/shrine/plugins/default_url_options.rb +0 -16
- data/lib/shrine/plugins/delete_promoted.rb +0 -6
- data/lib/shrine/plugins/delete_raw.rb +0 -10
- data/lib/shrine/plugins/derivation_endpoint.rb +652 -0
- data/lib/shrine/plugins/determine_mime_type.rb +1 -85
- data/lib/shrine/plugins/direct_upload.rb +0 -155
- data/lib/shrine/plugins/download_endpoint.rb +11 -73
- data/lib/shrine/plugins/dynamic_storage.rb +0 -17
- data/lib/shrine/plugins/hooks.rb +0 -48
- data/lib/shrine/plugins/included.rb +0 -12
- data/lib/shrine/plugins/infer_extension.rb +0 -49
- data/lib/shrine/plugins/keep_files.rb +0 -19
- data/lib/shrine/plugins/logging.rb +0 -39
- data/lib/shrine/plugins/metadata_attributes.rb +0 -35
- data/lib/shrine/plugins/migration_helpers.rb +0 -50
- data/lib/shrine/plugins/module_include.rb +0 -32
- data/lib/shrine/plugins/moving.rb +0 -12
- data/lib/shrine/plugins/multi_delete.rb +0 -13
- data/lib/shrine/plugins/parallelize.rb +0 -8
- data/lib/shrine/plugins/parsed_json.rb +0 -5
- data/lib/shrine/plugins/presign_endpoint.rb +2 -117
- data/lib/shrine/plugins/pretty_location.rb +0 -22
- data/lib/shrine/plugins/processing.rb +0 -55
- data/lib/shrine/plugins/rack_file.rb +0 -39
- data/lib/shrine/plugins/rack_response.rb +0 -81
- data/lib/shrine/plugins/recache.rb +0 -21
- data/lib/shrine/plugins/refresh_metadata.rb +0 -24
- data/lib/shrine/plugins/remote_url.rb +0 -85
- data/lib/shrine/plugins/remove_attachment.rb +0 -10
- data/lib/shrine/plugins/remove_invalid.rb +0 -6
- data/lib/shrine/plugins/restore_cached_data.rb +0 -10
- data/lib/shrine/plugins/sequel.rb +0 -54
- data/lib/shrine/plugins/signature.rb +0 -37
- data/lib/shrine/plugins/store_dimensions.rb +0 -63
- data/lib/shrine/plugins/tempfile.rb +4 -35
- data/lib/shrine/plugins/upload_endpoint.rb +2 -109
- data/lib/shrine/plugins/upload_options.rb +0 -20
- data/lib/shrine/plugins/validation_helpers.rb +0 -36
- data/lib/shrine/plugins/versions.rb +0 -156
- data/lib/shrine/storage/file_system.rb +0 -77
- data/lib/shrine/storage/s3.rb +0 -249
- data/lib/shrine/version.rb +1 -1
- data/shrine.gemspec +2 -2
- metadata +86 -6
@@ -2,43 +2,6 @@
|
|
2
2
|
|
3
3
|
class Shrine
|
4
4
|
module Plugins
|
5
|
-
# The `signature` plugin provides the ability to calculate a hash from file
|
6
|
-
# content. This hash can be used as a checksum or just as a unique
|
7
|
-
# signature for the uploaded file.
|
8
|
-
#
|
9
|
-
# Shrine.plugin :signature
|
10
|
-
#
|
11
|
-
# The plugin adds a `#calculate_signature` instance and class method to the
|
12
|
-
# uploader. The method accepts an IO object and a hashing algorithm, and
|
13
|
-
# returns the calculated hash.
|
14
|
-
#
|
15
|
-
# Shrine.calculate_signature(io, :md5)
|
16
|
-
# #=> "9a0364b9e99bb480dd25e1f0284c8555"
|
17
|
-
#
|
18
|
-
# You can then use the `add_metadata` plugin to add a new metadata field
|
19
|
-
# with the calculated hash.
|
20
|
-
#
|
21
|
-
# plugin :add_metadata
|
22
|
-
#
|
23
|
-
# add_metadata :md5 do |io, context|
|
24
|
-
# calculate_signature(io, :md5)
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# This will generate a hash for each uploaded file, but if you want to
|
28
|
-
# generate one only for the original file, you can add a conditional:
|
29
|
-
#
|
30
|
-
# add_metadata :md5 do |io, context|
|
31
|
-
# calculate_signature(io, :md5) if context[:action] == :cache
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# The following hashing algorithms are supported: SHA1, SHA256, SHA384,
|
35
|
-
# SHA512, MD5, and CRC32.
|
36
|
-
#
|
37
|
-
# You can also choose which format will the calculated hash be encoded in:
|
38
|
-
#
|
39
|
-
# Shrine.calculate_signature(io, :sha256, format: :base64)
|
40
|
-
#
|
41
|
-
# The supported encoding formats are `hex` (default), `base64`, and `none`.
|
42
5
|
module Signature
|
43
6
|
module ClassMethods
|
44
7
|
# Calculates `algorithm` hash of the contents of the IO object, and
|
@@ -2,69 +2,6 @@
|
|
2
2
|
|
3
3
|
class Shrine
|
4
4
|
module Plugins
|
5
|
-
# The `store_dimensions` plugin extracts dimensions of uploaded images and
|
6
|
-
# stores them into the metadata hash (by default it uses the [fastimage]
|
7
|
-
# gem).
|
8
|
-
#
|
9
|
-
# plugin :store_dimensions
|
10
|
-
#
|
11
|
-
# The dimensions are stored as "width" and "height" metadata values on the
|
12
|
-
# Shrine::UploadedFile object. For convenience the plugin also adds
|
13
|
-
# `#width`, `#height` and `#dimensions` reader methods.
|
14
|
-
#
|
15
|
-
# image = uploader.upload(file)
|
16
|
-
#
|
17
|
-
# image.metadata["width"] #=> 300
|
18
|
-
# image.metadata["height"] #=> 500
|
19
|
-
# # or
|
20
|
-
# image.width #=> 300
|
21
|
-
# image.height #=> 500
|
22
|
-
# # or
|
23
|
-
# image.dimensions #=> [300, 500]
|
24
|
-
#
|
25
|
-
# By default the [fastimage] gem is used to extract dimensions. You can
|
26
|
-
# choose a different built-in analyzer via the `:analyzer` option:
|
27
|
-
#
|
28
|
-
# plugin :store_dimensions, analyzer: :mini_magick
|
29
|
-
#
|
30
|
-
# The following analyzers are supported:
|
31
|
-
#
|
32
|
-
# :fastimage
|
33
|
-
# : (Default). Uses the [fastimage] gem to extract dimensions from any IO
|
34
|
-
# object.
|
35
|
-
#
|
36
|
-
# :mini_magick
|
37
|
-
# : Uses the [mini_magick] gem to extract dimensions from File objects. If
|
38
|
-
# non-file IO object is given it will be temporarily downloaded to disk.
|
39
|
-
#
|
40
|
-
# :ruby_vips
|
41
|
-
# : Uses the [ruby-vips] gem to extract dimensions from File objects. If
|
42
|
-
# non-file IO object is given it will be temporarily downloaded to disk.
|
43
|
-
#
|
44
|
-
# You can also create your own custom dimensions analyzer, where you can
|
45
|
-
# reuse any of the built-in analyzers. The analyzer is a lambda that
|
46
|
-
# accepts an IO object and returns width and height as a two-element array,
|
47
|
-
# or `nil` if dimensions could not be extracted.
|
48
|
-
#
|
49
|
-
# plugin :store_dimensions, analyzer: -> (io, analyzers) do
|
50
|
-
# dimensions = analyzers[:fastimage].call(io) # try extracting dimensions with FastImage
|
51
|
-
# dimensions ||= analyzers[:mini_magick].call(io) # otherwise fall back to MiniMagick
|
52
|
-
# dimensions
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# You can use methods for extracting the dimensions directly:
|
56
|
-
#
|
57
|
-
# # or YourUploader.extract_dimensions(io)
|
58
|
-
# Shrine.extract_dimensions(io) # calls the defined analyzer
|
59
|
-
# #=> [300, 400]
|
60
|
-
#
|
61
|
-
# # or YourUploader.dimensions_analyzers
|
62
|
-
# Shrine.dimensions_analyzers[:fastimage].call(io) # calls a built-in analyzer
|
63
|
-
# #=> [300, 400]
|
64
|
-
#
|
65
|
-
# [fastimage]: https://github.com/sdsykes/fastimage
|
66
|
-
# [mini_magick]: https://github.com/minimagick/minimagick
|
67
|
-
# [ruby-vips]: https://github.com/libvips/ruby-vips
|
68
5
|
module StoreDimensions
|
69
6
|
def self.configure(uploader, opts = {})
|
70
7
|
uploader.opts[:dimensions_analyzer] = opts.fetch(:analyzer, uploader.opts.fetch(:dimensions_analyzer, :fastimage))
|
@@ -1,44 +1,13 @@
|
|
1
1
|
class Shrine
|
2
2
|
module Plugins
|
3
|
-
# The `tempfile` plugin makes it easier to reuse a single copy of an
|
4
|
-
# uploaded file on disk.
|
5
|
-
#
|
6
|
-
# Shrine.plugin :tempfile
|
7
|
-
#
|
8
|
-
# The plugin provides the `UploadedFile#tempfile` method, which when called
|
9
|
-
# on an open uploaded file will return a copy of its content on disk. The
|
10
|
-
# first time the method is called the file content will cached into a
|
11
|
-
# temporary file and returned. On any subsequent method calls the cached
|
12
|
-
# temporary file will be returned directly. The temporary file is deleted
|
13
|
-
# when the uploaded file is closed.
|
14
|
-
#
|
15
|
-
# uploaded_file.open do
|
16
|
-
# # ...
|
17
|
-
# uploaded_file.tempfile #=> #<Tempfile:...> (file is cached)
|
18
|
-
# # ...
|
19
|
-
# uploaded_file.tempfile #=> #<Tempfile:...> (cache is returned)
|
20
|
-
# # ...
|
21
|
-
# end # tempfile is deleted
|
22
|
-
#
|
23
|
-
# # OR
|
24
|
-
#
|
25
|
-
# uploaded_file.open
|
26
|
-
# # ...
|
27
|
-
# uploaded_file.tempfile #=> #<Tempfile:...> (file is cached)
|
28
|
-
# # ...
|
29
|
-
# uploaded_file.tempfile #=> #<Tempfile:...> (cache is returned)
|
30
|
-
# # ...
|
31
|
-
# uploaded_file.close # tempfile is deleted
|
32
|
-
#
|
33
|
-
# This plugin also modifies `Shrine.with_file` to call
|
34
|
-
# `UploadedFile#tempfile` when the given IO object is an open
|
35
|
-
# `UploadedFile`. Since `Shrine.with_file` is typically called on the
|
36
|
-
# `Shrine` class directly, it's recommended to load this plugin globally.
|
37
3
|
module Tempfile
|
38
4
|
module ClassMethods
|
39
5
|
def with_file(io)
|
40
6
|
if io.is_a?(UploadedFile) && io.opened?
|
41
|
-
|
7
|
+
# open a new file descriptor for thread safety
|
8
|
+
File.open(io.tempfile.path, binmode: true) do |file|
|
9
|
+
yield file
|
10
|
+
end
|
42
11
|
else
|
43
12
|
super
|
44
13
|
end
|
@@ -7,113 +7,6 @@ require "digest"
|
|
7
7
|
|
8
8
|
class Shrine
|
9
9
|
module Plugins
|
10
|
-
# The `upload_endpoint` plugin provides a Rack endpoint which accepts file
|
11
|
-
# uploads and forwards them to specified storage. On the client side it's
|
12
|
-
# recommended to use [Uppy] for asynchronous uploads.
|
13
|
-
#
|
14
|
-
# plugin :upload_endpoint
|
15
|
-
#
|
16
|
-
# The plugin adds a `Shrine.upload_endpoint` method which, given a storage
|
17
|
-
# identifier, returns a Rack application that accepts multipart POST
|
18
|
-
# requests, and uploads received files to the specified storage. You can
|
19
|
-
# run this Rack application inside your app:
|
20
|
-
#
|
21
|
-
# # config.ru (Rack)
|
22
|
-
# map "/images/upload" do
|
23
|
-
# run ImageUploader.upload_endpoint(:cache)
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# # OR
|
27
|
-
#
|
28
|
-
# # config/routes.rb (Rails)
|
29
|
-
# Rails.application.routes.draw do
|
30
|
-
# mount ImageUploader.upload_endpoint(:cache) => "/images/upload"
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# Asynchronous upload is typically meant to replace the caching phase in
|
34
|
-
# the default synchronous workflow, so we want the uploads to go to
|
35
|
-
# temporary (`:cache`) storage.
|
36
|
-
#
|
37
|
-
# The above will create a `POST /images/upload` endpoint, which uploads the
|
38
|
-
# file received in the `file` param using `ImageUploader`, and returns a
|
39
|
-
# JSON representation of the uploaded file.
|
40
|
-
#
|
41
|
-
# # POST /images/upload
|
42
|
-
# {
|
43
|
-
# "id": "43kewit94.jpg",
|
44
|
-
# "storage": "cache",
|
45
|
-
# "metadata": {
|
46
|
-
# "size": 384393,
|
47
|
-
# "filename": "nature.jpg",
|
48
|
-
# "mime_type": "image/jpeg"
|
49
|
-
# }
|
50
|
-
# }
|
51
|
-
#
|
52
|
-
# This JSON string can now be assigned to an attachment attribute instead
|
53
|
-
# of a raw file. In a form it can be written to a hidden attachment field,
|
54
|
-
# and then it can be assigned as the attachment.
|
55
|
-
#
|
56
|
-
# ## Limiting filesize
|
57
|
-
#
|
58
|
-
# It's good practice to limit the accepted filesize of uploaded files. You
|
59
|
-
# can do that with the `:max_size` option:
|
60
|
-
#
|
61
|
-
# plugin :upload_endpoint, max_size: 20*1024*1024 # 20 MB
|
62
|
-
#
|
63
|
-
# If the uploaded file is larger than the specified value, a `413 Payload
|
64
|
-
# Too Large` response will be returned.
|
65
|
-
#
|
66
|
-
# ## Checksum
|
67
|
-
#
|
68
|
-
# If you want the upload endpoint to verify the integrity of the uploaded
|
69
|
-
# file, you can include the `Content-MD5` header in the request filled with
|
70
|
-
# the base64-encoded MD5 hash of the file that was calculated prior to the
|
71
|
-
# upload, and the endpoint will automatically use it to verify the uploaded
|
72
|
-
# data.
|
73
|
-
#
|
74
|
-
# If the checksums don't match, a `460 Checksum Mismatch` response is
|
75
|
-
# returned.
|
76
|
-
#
|
77
|
-
# ## Context
|
78
|
-
#
|
79
|
-
# The upload context will *not* contain `:record` and `:name` values, as
|
80
|
-
# the upload happens independently of a database record. The endpoint will
|
81
|
-
# send the following upload context:
|
82
|
-
#
|
83
|
-
# * `:action` - holds the value `:upload`
|
84
|
-
# * `:request` - holds an instance of `Rack::Request`
|
85
|
-
#
|
86
|
-
# You can update the upload context via `:upload_context`:
|
87
|
-
#
|
88
|
-
# plugin :upload_endpoint, upload_context: -> (request) do
|
89
|
-
# { location: "my-location" }
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# ## Upload
|
93
|
-
#
|
94
|
-
# You can also customize the upload itself via the `:upload` option:
|
95
|
-
#
|
96
|
-
# plugin :upload_endpoint, upload: -> (io, context, request) do
|
97
|
-
# Shrine.new(:cache).upload(io, context)
|
98
|
-
# end
|
99
|
-
#
|
100
|
-
# ## Response
|
101
|
-
#
|
102
|
-
# The response returned by the endpoint can be customized via the
|
103
|
-
# `:rack_response` option:
|
104
|
-
#
|
105
|
-
# plugin :upload_endpoint, rack_response: -> (uploaded_file, request) do
|
106
|
-
# body = { data: uploaded_file.data, url: uploaded_file.url }.to_json
|
107
|
-
# [201, { "Content-Type" => "application/json" }, [body]]
|
108
|
-
# end
|
109
|
-
#
|
110
|
-
# ## Ad-hoc options
|
111
|
-
#
|
112
|
-
# You can override any of the options above when creating the endpoint:
|
113
|
-
#
|
114
|
-
# Shrine.upload_endpoint(:cache, max_size: 20*1024*1024)
|
115
|
-
#
|
116
|
-
# [Uppy]: https://uppy.io
|
117
10
|
module UploadEndpoint
|
118
11
|
def self.load_dependencies(uploader, opts = {})
|
119
12
|
uploader.plugin :rack_file
|
@@ -237,7 +130,7 @@ class Shrine
|
|
237
130
|
if @rack_response
|
238
131
|
@rack_response.call(object, request)
|
239
132
|
else
|
240
|
-
[200, {"Content-Type" => CONTENT_TYPE_JSON}, [object.to_json]]
|
133
|
+
[200, { "Content-Type" => CONTENT_TYPE_JSON }, [object.to_json]]
|
241
134
|
end
|
242
135
|
end
|
243
136
|
|
@@ -251,7 +144,7 @@ class Shrine
|
|
251
144
|
|
252
145
|
# Used for early returning an error response.
|
253
146
|
def error!(status, message)
|
254
|
-
throw :halt, [status, {"Content-Type" => CONTENT_TYPE_TEXT}, [message]]
|
147
|
+
throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]]
|
255
148
|
end
|
256
149
|
|
257
150
|
# Returns the uploader around the specified storage.
|
@@ -2,26 +2,6 @@
|
|
2
2
|
|
3
3
|
class Shrine
|
4
4
|
module Plugins
|
5
|
-
# The `upload_options` plugin allows you to automatically pass additional
|
6
|
-
# upload options to storage on every upload:
|
7
|
-
#
|
8
|
-
# plugin :upload_options, cache: { acl: "private" }
|
9
|
-
#
|
10
|
-
# Keys are names of the registered storages, and values are either hashes
|
11
|
-
# or blocks.
|
12
|
-
#
|
13
|
-
# plugin :upload_options, store: ->(io, context) do
|
14
|
-
# if [:original, :thumb].include?(context[:version])
|
15
|
-
# { acl: "public-read" }
|
16
|
-
# else
|
17
|
-
# { acl: "private" }
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# If you're uploading the file directly, you can also pass `:upload_options`
|
22
|
-
# to the uploader.
|
23
|
-
#
|
24
|
-
# uploader.upload(file, upload_options: { acl: "public-read" })
|
25
5
|
module UploadOptions
|
26
6
|
def self.configure(uploader, options = {})
|
27
7
|
uploader.opts[:upload_options] ||= {}
|
@@ -2,42 +2,6 @@
|
|
2
2
|
|
3
3
|
class Shrine
|
4
4
|
module Plugins
|
5
|
-
# The `validation_helpers` plugin provides helper methods for validating
|
6
|
-
# attached files.
|
7
|
-
#
|
8
|
-
# plugin :validation_helpers
|
9
|
-
#
|
10
|
-
# Attacher.validate do
|
11
|
-
# validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
|
12
|
-
# validate_max_size 5*1024*1024 if record.guest?
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# The validation methods are instance-level, the `Attacher.validate` block
|
16
|
-
# is evaluated in context of an instance of `Shrine::Attacher`, so you can
|
17
|
-
# easily do conditional validation.
|
18
|
-
#
|
19
|
-
# The validation methods return whether the validation succeeded, allowing
|
20
|
-
# you to do conditional validation.
|
21
|
-
#
|
22
|
-
# if validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
|
23
|
-
# validate_max_width 2000
|
24
|
-
# validate_max_height 2000
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# If you would like to change default validation error messages, you can
|
28
|
-
# pass in the `:default_messages` option to the plugin:
|
29
|
-
#
|
30
|
-
# plugin :validation_helpers, default_messages: {
|
31
|
-
# max_size: ->(max) { I18n.t("errors.file.max_size", max: max) },
|
32
|
-
# mime_type_inclusion: ->(whitelist) { I18n.t("errors.file.mime_type_inclusion", whitelist: whitelist) },
|
33
|
-
# }
|
34
|
-
#
|
35
|
-
# If you would like to change the error message inline, you can pass the
|
36
|
-
# `:message` option to any validation method:
|
37
|
-
#
|
38
|
-
# validate_mime_type_inclusion %w[image/jpeg image/png image/gif], message: "must be JPEG, PNG or GIF"
|
39
|
-
#
|
40
|
-
# For a complete list of all validation helpers, see AttacherMethods.
|
41
5
|
module ValidationHelpers
|
42
6
|
def self.configure(uploader, opts = {})
|
43
7
|
uploader.opts[:validation_default_messages] ||= {}
|
@@ -2,162 +2,6 @@
|
|
2
2
|
|
3
3
|
class Shrine
|
4
4
|
module Plugins
|
5
|
-
# The `versions` plugin enables your uploader to deal with versions, by
|
6
|
-
# allowing you to return a Hash of files when processing.
|
7
|
-
#
|
8
|
-
# plugin :versions
|
9
|
-
#
|
10
|
-
# Here is an example of processing image thumbnails using the
|
11
|
-
# [image_processing] gem:
|
12
|
-
#
|
13
|
-
# require "image_processing/mini_magick"
|
14
|
-
#
|
15
|
-
# plugin :processing
|
16
|
-
#
|
17
|
-
# process(:store) do |io, context|
|
18
|
-
# versions = { original: io } # retain original
|
19
|
-
#
|
20
|
-
# io.download do |original|
|
21
|
-
# pipeline = ImageProcessing::MiniMagick.source(original)
|
22
|
-
#
|
23
|
-
# versions[:large] = pipeline.resize_to_limit!(800, 800)
|
24
|
-
# versions[:medium] = pipeline.resize_to_limit!(500, 500)
|
25
|
-
# versions[:small] = pipeline.resize_to_limit!(300, 300)
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# versions # return the hash of processed files
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# You probably want to load the `delete_raw` plugin to automatically
|
32
|
-
# delete processed files after they have been uploaded.
|
33
|
-
#
|
34
|
-
# Now when you access the stored attachment through the model, a hash of
|
35
|
-
# uploaded files will be returned:
|
36
|
-
#
|
37
|
-
# user.avatar_data #=>
|
38
|
-
# # '{
|
39
|
-
# # "original": {"id":"0gsdf.jpg", "storage":"store", "metadata":{...}},
|
40
|
-
# # "large": {"id":"lg043.jpg", "storage":"store", "metadata":{...}},
|
41
|
-
# # "medium": {"id":"kd9fk.jpg", "storage":"store", "metadata":{...}},
|
42
|
-
# # "small": {"id":"932fl.jpg", "storage":"store", "metadata":{...}}
|
43
|
-
# # }'
|
44
|
-
#
|
45
|
-
# user.avatar #=>
|
46
|
-
# # {
|
47
|
-
# # :original => #<Shrine::UploadedFile @data={"id"=>"0gsdf.jpg", ...}>,
|
48
|
-
# # :large => #<Shrine::UploadedFile @data={"id"=>"lg043.jpg", ...}>,
|
49
|
-
# # :medium => #<Shrine::UploadedFile @data={"id"=>"kd9fk.jpg", ...}>,
|
50
|
-
# # :small => #<Shrine::UploadedFile @data={"id"=>"932fl.jpg", ...}>,
|
51
|
-
# # }
|
52
|
-
#
|
53
|
-
# user.avatar[:medium] #=> #<Shrine::UploadedFile>
|
54
|
-
# user.avatar[:medium].url #=> "/uploads/store/lg043.jpg"
|
55
|
-
#
|
56
|
-
# The plugin also extends the `Attacher#url` to accept versions:
|
57
|
-
#
|
58
|
-
# user.avatar_url(:large)
|
59
|
-
# user.avatar_url(:small, download: true) # with URL options
|
60
|
-
#
|
61
|
-
# `Shrine.uploaded_file` will also instantiate a hash of
|
62
|
-
# `Shrine::UploadedFile` objects if given data with versions. If you want
|
63
|
-
# to apply a change to all files in an attachment, regardless of whether
|
64
|
-
# it consists of a single file or a hash of versions, you can pass a block
|
65
|
-
# to `Shrine.uploaded_file` and it will yield each file:
|
66
|
-
#
|
67
|
-
# Shrine.uploaded_file(attachment_data) do |uploaded_file|
|
68
|
-
# # ...
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# ## Fallbacks
|
72
|
-
#
|
73
|
-
# If versions are processed in a background job, there will be a period
|
74
|
-
# where the user will browse the site before versions have finished
|
75
|
-
# processing. In this period `Attacher#url` will by default fall back to
|
76
|
-
# the original file.
|
77
|
-
#
|
78
|
-
# user.avatar #=> #<Shrine::UploadedFile>
|
79
|
-
# user.avatar_url(:large) # falls back to `user.avatar_url`
|
80
|
-
#
|
81
|
-
# This behaviour is convenient if you want to gracefully degrade to the
|
82
|
-
# cached file until the background job has finished processing. However, if
|
83
|
-
# you would rather provide your own default URLs for versions, you can
|
84
|
-
# disable this fallback:
|
85
|
-
#
|
86
|
-
# plugin :versions, fallback_to_original: false
|
87
|
-
#
|
88
|
-
# If you already have some versions processed in the foreground after a
|
89
|
-
# background job is kicked off (with the `recache` plugin), you can have
|
90
|
-
# URLs for versions that are yet to be processed fall back to existing
|
91
|
-
# versions:
|
92
|
-
#
|
93
|
-
# plugin :versions, fallbacks: {
|
94
|
-
# :thumb_2x => :thumb,
|
95
|
-
# :large_2x => :large,
|
96
|
-
# }
|
97
|
-
#
|
98
|
-
# # ... (background job is kicked off)
|
99
|
-
#
|
100
|
-
# user.avatar_url(:thumb_2x) # returns :thumb URL until :thumb_2x becomes available
|
101
|
-
# user.avatar_url(:large_2x) # returns :large URL until :large_2x becomes available
|
102
|
-
#
|
103
|
-
# ## Arrays
|
104
|
-
#
|
105
|
-
# In addition to Hashes, the plugin also supports Arrays of files. For
|
106
|
-
# example, you might want to split a PDf into pages:
|
107
|
-
#
|
108
|
-
# process(:store) do |io, context|
|
109
|
-
# versions = { pages: [] }
|
110
|
-
#
|
111
|
-
# io.download do |pdf|
|
112
|
-
# page_count = MiniMagick::Image.new(pdf.path).pages.count
|
113
|
-
# pipeline = ImageProcessing::MiniMagick.source(pdf).convert("jpg")
|
114
|
-
#
|
115
|
-
# page_count.times do |page_number|
|
116
|
-
# versions[:pages] << pipeline.loader(page: page_number).call
|
117
|
-
# end
|
118
|
-
# end
|
119
|
-
#
|
120
|
-
# versions
|
121
|
-
# end
|
122
|
-
#
|
123
|
-
# You can also combine Hashes and Arrays, there is no limit to the level of
|
124
|
-
# nesting.
|
125
|
-
#
|
126
|
-
# ## Original file
|
127
|
-
#
|
128
|
-
# It's recommended to always keep the original file after processing
|
129
|
-
# versions, which you can do by adding the yielded `Shrine::UploadedFile`
|
130
|
-
# object as one of the versions, by convention named `:original`:
|
131
|
-
#
|
132
|
-
# process(:store) do |io, context|
|
133
|
-
# # processing thumbnail
|
134
|
-
# { original: io, thumbnail: thumbnail }
|
135
|
-
# end
|
136
|
-
#
|
137
|
-
# If both temporary and permanent storage are Amazon S3, the cached original
|
138
|
-
# will simply be copied over to permanent storage (without any downloading
|
139
|
-
# and reuploading), so in these cases the performance impact of storing the
|
140
|
-
# original file in addition to processed versions is neglibible.
|
141
|
-
#
|
142
|
-
# ## Context
|
143
|
-
#
|
144
|
-
# The version name will be available via `:version` when generating
|
145
|
-
# location or a default URL.
|
146
|
-
#
|
147
|
-
# def generate_location(io, context)
|
148
|
-
# "uploads/#{context[:version]}-#{super}"
|
149
|
-
# end
|
150
|
-
#
|
151
|
-
# Attacher.default_url do |options|
|
152
|
-
# "/images/defaults/#{options[:version]}.jpg"
|
153
|
-
# end
|
154
|
-
#
|
155
|
-
# ## Re-create Versions
|
156
|
-
#
|
157
|
-
# If you want to re-create a single or all versions, refer to the [reprocessing versions] guide for details.
|
158
|
-
#
|
159
|
-
# [reprocessing versions]: https://shrinerb.com/rdoc/files/doc/regenerating_versions_md.html
|
160
|
-
# [image_processing]: https://github.com/janko-m/image_processing
|
161
5
|
module Versions
|
162
6
|
def self.load_dependencies(uploader, *)
|
163
7
|
uploader.plugin :default_url
|