shrine 2.18.1 → 2.19.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.

Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -1
  3. data/README.md +96 -137
  4. data/doc/advantages.md +4 -4
  5. data/doc/attacher.md +1 -2
  6. data/doc/carrierwave.md +3 -2
  7. data/doc/creating_storages.md +0 -20
  8. data/doc/design.md +1 -1
  9. data/doc/metadata.md +62 -36
  10. data/doc/paperclip.md +7 -6
  11. data/doc/plugins/data_uri.md +50 -4
  12. data/doc/plugins/derivation_endpoint.md +24 -0
  13. data/doc/plugins/determine_mime_type.md +47 -5
  14. data/doc/plugins/infer_extension.md +45 -9
  15. data/doc/plugins/instrumentation.md +170 -0
  16. data/doc/plugins/presign_endpoint.md +1 -1
  17. data/doc/plugins/pretty_location.md +23 -0
  18. data/doc/plugins/remote_url.md +59 -8
  19. data/doc/plugins/signature.md +54 -7
  20. data/doc/plugins/store_dimensions.md +69 -4
  21. data/doc/plugins/upload_endpoint.md +2 -2
  22. data/doc/plugins/validation_helpers.md +71 -29
  23. data/doc/refile.md +1 -1
  24. data/doc/release_notes/2.18.0.md +2 -2
  25. data/doc/release_notes/2.19.0.md +263 -0
  26. data/doc/storage/file_system.md +26 -8
  27. data/doc/testing.md +10 -10
  28. data/lib/shrine.rb +32 -16
  29. data/lib/shrine/attacher.rb +3 -0
  30. data/lib/shrine/attachment.rb +3 -0
  31. data/lib/shrine/plugins/add_metadata.rb +12 -16
  32. data/lib/shrine/plugins/backup.rb +2 -0
  33. data/lib/shrine/plugins/copy.rb +2 -0
  34. data/lib/shrine/plugins/data_uri.rb +56 -28
  35. data/lib/shrine/plugins/derivation_endpoint.rb +61 -27
  36. data/lib/shrine/plugins/determine_mime_type.rb +27 -5
  37. data/lib/shrine/plugins/infer_extension.rb +26 -5
  38. data/lib/shrine/plugins/instrumentation.rb +300 -0
  39. data/lib/shrine/plugins/logging.rb +2 -0
  40. data/lib/shrine/plugins/moving.rb +2 -0
  41. data/lib/shrine/plugins/pretty_location.rb +21 -12
  42. data/lib/shrine/plugins/rack_file.rb +23 -18
  43. data/lib/shrine/plugins/refresh_metadata.rb +4 -4
  44. data/lib/shrine/plugins/remote_url.rb +42 -23
  45. data/lib/shrine/plugins/signature.rb +32 -1
  46. data/lib/shrine/plugins/store_dimensions.rb +54 -9
  47. data/lib/shrine/plugins/validation_helpers.rb +148 -47
  48. data/lib/shrine/storage/file_system.rb +32 -15
  49. data/lib/shrine/storage/linter.rb +0 -13
  50. data/lib/shrine/storage/s3.rb +2 -5
  51. data/lib/shrine/uploaded_file.rb +8 -0
  52. data/lib/shrine/version.rb +2 -2
  53. data/shrine.gemspec +18 -3
  54. metadata +58 -27
@@ -50,22 +50,28 @@ class Shrine
50
50
  end
51
51
 
52
52
  # Copies the file into the given location.
53
- def upload(io, id, shrine_metadata: {}, **upload_options)
54
- bytes_copied = IO.copy_stream(io, path!(id))
55
- path(id).chmod(permissions) if permissions
53
+ def upload(io, id, move: false, shrine_metadata: {}, **options)
54
+ Shrine.deprecation("Unrecognized options for FileSystem#upload: #{options.inspect}. Passing unrecognized options to FileSystem#upload will not be supported in Shrine 3.") if options.any?
55
+
56
+ if move && movable?(io, id)
57
+ move(io, id)
58
+ else
59
+ IO.copy_stream(io, path!(id))
56
60
 
57
- shrine_metadata["size"] ||= bytes_copied
61
+ path(id).chmod(permissions) if permissions
62
+ end
58
63
  end
59
64
 
60
65
  # Moves the file to the given location. This gets called by the `moving`
61
66
  # plugin.
62
- def move(io, id, shrine_metadata: {}, **upload_options)
67
+ def move(io, id, **)
63
68
  if io.respond_to?(:path)
64
69
  FileUtils.mv io.path, path!(id)
65
70
  else
66
71
  FileUtils.mv io.storage.path(io.id), path!(id)
67
72
  io.storage.clean(io.storage.path(io.id)) if io.storage.clean?
68
73
  end
74
+
69
75
  path(id).chmod(permissions) if permissions
70
76
  end
71
77
 
@@ -106,17 +112,22 @@ class Shrine
106
112
  host ? host + path : path
107
113
  end
108
114
 
109
- # Deletes all files from the #directory. If `:older_than` is passed in (a
110
- # `Time` object), deletes all files which were last modified before that
111
- # time.
112
- def clear!(older_than: nil)
113
- if older_than
114
- # add trailing slash to make it work with symlinks
115
- Pathname("#{directory}/").find do |path|
116
- if path.file? && path.mtime < older_than
117
- path.delete
118
- clean(path) if clean?
115
+ # Deletes all files from the #directory. If a block is passed in, deletes
116
+ # only the files for which the block evaluates to true.
117
+ #
118
+ # file_system.clear! # deletes all files and subdirectories in the storage directory
119
+ # file_system.clear! { |path| path.mtime < Time.now - 7*24*60*60 } # deletes only files older than 1 week
120
+ def clear!(older_than: nil, &condition)
121
+ if older_than || condition
122
+ list_files(directory) do |path|
123
+ if older_than
124
+ Shrine.deprecation("The :older_than option to FileSystem#clear! is deprecated and will be removed in Shrine 3. You should use a block instead, e.g. `storage.clear! { |path| path.mtime < Time.now - 7*24*60*60 }`.")
125
+ next unless path.mtime < older_than
126
+ else
127
+ next unless condition.call(path)
119
128
  end
129
+ path.delete
130
+ clean(path) if clean?
120
131
  end
121
132
  else
122
133
  directory.children.each(&:rmtree)
@@ -171,6 +182,12 @@ class Shrine
171
182
  path.sub(%r{^/}, "")
172
183
  end
173
184
 
185
+ def list_files(directory)
186
+ Pathname("#{directory}/") # add trailing slash to make it work with symlinks
187
+ .find
188
+ .each { |path| yield path if path.file? }
189
+ end
190
+
174
191
  def deprecated_download(id, **options)
175
192
  Shrine.deprecation("Shrine::Storage::FileSystem#download is deprecated and will be removed in Shrine 3.")
176
193
  tempfile = Tempfile.new(["shrine-filesystem", File.extname(id)], binmode: true)
@@ -43,11 +43,6 @@ class Shrine
43
43
  lint_url(id)
44
44
  lint_delete(id)
45
45
 
46
- if storage.respond_to?(:move)
47
- uploaded_file = uploader.upload(io_factory.call, location: "bar".dup)
48
- lint_move(uploaded_file, "quux")
49
- end
50
-
51
46
  if storage.respond_to?(:clear!)
52
47
  storage.upload(io_factory.call, id = "quux".dup)
53
48
  lint_clear(id)
@@ -85,14 +80,6 @@ class Shrine
85
80
  end
86
81
  end
87
82
 
88
- def lint_move(uploaded_file, id)
89
- if storage.movable?(uploaded_file, id)
90
- storage.move(uploaded_file, id, {})
91
- error :exists?, "returns false for destination after #move" if !storage.exists?(id)
92
- error :exists?, "returns true for source after #move" if storage.exists?(uploaded_file.id)
93
- end
94
- end
95
-
96
83
  def lint_clear(id)
97
84
  storage.clear!
98
85
  error :clear!, "file still #exists? after clearing" if storage.exists?(id)
@@ -252,11 +252,8 @@ class Shrine
252
252
  # # or
253
253
  # s3.clear! { |object| object.last_modified < Time.now - 7*24*60*60 }
254
254
  def clear!(&block)
255
- objects_to_delete = Enumerator.new do |yielder|
256
- bucket.objects(prefix: prefix).each do |object|
257
- yielder << object if block.nil? || block.call(object)
258
- end
259
- end
255
+ objects_to_delete = bucket.objects(prefix: prefix)
256
+ objects_to_delete = objects_to_delete.lazy.select(&block) if block
260
257
 
261
258
  delete_objects(objects_to_delete)
262
259
  end
@@ -74,6 +74,11 @@ class Shrine
74
74
  end
75
75
  alias content_type mime_type
76
76
 
77
+ # Shorthand for accessing metadata values.
78
+ def [](key)
79
+ metadata[key]
80
+ end
81
+
77
82
  # Calls `#open` on the storage to open the uploaded file for reading.
78
83
  # Most storages will return a lazy IO object which dynamically
79
84
  # retrieves file content from the storage as the object is being read.
@@ -262,5 +267,8 @@ class Shrine
262
267
  end
263
268
  end
264
269
  end
270
+
271
+ extend ClassMethods
272
+ include InstanceMethods
265
273
  end
266
274
  end
@@ -7,8 +7,8 @@ class Shrine
7
7
 
8
8
  module VERSION
9
9
  MAJOR = 2
10
- MINOR = 18
11
- TINY = 1
10
+ MINOR = 19
11
+ TINY = 0
12
12
  PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
data/shrine.gemspec CHANGED
@@ -36,26 +36,41 @@ direct uploads for fully asynchronous user experience.
36
36
  gem.add_dependency "down", "~> 4.1"
37
37
  gem.add_dependency "content_disposition", "~> 1.0"
38
38
 
39
+ # general testing helpers
39
40
  gem.add_development_dependency "rake", ">= 11.1"
40
41
  gem.add_development_dependency "minitest", "~> 5.8"
41
42
  gem.add_development_dependency "minitest-hooks", "~> 1.3"
42
43
  gem.add_development_dependency "mocha", "~> 1.4"
43
- gem.add_development_dependency "rack-test_app"
44
44
  gem.add_development_dependency "shrine-memory", ">= 0.2.2"
45
45
 
46
+ # for endpoint plugins
46
47
  gem.add_development_dependency "rack", "~> 2.0"
48
+ gem.add_development_dependency "http-form_data", "~> 2.0"
49
+ gem.add_development_dependency "rack-test_app"
50
+
51
+ # for determine_mime_type plugin
47
52
  gem.add_development_dependency "mimemagic", ">= 0.3.2"
48
53
  gem.add_development_dependency "marcel"
54
+ gem.add_development_dependency "ruby-filemagic", "~> 0.7" unless RUBY_ENGINE == "jruby" || ENV["CI"]
55
+
56
+ # for determine_mime_type and infer_extension plugins
49
57
  gem.add_development_dependency "mime-types"
50
58
  gem.add_development_dependency "mini_mime", "~> 1.0"
51
- gem.add_development_dependency "ruby-filemagic", "~> 0.7" unless RUBY_ENGINE == "jruby" || ENV["CI"]
59
+
60
+ # for store_dimensions plugin
52
61
  gem.add_development_dependency "fastimage"
53
62
  gem.add_development_dependency "mini_magick", "~> 4.0" unless ENV["CI"]
54
63
  gem.add_development_dependency "ruby-vips", "~> 2.0" unless ENV["CI"]
64
+
65
+ # for S3 storage
55
66
  gem.add_development_dependency "aws-sdk-s3", "~> 1.16"
56
67
  gem.add_development_dependency "aws-sdk-core", "~> 3.23"
57
- gem.add_development_dependency "http-form_data", "~> 2.0"
58
68
 
69
+ # for instrumentation plugin
70
+ gem.add_development_dependency "dry-monitor"
71
+ gem.add_development_dependency "activesupport", "~> 5.2.0"
72
+
73
+ # for ORM plugins
59
74
  gem.add_development_dependency "sequel"
60
75
  gem.add_development_dependency "activerecord", "~> 5.2.0"
61
76
  gem.add_development_dependency "sqlite3", "~> 1.3.6" unless RUBY_ENGINE == "jruby"
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.18.1
4
+ version: 2.19.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: 2019-07-05 00:00:00.000000000 Z
11
+ date: 2019-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -95,35 +95,35 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.4'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rack-test_app
98
+ name: shrine-memory
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 0.2.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: '0'
110
+ version: 0.2.2
111
111
  - !ruby/object:Gem::Dependency
112
- name: shrine-memory
112
+ name: rack
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.2.2
117
+ version: '2.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.2.2
124
+ version: '2.0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: rack
126
+ name: http-form_data
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
@@ -137,35 +137,35 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '2.0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: mimemagic
140
+ name: rack-test_app
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: 0.3.2
145
+ version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: 0.3.2
152
+ version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: marcel
154
+ name: mimemagic
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: '0'
159
+ version: 0.3.2
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
- version: '0'
166
+ version: 0.3.2
167
167
  - !ruby/object:Gem::Dependency
168
- name: mime-types
168
+ name: marcel
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -179,33 +179,47 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: mini_mime
182
+ name: ruby-filemagic
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '1.0'
187
+ version: '0.7'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '1.0'
194
+ version: '0.7'
195
195
  - !ruby/object:Gem::Dependency
196
- name: ruby-filemagic
196
+ name: mime-types
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: mini_mime
197
211
  requirement: !ruby/object:Gem::Requirement
198
212
  requirements:
199
213
  - - "~>"
200
214
  - !ruby/object:Gem::Version
201
- version: '0.7'
215
+ version: '1.0'
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.7'
222
+ version: '1.0'
209
223
  - !ruby/object:Gem::Dependency
210
224
  name: fastimage
211
225
  requirement: !ruby/object:Gem::Requirement
@@ -277,19 +291,33 @@ dependencies:
277
291
  - !ruby/object:Gem::Version
278
292
  version: '3.23'
279
293
  - !ruby/object:Gem::Dependency
280
- name: http-form_data
294
+ name: dry-monitor
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
307
+ - !ruby/object:Gem::Dependency
308
+ name: activesupport
281
309
  requirement: !ruby/object:Gem::Requirement
282
310
  requirements:
283
311
  - - "~>"
284
312
  - !ruby/object:Gem::Version
285
- version: '2.0'
313
+ version: 5.2.0
286
314
  type: :development
287
315
  prerelease: false
288
316
  version_requirements: !ruby/object:Gem::Requirement
289
317
  requirements:
290
318
  - - "~>"
291
319
  - !ruby/object:Gem::Version
292
- version: '2.0'
320
+ version: 5.2.0
293
321
  - !ruby/object:Gem::Dependency
294
322
  name: sequel
295
323
  requirement: !ruby/object:Gem::Requirement
@@ -382,6 +410,7 @@ files:
382
410
  - doc/plugins/hooks.md
383
411
  - doc/plugins/included.md
384
412
  - doc/plugins/infer_extension.md
413
+ - doc/plugins/instrumentation.md
385
414
  - doc/plugins/keep_files.md
386
415
  - doc/plugins/logging.md
387
416
  - doc/plugins/metadata_attributes.md
@@ -434,6 +463,7 @@ files:
434
463
  - doc/release_notes/2.16.0.md
435
464
  - doc/release_notes/2.17.0.md
436
465
  - doc/release_notes/2.18.0.md
466
+ - doc/release_notes/2.19.0.md
437
467
  - doc/release_notes/2.2.0.md
438
468
  - doc/release_notes/2.3.0.md
439
469
  - doc/release_notes/2.3.1.md
@@ -477,6 +507,7 @@ files:
477
507
  - lib/shrine/plugins/hooks.rb
478
508
  - lib/shrine/plugins/included.rb
479
509
  - lib/shrine/plugins/infer_extension.rb
510
+ - lib/shrine/plugins/instrumentation.rb
480
511
  - lib/shrine/plugins/keep_files.rb
481
512
  - lib/shrine/plugins/logging.rb
482
513
  - lib/shrine/plugins/metadata_attributes.rb