shrine 2.1.1 → 2.2.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.

@@ -1,25 +1,22 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The versions plugin enables your uploader to deal with versions. To
4
- # generate versions, you simply return a hash of versions in `Shrine#process`.
3
+ # The versions plugin enables your uploader to deal with versions, by
4
+ # allowing you to return a Hash of files when processing.
5
+ #
6
+ # plugin :versions
7
+ #
5
8
  # Here is an example of processing image thumbnails using the
6
9
  # [image_processing] gem:
7
10
  #
8
- # require "image_processing/mini_magick"
9
- #
10
- # class ImageUploader < Shrine
11
- # include ImageProcessing::MiniMagick
12
- # plugin :versions
11
+ # include ImageProcessing::MiniMagick
12
+ # plugin :processing
13
13
  #
14
- # def process(io, context)
15
- # if context[:phase] == :store
16
- # size_700 = resize_to_limit(io.download, 700, 700)
17
- # size_500 = resize_to_limit(size_700, 500, 500)
18
- # size_300 = resize_to_limit(size_500, 300, 300)
14
+ # process(:store) do |io, context|
15
+ # size_700 = resize_to_limit(io.download, 700, 700)
16
+ # size_500 = resize_to_limit(size_700, 500, 500)
17
+ # size_300 = resize_to_limit(size_500, 300, 300)
19
18
  #
20
- # {large: size_700, medium: size_500, small: size_300}
21
- # end
22
- # end
19
+ # {large: size_700, medium: size_500, small: size_300}
23
20
  # end
24
21
  #
25
22
  # Note that if you want to keep the original file, you can forward it as is
@@ -27,11 +24,9 @@ class Shrine
27
24
  # an IO-like object), which might avoid downloading depending on the
28
25
  # storage:
29
26
  #
30
- # def process(io, context)
31
- # if context[:phase] == :store
32
- # # ...
33
- # {original: io, thumb: thumb}
34
- # end
27
+ # process(:store) do |io, context|
28
+ # # processing thumbnail
29
+ # {original: io, thumbnail: thumbnail}
35
30
  # end
36
31
  #
37
32
  # Now when you access the stored attachment through the model, a hash of
@@ -89,8 +84,12 @@ class Shrine
89
84
  #
90
85
  # user.avatar_url(:medium, download: true)
91
86
  #
92
- # You can also easily generate default URLs for specific versions, since
93
- # the `context` will include the version name:
87
+ # The `context` will now also include the version name, which you can use
88
+ # when generating a location or a default URL:
89
+ #
90
+ # def generate_location(io, context)
91
+ # "uploads/#{context[:version]}-#{super}"
92
+ # end
94
93
  #
95
94
  # plugin :default_url do |context|
96
95
  # "/images/defaults/#{context[:version]}.jpg"
@@ -211,7 +210,7 @@ class Shrine
211
210
 
212
211
  def assign_cached(value)
213
212
  cached_file = uploaded_file(value)
214
- warn "Generating versions in the :cache phase is deprecated and will be forbidden in Shrine 3." if cached_file.is_a?(Hash)
213
+ warn "Generating versions in the :cache action is deprecated and will be forbidden in Shrine 3." if cached_file.is_a?(Hash)
215
214
  super(cached_file)
216
215
  end
217
216
  end
@@ -142,11 +142,6 @@ class Shrine
142
142
  path(id).open("rb", &block)
143
143
  end
144
144
 
145
- # Returns the contents of the file as a String.
146
- def read(id)
147
- path(id).binread
148
- end
149
-
150
145
  # Returns true if the file exists on the filesystem.
151
146
  def exists?(id)
152
147
  path(id).exist?
@@ -37,7 +37,6 @@ class Shrine
37
37
 
38
38
  lint_download(id)
39
39
  lint_open(id)
40
- lint_read(id)
41
40
  lint_exists(id)
42
41
  lint_url(id)
43
42
  lint_delete(id)
@@ -52,8 +51,10 @@ class Shrine
52
51
  lint_multi_delete(id)
53
52
  end
54
53
 
55
- storage.upload(io_factory.call, id = "quux")
56
- lint_clear(id)
54
+ if storage.respond_to?(:clear!)
55
+ storage.upload(io_factory.call, id = "quux")
56
+ lint_clear(id)
57
+ end
57
58
  end
58
59
 
59
60
  def lint_download(id)
@@ -69,12 +70,6 @@ class Shrine
69
70
  opened.close
70
71
  end
71
72
 
72
- def lint_read(id)
73
- read = storage.read(id)
74
- error :read, "doesn't return a string" if !read.is_a?(String)
75
- error :read, "returns an empty string" if read.empty?
76
- end
77
-
78
73
  def lint_exists(id)
79
74
  error :exists?, "returns false for a file that was uploaded" if !storage.exists?(id)
80
75
  end
@@ -97,18 +97,23 @@ class Shrine
97
97
  # be passed to [`Aws::S3::Object#put`], [`Aws::S3::Object#copy_from`]
98
98
  # and [`Aws::S3::Bucket#presigned_post`].
99
99
  #
100
+ # :multipart_threshold
101
+ # : The file size over which the storage will use parallelized
102
+ # multipart copy/upload. Default is `15*1024*1024` (15MB).
103
+ #
100
104
  # All other options are forwarded to [`Aws::S3::Client#initialize`].
101
105
  #
102
106
  # [`Aws::S3::Object#put`]: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#put-instance_method
103
107
  # [`Aws::S3::Object#copy_from`]: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#copy_from-instance_method
104
108
  # [`Aws::S3::Bucket#presigned_post`]: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_post-instance_method
105
109
  # [`Aws::S3::Client#initialize`]: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html#initialize-instance_method
106
- def initialize(bucket:, prefix: nil, host: nil, upload_options: {}, **s3_options)
110
+ def initialize(bucket:, prefix: nil, host: nil, upload_options: {}, multipart_threshold: 15*1024*1024, **s3_options)
107
111
  @prefix = prefix
108
112
  @s3 = Aws::S3::Resource.new(**s3_options)
109
113
  @bucket = @s3.bucket(bucket)
110
114
  @host = host
111
115
  @upload_options = upload_options
116
+ @multipart_threshold = multipart_threshold
112
117
  end
113
118
 
114
119
  # If the file is an UploadedFile from S3, issues a COPY command, otherwise
@@ -130,7 +135,11 @@ class Shrine
130
135
 
131
136
  # Downloads the file from S3, and returns a `Tempfile`.
132
137
  def download(id)
133
- Down.download(url(id), ssl_ca_cert: Aws.config[:ssl_ca_bundle])
138
+ tempfile = Tempfile.new(["s3", File.extname(id)], binmode: true)
139
+ (object = object(id)).get(response_target: tempfile.path)
140
+ tempfile.singleton_class.instance_eval { attr_accessor :content_type }
141
+ tempfile.content_type = object.content_type
142
+ tempfile.tap(&:open)
134
143
  end
135
144
 
136
145
  # Alias for #download.
@@ -138,11 +147,6 @@ class Shrine
138
147
  Down.open(url(id), ssl_ca_cert: Aws.config[:ssl_ca_bundle])
139
148
  end
140
149
 
141
- # Returns the contents of the file as a String.
142
- def read(id)
143
- object(id).get.body.string
144
- end
145
-
146
150
  # Returns true file exists on S3.
147
151
  def exists?(id)
148
152
  object(id).exists?
@@ -199,7 +203,12 @@ class Shrine
199
203
 
200
204
  # Deletes all files from the storage.
201
205
  def clear!
202
- bucket.object_versions(prefix: prefix).delete
206
+ objects = bucket.object_versions(prefix: prefix)
207
+ if objects.respond_to?(:batch_delete!)
208
+ objects.batch_delete!
209
+ else
210
+ objects.delete
211
+ end
203
212
  end
204
213
 
205
214
  # Returns a signature for direct uploads. Internally it calls
@@ -239,13 +248,18 @@ class Shrine
239
248
 
240
249
  # Copies an existing S3 object to a new location.
241
250
  def copy(io, id, **options)
242
- options.update(multipart_copy: true) if large?(io)
251
+ options = {multipart_copy: true, content_length: io.size}.update(options) if multipart?(io)
243
252
  object(id).copy_from(io.storage.object(io.id), **options)
244
253
  end
245
254
 
246
255
  # Uploads the file to S3.
247
256
  def put(io, id, **options)
248
- object(id).put(body: io, **options)
257
+ if io.respond_to?(:path)
258
+ options = {multipart_threshold: @multipart_threshold}.update(options)
259
+ object(id).upload_file(io.path, **options)
260
+ else
261
+ object(id).put(body: io, **options)
262
+ end
249
263
  end
250
264
 
251
265
  # The file is copyable if it's on S3 and on the same Amazon account.
@@ -255,9 +269,10 @@ class Shrine
255
269
  io.storage.access_key_id == access_key_id
256
270
  end
257
271
 
258
- # Amazon requires multipart copy from S3 objects larger than 5 GB.
259
- def large?(io)
260
- io.size && io.size >= 5*1024*1024*1024 # 5GB
272
+ # Determines whether multipart upload/copy should be used from
273
+ # `:multipart_threshold`.
274
+ def multipart?(io)
275
+ io.size && io.size >= @multipart_threshold
261
276
  end
262
277
  end
263
278
  end
@@ -5,8 +5,8 @@ class Shrine
5
5
 
6
6
  module VERSION
7
7
  MAJOR = 2
8
- MINOR = 1
9
- TINY = 1
8
+ MINOR = 2
9
+ TINY = 0
10
10
  PRE = nil
11
11
 
12
12
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
data/shrine.gemspec CHANGED
@@ -25,7 +25,7 @@ column, and tying them to record's lifecycle.
25
25
  gem.files = Dir["README.md", "LICENSE.txt", "lib/**/*.rb", "shrine.gemspec", "doc/*.md"]
26
26
  gem.require_path = "lib"
27
27
 
28
- gem.add_dependency "down", ">= 2.3.4"
28
+ gem.add_dependency "down", ">= 2.3.5"
29
29
 
30
30
  gem.add_development_dependency "rake", "~> 11.1"
31
31
  gem.add_development_dependency "minitest", "~> 5.8"
@@ -37,10 +37,11 @@ column, and tying them to record's lifecycle.
37
37
  gem.add_development_dependency "shrine-memory", ">= 0.2.1"
38
38
 
39
39
  gem.add_development_dependency "roda"
40
+ gem.add_development_dependency "rack", "~> 1.6.4"
40
41
  gem.add_development_dependency "mimemagic"
41
42
  gem.add_development_dependency "mime-types"
42
43
  gem.add_development_dependency "fastimage"
43
- gem.add_development_dependency "aws-sdk"
44
+ gem.add_development_dependency "aws-sdk", "~> 2.1"
44
45
 
45
46
  unless RUBY_ENGINE == "jruby" || ENV["CI"]
46
47
  gem.add_development_dependency "ruby-filemagic", "~> 0.7"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.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: 2016-07-13 00:00:00.000000000 Z
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.3.4
19
+ version: 2.3.5
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.3.4
26
+ version: 2.3.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rack
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.6.4
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.6.4
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: mimemagic
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -196,16 +210,16 @@ dependencies:
196
210
  name: aws-sdk
197
211
  requirement: !ruby/object:Gem::Requirement
198
212
  requirements:
199
- - - ">="
213
+ - - "~>"
200
214
  - !ruby/object:Gem::Version
201
- version: '0'
215
+ version: '2.1'
202
216
  type: :development
203
217
  prerelease: false
204
218
  version_requirements: !ruby/object:Gem::Requirement
205
219
  requirements:
206
- - - ">="
220
+ - - "~>"
207
221
  - !ruby/object:Gem::Version
208
- version: '0'
222
+ version: '2.1'
209
223
  - !ruby/object:Gem::Dependency
210
224
  name: ruby-filemagic
211
225
  requirement: !ruby/object:Gem::Requirement
@@ -291,6 +305,7 @@ files:
291
305
  - doc/securing_uploads.md
292
306
  - lib/shrine.rb
293
307
  - lib/shrine/plugins/activerecord.rb
308
+ - lib/shrine/plugins/add_metadata.rb
294
309
  - lib/shrine/plugins/background_helpers.rb
295
310
  - lib/shrine/plugins/backgrounding.rb
296
311
  - lib/shrine/plugins/backup.rb
@@ -316,6 +331,7 @@ files:
316
331
  - lib/shrine/plugins/parallelize.rb
317
332
  - lib/shrine/plugins/parsed_json.rb
318
333
  - lib/shrine/plugins/pretty_location.rb
334
+ - lib/shrine/plugins/processing.rb
319
335
  - lib/shrine/plugins/rack_file.rb
320
336
  - lib/shrine/plugins/recache.rb
321
337
  - lib/shrine/plugins/remote_url.rb
@@ -357,4 +373,3 @@ signing_key:
357
373
  specification_version: 4
358
374
  summary: Toolkit for handling file uploads in Ruby
359
375
  test_files: []
360
- has_rdoc: