shrine-transloadit 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +107 -80
- data/lib/shrine/plugins/transloadit.rb +124 -53
- data/lib/shrine/plugins/transloadit2.rb +48 -0
- data/shrine-transloadit.gemspec +5 -5
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44fd7310fe53d3e86b451820183df6a5dfb1bbd9
|
4
|
+
data.tar.gz: f4f11d18200d7a233147d9bd1b851d774d6de44c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 875d9ecbe9bbdbd95af66971f992722470dcb71758991132d7c55385d31b14b8aec8fe0b32e9feed266b37e87d2cb9957a774d2a3c62eedff7d5e6ba311f686c
|
7
|
+
data.tar.gz: d768031f8d091a3a9e3152accde460d860e801eddc2a825744b87d590aef1ebc35338a8b3eb60ab1935e256b7eebe63f5fde29c03fc12528cf6653a8ffed7d5b
|
data/README.md
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
Provides [Transloadit] integration for [Shrine].
|
4
4
|
|
5
|
-
Transloadit
|
6
|
-
|
7
|
-
|
5
|
+
Transloadit is a service that helps you handles file uploads, resize, crop and
|
6
|
+
watermark your images, make GIFs, transcode your videos, extract thumbnails,
|
7
|
+
generate audio waveforms, and so much more. In short, Transloadit is the Swiss
|
8
|
+
Army Knife for your files.
|
8
9
|
|
9
10
|
## Setup
|
10
11
|
|
@@ -15,7 +16,7 @@ shrine-transloadit to your current setup:
|
|
15
16
|
|
16
17
|
```rb
|
17
18
|
gem "shrine"
|
18
|
-
gem "aws-sdk" # for Amazon S3
|
19
|
+
gem "aws-sdk-s3", "~> 1.2" # for Amazon S3
|
19
20
|
gem "shrine-transloadit"
|
20
21
|
```
|
21
22
|
|
@@ -107,13 +108,49 @@ class ImageUploader < TransloaditUploader
|
|
107
108
|
medium = original.add_step("resize_500", "/image/resize", width: 500)
|
108
109
|
small = original.add_step("resize_300", "/image/resize", width: 300)
|
109
110
|
|
110
|
-
files = {original: original, medium: medium, small: small}
|
111
|
+
files = { original: original, medium: medium, small: small }
|
111
112
|
|
112
113
|
transloadit_assembly(files, context: context)
|
113
114
|
end
|
114
115
|
end
|
115
116
|
```
|
116
117
|
|
118
|
+
### Multiple files
|
119
|
+
|
120
|
+
Some Transloadit robots might produce multiple files, e.g. `/video/adaptive` or
|
121
|
+
`/document/thumbs`. By default, shrine-transloadit will raise an error when a
|
122
|
+
step returned more than one file, but it's possible to specify the result
|
123
|
+
format in which shrine-transloadit should save the processed files.
|
124
|
+
|
125
|
+
#### `list`
|
126
|
+
|
127
|
+
The `list` format means that the processed files will be saved as a flat list.
|
128
|
+
|
129
|
+
```rb
|
130
|
+
class PdfUploader < TransloaditUploader
|
131
|
+
def transloadit_process(io, context)
|
132
|
+
thumbs = transloadit_file(io)
|
133
|
+
.add_step("thumbs", "/document/thumbs", ...)
|
134
|
+
.multiple(:list) # marks that the result of this pipeline should be saved as a list
|
135
|
+
|
136
|
+
transloadit_assembly(thumbs)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
This will make the processing results save as an array of files:
|
142
|
+
|
143
|
+
```rb
|
144
|
+
pdf.file #=>
|
145
|
+
# [
|
146
|
+
# #<Shrine::UploadedFile ...>
|
147
|
+
# #<Shrine::UploadedFile ...>
|
148
|
+
# ...
|
149
|
+
# ]
|
150
|
+
|
151
|
+
pdf.file[0] # page 1
|
152
|
+
```
|
153
|
+
|
117
154
|
### Webhooks
|
118
155
|
|
119
156
|
Transloadit performs its processing asynchronously, and you can provide a URL
|
@@ -143,33 +180,59 @@ CSRF token for this route.
|
|
143
180
|
|
144
181
|
### Direct uploads
|
145
182
|
|
146
|
-
Transloadit supports direct uploads, allowing you to do
|
147
|
-
|
148
|
-
|
149
|
-
|
183
|
+
Transloadit supports direct uploads, allowing you to do some processing on the
|
184
|
+
file before it's submitted to the app. It's recommended that you use [Uppy] for
|
185
|
+
client side uploads, take a look its [Transloadit plugin][uppy transloadit] for
|
186
|
+
more details.
|
150
187
|
|
151
188
|
```js
|
152
|
-
//
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
189
|
+
// https://uppy.io/docs/transloadit/
|
190
|
+
var uppy = Uppy.Core({})
|
191
|
+
.use(Uppy.FileInput, {
|
192
|
+
target: fileInput.parentNode,
|
193
|
+
allowMultipleFiles: fileInput.multiple
|
194
|
+
})
|
195
|
+
.use(Uppy.Tus, {})
|
196
|
+
.use(Uppy.Transloadit, {
|
197
|
+
waitForEncoding: true,
|
198
|
+
params: {
|
199
|
+
auth: { key: 'YOUR_TRANSLOADIT_KEY' },
|
200
|
+
steps: {
|
201
|
+
// ...
|
163
202
|
}
|
164
203
|
}
|
165
|
-
}
|
166
|
-
|
204
|
+
})
|
205
|
+
|
206
|
+
uppy.run()
|
167
207
|
```
|
168
208
|
|
169
|
-
When direct upload finishes
|
170
|
-
|
171
|
-
|
172
|
-
|
209
|
+
When direct upload finishes Transloadit will return processing results, which
|
210
|
+
you can use to construct the Shrine uploaded file data and send it as the
|
211
|
+
Shrine attachment. Let's assume that we didn't provide and export step, in
|
212
|
+
which case Transloadit will return temporary URL to the processed files, which
|
213
|
+
we can use as the uploaded file identifier:
|
214
|
+
|
215
|
+
```js
|
216
|
+
uppy.on('transloadit:result', function (stepName, result) {
|
217
|
+
var uploadedFileData = JSON.stringify({
|
218
|
+
id: result['ssl_url'],
|
219
|
+
storage: 'cache',
|
220
|
+
metadata: {
|
221
|
+
size: result['size'],
|
222
|
+
filename: result['name'],
|
223
|
+
mime_type: result['mime'],
|
224
|
+
width: result['meta'] && result['meta']['width'],
|
225
|
+
height: result['meta'] && result['meta']['height'],
|
226
|
+
transloadit: result['meta'],
|
227
|
+
}
|
228
|
+
})
|
229
|
+
|
230
|
+
// send `uploadedFileData` as the Shrine attachment
|
231
|
+
})
|
232
|
+
```
|
233
|
+
|
234
|
+
In order for using an URL as the uploaded file identifier to work, you'll need
|
235
|
+
to set [shrine-url] as your temporary storage:
|
173
236
|
|
174
237
|
```rb
|
175
238
|
gem "shrine-url"
|
@@ -180,29 +243,7 @@ require "shrine/storage/url"
|
|
180
243
|
Shrine.storages[:cache] = Shrine::Storage::Url.new
|
181
244
|
```
|
182
245
|
|
183
|
-
|
184
|
-
you need to transform the Transloadit hash into Shrine's uploaded file
|
185
|
-
representation, using the URL as the "id":
|
186
|
-
|
187
|
-
```js
|
188
|
-
{
|
189
|
-
id: data['url'], // we save the URL
|
190
|
-
storage: 'cache',
|
191
|
-
metadata: {
|
192
|
-
size: data['size'],
|
193
|
-
filename: data['name'],
|
194
|
-
mime_type: data['mime'],
|
195
|
-
width: data['meta'] && data['meta']['width'],
|
196
|
-
height: data['meta'] && data['meta']['height'],
|
197
|
-
transloadit: data['meta'],
|
198
|
-
}
|
199
|
-
}
|
200
|
-
```
|
201
|
-
|
202
|
-
If the result of direct upload processing are multiple files (e.g. video
|
203
|
-
thumbnails), you need to assign them to individual records.
|
204
|
-
|
205
|
-
See the **[demo app]** for a complete implementation of direct uploads.
|
246
|
+
See the **[demo app]** for a complete example of direct uploads.
|
206
247
|
|
207
248
|
### Templates
|
208
249
|
|
@@ -342,7 +383,7 @@ file.add_step(transloadit_import_step("import", io))
|
|
342
383
|
```
|
343
384
|
|
344
385
|
```rb
|
345
|
-
transloadit_assembly({original: original, thumb: thumb})
|
386
|
+
transloadit_assembly({ original: original, thumb: thumb })
|
346
387
|
|
347
388
|
# is equivalent to
|
348
389
|
|
@@ -355,38 +396,23 @@ transloadit_assembly({
|
|
355
396
|
If you want/need to generate these steps yourself, you can just use the
|
356
397
|
expanded forms.
|
357
398
|
|
358
|
-
###
|
399
|
+
### Errors
|
359
400
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
`Transloadit::Assembly`.
|
401
|
+
Any errors that happen on assembly submission or during processing will be
|
402
|
+
propagated as a `Shrine::Plugins::Transloadit::ResponseError`, which
|
403
|
+
additionally carries the Transloadit response in the `#response` attribute.
|
364
404
|
|
365
405
|
```rb
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
end
|
372
|
-
end
|
373
|
-
```
|
374
|
-
|
375
|
-
The import/export helper methods simply generate a `Transloadit::Step` object,
|
376
|
-
and you can pass additional options:
|
377
|
-
|
378
|
-
```rb
|
379
|
-
class MyUploader < TransloaditUploader
|
380
|
-
def transloadit_process(io, context)
|
381
|
-
transloadit_import_step("import", io) #=> #<Transloadit::Step>
|
382
|
-
transloadit_export_step("export", path: "mypath") #=> #<Transloadit::Step>
|
406
|
+
post "/webhooks/transloadit" do
|
407
|
+
begin
|
408
|
+
TransloaditUploader::Attacher.transloadit_save(params)
|
409
|
+
rescue Shrine::Plugins::Transloadit::ResponseError => exception
|
410
|
+
exception.response # include this response in your exception notification
|
383
411
|
end
|
412
|
+
# ...
|
384
413
|
end
|
385
414
|
```
|
386
415
|
|
387
|
-
The `#add_step` method for `TransloaditFile` is just a convenient way to add
|
388
|
-
steps where `:use` is automatically set to previous step.
|
389
|
-
|
390
416
|
### Testing
|
391
417
|
|
392
418
|
In development or test environment you cannot use webhooks, because Transloadit
|
@@ -434,8 +460,8 @@ project root containing your Transloadit and Amazon S3 credentials:
|
|
434
460
|
|
435
461
|
```sh
|
436
462
|
# .env
|
437
|
-
|
438
|
-
|
463
|
+
TRANSLOADIT_KEY="..."
|
464
|
+
TRANSLOADIT_SECRET="..."
|
439
465
|
S3_BUCKET="..."
|
440
466
|
S3_REGION="..."
|
441
467
|
S3_ACCESS_KEY_ID="..."
|
@@ -452,13 +478,14 @@ $ bundle exec rake test
|
|
452
478
|
|
453
479
|
[MIT](/LICENSE.txt)
|
454
480
|
|
455
|
-
[Shrine]: https://github.com/
|
481
|
+
[Shrine]: https://github.com/shrinerb/shrine
|
456
482
|
[Transloadit]: https://transloadit.com/
|
457
483
|
[many storage services]: https://transloadit.com/docs/conversion-robots/#file-export-robots
|
458
484
|
[transloadit gem]: https://github.com/transloadit/ruby-sdk
|
459
485
|
[robot and arguments]: https://transloadit.com/docs/conversion-robots/
|
460
486
|
[templates]: https://transloadit.com/docs/#templates
|
461
|
-
[
|
487
|
+
[Uppy]: https://uppy.io
|
488
|
+
[uppy transloadit]: https://uppy.io/docs/transloadit/
|
462
489
|
[demo app]: /demo
|
463
490
|
[direct uploads to Transloadit]: #direct-uploads
|
464
|
-
[shrine-url]: https://github.com/
|
491
|
+
[shrine-url]: https://github.com/shrinerb/shrine-url
|
@@ -7,6 +7,17 @@ require "openssl"
|
|
7
7
|
class Shrine
|
8
8
|
module Plugins
|
9
9
|
module Transloadit
|
10
|
+
class Error < Shrine::Error; end
|
11
|
+
|
12
|
+
class ResponseError < Error
|
13
|
+
attr_reader :response
|
14
|
+
|
15
|
+
def initialize(response)
|
16
|
+
@response = response
|
17
|
+
super("#{response["error"]}: #{response["reason"] || response["message"]}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
10
21
|
# Accepts Transloadit credentials via `:auth_key` and `:auth_secret`.
|
11
22
|
#
|
12
23
|
# If :cache storage wasn't assigned, it will be assigned to a URL storage
|
@@ -43,8 +54,7 @@ class Shrine
|
|
43
54
|
# params that Transloadit POSTed to the endpoint. It checks the
|
44
55
|
# signature, loads the attacher, saves processing results to the record.
|
45
56
|
def transloadit_save(params)
|
46
|
-
|
47
|
-
check_transloadit_signature!(params)
|
57
|
+
shrine_class.verify_transloadit_signature!(params)
|
48
58
|
response = JSON.parse(params["transloadit"])
|
49
59
|
data = response["fields"]["attacher"]
|
50
60
|
attacher = self.load(data)
|
@@ -52,18 +62,6 @@ class Shrine
|
|
52
62
|
attacher.transloadit_save(response, valid: attacher.get == cached_file)
|
53
63
|
attacher
|
54
64
|
end
|
55
|
-
|
56
|
-
# Checks if the webhook has indeed been triggered by Transloadit, by
|
57
|
-
# checking if sent signature matches the calculated signature, and
|
58
|
-
# raising a `Shrine::Error` if signatures don't match.
|
59
|
-
def check_transloadit_signature!(params)
|
60
|
-
sent_signature = params["signature"]
|
61
|
-
payload = params["transloadit"]
|
62
|
-
algorithm = OpenSSL::Digest.new('sha1')
|
63
|
-
secret = shrine_class.opts[:transloadit_auth_secret]
|
64
|
-
calculated_signature = OpenSSL::HMAC.hexdigest(algorithm, secret, payload)
|
65
|
-
raise Error, "Transloadit signature that was sent doesn't match the calculated signature" if calculated_signature != sent_signature
|
66
|
-
end
|
67
65
|
end
|
68
66
|
|
69
67
|
module AttacherMethods
|
@@ -76,13 +74,13 @@ class Shrine
|
|
76
74
|
# into cached file's metadata, which can then be reloaded at will for
|
77
75
|
# checking progress of the assembly.
|
78
76
|
#
|
79
|
-
#
|
77
|
+
# Raises a `Shrine::Plugins::Transloadit::ResponseError` if Transloadit returned an error.
|
80
78
|
def transloadit_process(cached_file = get)
|
81
79
|
assembly = store.transloadit_process(cached_file, context)
|
82
80
|
assembly.options[:fields] ||= {}
|
83
81
|
assembly.options[:fields]["attacher"] = self.dump.merge("attachment" => cached_file.to_json)
|
84
82
|
response = assembly.create!
|
85
|
-
raise
|
83
|
+
raise ResponseError.new(response.body) if response["error"]
|
86
84
|
cached_file.metadata["transloadit_response"] = response.body.to_json
|
87
85
|
swap(cached_file) or _set(cached_file)
|
88
86
|
end
|
@@ -94,16 +92,37 @@ class Shrine
|
|
94
92
|
# If attachment has changed in the meanwhile, meaning the result of
|
95
93
|
# this processing is no longer valid, it deletes the processed files
|
96
94
|
# from the main storage.
|
95
|
+
#
|
96
|
+
# Raises a `Shrine::Plugins::Transloadit::ResponseError` if Transloadit returned an error.
|
97
97
|
def transloadit_save(response, valid: true)
|
98
|
+
raise ResponseError.new(response) if response["error"]
|
99
|
+
|
98
100
|
if versions = response["fields"]["versions"]
|
99
|
-
stored_file = versions.inject({}) do |hash, (name,
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
stored_file = versions.inject({}) do |hash, (name, step_name)|
|
102
|
+
results = response["results"].fetch(step_name)
|
103
|
+
uploaded_files = results.map { |result| store.transloadit_uploaded_file(result) }
|
104
|
+
multiple = response["fields"]["multiple"].to_h[name]
|
105
|
+
|
106
|
+
if multiple == "list"
|
107
|
+
hash.merge!(name => uploaded_files)
|
108
|
+
elsif uploaded_files.one?
|
109
|
+
hash.merge!(name => uploaded_files[0])
|
110
|
+
else
|
111
|
+
raise Error, "Step produced multiple files but wasn't marked as multiple"
|
112
|
+
end
|
103
113
|
end
|
104
114
|
else
|
105
|
-
|
106
|
-
|
115
|
+
results = response["results"].values.last
|
116
|
+
uploaded_files = results.map { |result| store.transloadit_uploaded_file(result) }
|
117
|
+
multiple = response["fields"]["multiple"]
|
118
|
+
|
119
|
+
if multiple == "list"
|
120
|
+
stored_file = uploaded_files
|
121
|
+
elsif uploaded_files.one?
|
122
|
+
stored_file = uploaded_files[0]
|
123
|
+
else
|
124
|
+
raise Error, "Step produced multiple files but wasn't marked as multiple"
|
125
|
+
end
|
107
126
|
end
|
108
127
|
|
109
128
|
if valid
|
@@ -123,6 +142,19 @@ class Shrine
|
|
123
142
|
secret: opts[:transloadit_auth_secret],
|
124
143
|
)
|
125
144
|
end
|
145
|
+
|
146
|
+
# Checks if the webhook has indeed been triggered by Transloadit, by
|
147
|
+
# checking if sent signature matches the calculated signature, and
|
148
|
+
# raising a `Shrine::Plugins::Transloadit::Error` if signatures don't
|
149
|
+
# match.
|
150
|
+
def verify_transloadit_signature!(params)
|
151
|
+
sent_signature = params["signature"]
|
152
|
+
payload = params["transloadit"]
|
153
|
+
algorithm = OpenSSL::Digest.new('sha1')
|
154
|
+
secret = opts[:transloadit_auth_secret]
|
155
|
+
calculated_signature = OpenSSL::HMAC.hexdigest(algorithm, secret, payload)
|
156
|
+
raise Error, "Received signature doesn't match the calculated signature" if calculated_signature != sent_signature
|
157
|
+
end
|
126
158
|
end
|
127
159
|
|
128
160
|
module InstanceMethods
|
@@ -229,34 +261,14 @@ class Shrine
|
|
229
261
|
# assembly's payload, so that later in the webhook it can be used to
|
230
262
|
# construct a hash of versions.
|
231
263
|
def transloadit_assembly(value, context: {}, **options)
|
232
|
-
options[
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
versions.each do |name, transloadit_file|
|
239
|
-
raise Error, "The given TransloaditFile is missing an import step" if !transloadit_file.imported?
|
240
|
-
unless transloadit_file.exported?
|
241
|
-
path = generate_location(transloadit_file, context.merge(version: name)) + ".${file.ext}"
|
242
|
-
export_step = transloadit_export_step("export_#{name}", path: path)
|
243
|
-
transloadit_file = transloadit_file.add_step(export_step)
|
244
|
-
end
|
245
|
-
options[:steps] |= transloadit_file.steps
|
246
|
-
options[:fields]["versions"][name] = transloadit_file.name
|
247
|
-
end
|
248
|
-
elsif (transloadit_file = value).is_a?(TransloaditFile)
|
249
|
-
raise Error, "The given TransloaditFile is missing an import step" if !transloadit_file.imported?
|
250
|
-
unless transloadit_file.exported?
|
251
|
-
path = generate_location(transloadit_file, context) + ".${file.ext}"
|
252
|
-
export_step = transloadit_export_step("export", path: path)
|
253
|
-
transloadit_file = transloadit_file.add_step(export_step)
|
254
|
-
end
|
255
|
-
options[:steps] += transloadit_file.steps
|
256
|
-
elsif (template = value).is_a?(String)
|
257
|
-
options[:template_id] = template
|
264
|
+
options = { steps: [], fields: {} }.merge(options)
|
265
|
+
|
266
|
+
case value
|
267
|
+
when TransloaditFile then transloadit_assembly_update_single!(value, context, options)
|
268
|
+
when Hash then transloadit_assembly_update_versions!(value, context, options)
|
269
|
+
when String then transloadit_assembly_update_template!(value, context, options)
|
258
270
|
else
|
259
|
-
raise Error, "
|
271
|
+
raise Error, "Assembly value has to be either a TransloaditFile, a hash of TransloaditFile objects, or a template"
|
260
272
|
end
|
261
273
|
|
262
274
|
if options[:steps].uniq(&:name) != options[:steps]
|
@@ -270,6 +282,44 @@ class Shrine
|
|
270
282
|
def transloadit
|
271
283
|
@transloadit ||= self.class.transloadit
|
272
284
|
end
|
285
|
+
|
286
|
+
private
|
287
|
+
|
288
|
+
# Updates assembly options for single files.
|
289
|
+
def transloadit_assembly_update_single!(transloadit_file, context, options)
|
290
|
+
raise Error, "The given TransloaditFile is missing an import step" if !transloadit_file.imported?
|
291
|
+
unless transloadit_file.exported?
|
292
|
+
path = generate_location(transloadit_file, context) + ".${file.ext}"
|
293
|
+
export_step = transloadit_export_step("export", path: path)
|
294
|
+
transloadit_file = transloadit_file.add_step(export_step)
|
295
|
+
end
|
296
|
+
options[:steps] += transloadit_file.steps
|
297
|
+
options[:fields]["multiple"] = transloadit_file.multiple
|
298
|
+
end
|
299
|
+
|
300
|
+
# Updates assembly options for a hash of versions.
|
301
|
+
def transloadit_assembly_update_versions!(versions, context, options)
|
302
|
+
raise Error, "The versions Shrine plugin isn't loaded" if !defined?(Shrine::Plugins::Versions)
|
303
|
+
options[:fields]["versions"] = {}
|
304
|
+
options[:fields]["multiple"] = {}
|
305
|
+
versions.each do |name, transloadit_file|
|
306
|
+
raise Error, "The :#{name} version value is not a TransloaditFile" if !transloadit_file.is_a?(TransloaditFile)
|
307
|
+
raise Error, "The given TransloaditFile is missing an import step" if !transloadit_file.imported?
|
308
|
+
unless transloadit_file.exported?
|
309
|
+
path = generate_location(transloadit_file, context.merge(version: name)) + ".${file.ext}"
|
310
|
+
export_step = transloadit_export_step("export_#{name}", path: path)
|
311
|
+
transloadit_file = transloadit_file.add_step(export_step)
|
312
|
+
end
|
313
|
+
options[:steps] |= transloadit_file.steps
|
314
|
+
options[:fields]["versions"][name] = transloadit_file.name
|
315
|
+
options[:fields]["multiple"][name] = transloadit_file.multiple
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Updates assembly options for a template.
|
320
|
+
def transloadit_assembly_update_template!(template, context, options)
|
321
|
+
options[:template_id] = template
|
322
|
+
end
|
273
323
|
end
|
274
324
|
|
275
325
|
module FileMethods
|
@@ -290,9 +340,10 @@ class Shrine
|
|
290
340
|
class TransloaditFile
|
291
341
|
attr_reader :transloadit, :steps
|
292
342
|
|
293
|
-
def initialize(transloadit:, steps: [])
|
343
|
+
def initialize(transloadit:, steps: [], multiple: nil)
|
294
344
|
@transloadit = transloadit
|
295
|
-
@steps
|
345
|
+
@steps = steps
|
346
|
+
@multiple = multiple
|
296
347
|
end
|
297
348
|
|
298
349
|
# Adds a step to the pipeline, automatically setting :use to the
|
@@ -308,10 +359,19 @@ class Shrine
|
|
308
359
|
end
|
309
360
|
|
310
361
|
unless step.options[:use]
|
311
|
-
step.use
|
362
|
+
step.use steps.last if steps.any?
|
312
363
|
end
|
313
364
|
|
314
|
-
|
365
|
+
transloadit_file(steps: steps + [step])
|
366
|
+
end
|
367
|
+
|
368
|
+
# Specify the result format.
|
369
|
+
def multiple(format = nil)
|
370
|
+
if format
|
371
|
+
transloadit_file(multiple: format)
|
372
|
+
else
|
373
|
+
@multiple
|
374
|
+
end
|
315
375
|
end
|
316
376
|
|
317
377
|
# The key that Transloadit will use in its processing results for the
|
@@ -334,6 +394,17 @@ class Shrine
|
|
334
394
|
def exported?
|
335
395
|
@steps.any? && @steps.last.robot.end_with?("/store")
|
336
396
|
end
|
397
|
+
|
398
|
+
private
|
399
|
+
|
400
|
+
def transloadit_file(**options)
|
401
|
+
TransloaditFile.new(
|
402
|
+
transloadit: @transloadit,
|
403
|
+
steps: @steps,
|
404
|
+
multiple: @multiple,
|
405
|
+
**options
|
406
|
+
)
|
407
|
+
end
|
337
408
|
end
|
338
409
|
end
|
339
410
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "transloadit"
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "json"
|
5
|
+
require "openssl"
|
6
|
+
|
7
|
+
class Shrine
|
8
|
+
module Plugins
|
9
|
+
module Transloadit2
|
10
|
+
class Error < Shrine::Error; end
|
11
|
+
|
12
|
+
class ResponseError < Error
|
13
|
+
attr_reader :response
|
14
|
+
|
15
|
+
def initialize(response)
|
16
|
+
@response = response
|
17
|
+
super("#{response["error"]}: #{response["reason"] || response["message"]} (Assembly ID: #{response["assembly_id"]})")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Accepts Transloadit credentials via `:auth_key` and `:auth_secret`.
|
22
|
+
#
|
23
|
+
# If :cache storage wasn't assigned, it will be assigned to a URL storage
|
24
|
+
# for direct uploads.
|
25
|
+
#
|
26
|
+
# If promoting was not yet overriden, it is set to automatically trigger
|
27
|
+
# Transloadit processing defined in `Shrine#transloadit_process`.
|
28
|
+
def self.configure(uploader, opts = {})
|
29
|
+
uploader.opts[:transloadit_auth_key] = opts.fetch(:auth_key, uploader.opts[:transloadit_auth_key])
|
30
|
+
uploader.opts[:transloadit_auth_secret] = opts.fetch(:auth_secret, uploader.opts[:transloadit_auth_secret])
|
31
|
+
|
32
|
+
raise Error, "The :auth_key is required for transloadit plugin" if uploader.opts[:transloadit_auth_key].nil?
|
33
|
+
raise Error, "The :auth_secret is required for transloadit plugin" if uploader.opts[:transloadit_auth_secret].nil?
|
34
|
+
|
35
|
+
uploader.opts[:backgrounding_promote] ||= proc { transloadit_process }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Load the backgrounding plugin to override promoting, and load the
|
39
|
+
# versions plugin to automatically save steps.
|
40
|
+
def self.load_dependencies(uploader, opts = {})
|
41
|
+
uploader.plugin :backgrounding
|
42
|
+
uploader.plugin :versions
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
register_plugin(:transloadit2, Transloadit2)
|
47
|
+
end
|
48
|
+
end
|
data/shrine-transloadit.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "shrine-transloadit"
|
3
|
-
gem.version = "0.
|
3
|
+
gem.version = "0.5.0"
|
4
4
|
|
5
|
-
gem.required_ruby_version = ">= 2.
|
5
|
+
gem.required_ruby_version = ">= 2.2"
|
6
6
|
|
7
7
|
gem.summary = "Provides Transloadit integration for Shrine."
|
8
|
-
gem.homepage = "https://github.com/
|
8
|
+
gem.homepage = "https://github.com/shrinerb/shrine-transloadit"
|
9
9
|
gem.authors = ["Janko Marohnić"]
|
10
10
|
gem.email = ["janko.marohnic@gmail.com"]
|
11
11
|
gem.license = "MIT"
|
@@ -13,14 +13,14 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.files = Dir["README.md", "LICENSE.txt", "lib/**/*.rb", "*.gemspec"]
|
14
14
|
gem.require_path = "lib"
|
15
15
|
|
16
|
-
gem.add_dependency "shrine", "~> 2.
|
16
|
+
gem.add_dependency "shrine", "~> 2.9"
|
17
17
|
gem.add_dependency "transloadit", "~> 2.0"
|
18
18
|
|
19
19
|
gem.add_development_dependency "rake"
|
20
20
|
gem.add_development_dependency "minitest"
|
21
21
|
gem.add_development_dependency "minitest-hooks"
|
22
22
|
gem.add_development_dependency "dotenv"
|
23
|
-
gem.add_development_dependency "aws-sdk"
|
23
|
+
gem.add_development_dependency "aws-sdk-s3", "~> 1.2"
|
24
24
|
gem.add_development_dependency "sequel"
|
25
25
|
gem.add_development_dependency "sqlite3"
|
26
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shrine-transloadit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
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: 2018-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shrine
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.9'
|
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: '2.
|
26
|
+
version: '2.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: transloadit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +95,19 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name: aws-sdk
|
98
|
+
name: aws-sdk-s3
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '1.2'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '1.2'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: sequel
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,8 +146,9 @@ files:
|
|
146
146
|
- LICENSE.txt
|
147
147
|
- README.md
|
148
148
|
- lib/shrine/plugins/transloadit.rb
|
149
|
+
- lib/shrine/plugins/transloadit2.rb
|
149
150
|
- shrine-transloadit.gemspec
|
150
|
-
homepage: https://github.com/
|
151
|
+
homepage: https://github.com/shrinerb/shrine-transloadit
|
151
152
|
licenses:
|
152
153
|
- MIT
|
153
154
|
metadata: {}
|
@@ -159,7 +160,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
159
160
|
requirements:
|
160
161
|
- - ">="
|
161
162
|
- !ruby/object:Gem::Version
|
162
|
-
version: '2.
|
163
|
+
version: '2.2'
|
163
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
165
|
requirements:
|
165
166
|
- - ">="
|
@@ -167,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
168
|
version: '0'
|
168
169
|
requirements: []
|
169
170
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.6.11
|
171
172
|
signing_key:
|
172
173
|
specification_version: 4
|
173
174
|
summary: Provides Transloadit integration for Shrine.
|