shrine 2.2.0 → 2.3.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.

Potentially problematic release.


This version of shrine might be problematic. Click here for more details.

Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +143 -84
  3. data/doc/carrierwave.md +187 -47
  4. data/doc/direct_s3.md +57 -39
  5. data/doc/paperclip.md +183 -91
  6. data/doc/refile.md +148 -124
  7. data/doc/regenerating_versions.md +2 -3
  8. data/lib/shrine.rb +26 -28
  9. data/lib/shrine/plugins/activerecord.rb +22 -31
  10. data/lib/shrine/plugins/add_metadata.rb +1 -1
  11. data/lib/shrine/plugins/backgrounding.rb +19 -7
  12. data/lib/shrine/plugins/backup.rb +2 -2
  13. data/lib/shrine/plugins/cached_attachment_data.rb +1 -1
  14. data/lib/shrine/plugins/copy.rb +52 -0
  15. data/lib/shrine/plugins/data_uri.rb +1 -1
  16. data/lib/shrine/plugins/default_storage.rb +2 -2
  17. data/lib/shrine/plugins/default_url.rb +1 -1
  18. data/lib/shrine/plugins/default_url_options.rb +1 -1
  19. data/lib/shrine/plugins/delete_promoted.rb +1 -1
  20. data/lib/shrine/plugins/delete_raw.rb +1 -1
  21. data/lib/shrine/plugins/determine_mime_type.rb +3 -2
  22. data/lib/shrine/plugins/direct_upload.rb +36 -24
  23. data/lib/shrine/plugins/download_endpoint.rb +3 -3
  24. data/lib/shrine/plugins/dynamic_storage.rb +2 -2
  25. data/lib/shrine/plugins/hooks.rb +1 -1
  26. data/lib/shrine/plugins/included.rb +3 -4
  27. data/lib/shrine/plugins/keep_files.rb +1 -1
  28. data/lib/shrine/plugins/logging.rb +1 -1
  29. data/lib/shrine/plugins/module_include.rb +1 -1
  30. data/lib/shrine/plugins/moving.rb +10 -5
  31. data/lib/shrine/plugins/multi_delete.rb +2 -2
  32. data/lib/shrine/plugins/parallelize.rb +2 -2
  33. data/lib/shrine/plugins/parsed_json.rb +1 -1
  34. data/lib/shrine/plugins/pretty_location.rb +1 -1
  35. data/lib/shrine/plugins/processing.rb +11 -9
  36. data/lib/shrine/plugins/rack_file.rb +1 -1
  37. data/lib/shrine/plugins/recache.rb +14 -4
  38. data/lib/shrine/plugins/remote_url.rb +1 -1
  39. data/lib/shrine/plugins/remove_attachment.rb +3 -4
  40. data/lib/shrine/plugins/remove_invalid.rb +1 -1
  41. data/lib/shrine/plugins/restore_cached_data.rb +11 -4
  42. data/lib/shrine/plugins/sequel.rb +34 -45
  43. data/lib/shrine/plugins/store_dimensions.rb +1 -1
  44. data/lib/shrine/plugins/upload_options.rb +2 -2
  45. data/lib/shrine/plugins/validation_helpers.rb +7 -8
  46. data/lib/shrine/plugins/versions.rb +31 -30
  47. data/lib/shrine/storage/file_system.rb +16 -12
  48. data/lib/shrine/storage/s3.rb +36 -2
  49. data/lib/shrine/version.rb +1 -1
  50. data/shrine.gemspec +9 -8
  51. metadata +11 -9
@@ -1,6 +1,6 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The store_dimensions plugin extracts and stores dimensions of the
3
+ # The `store_dimensions` plugin extracts and stores dimensions of the
4
4
  # uploaded image using the [fastimage] gem.
5
5
  #
6
6
  # plugin :store_dimensions
@@ -1,7 +1,7 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The upload_options allows you to automatically pass additional upload
4
- # options to storage on every upload:
3
+ # The `upload_options` plugin allows you to automatically pass additional
4
+ # upload options to storage on every upload:
5
5
  #
6
6
  # plugin :upload_options, cache: {acl: "private"}
7
7
  #
@@ -1,15 +1,14 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The validation_helpers plugin provides helper methods for validating
3
+ # The `validation_helpers` plugin provides helper methods for validating
4
4
  # attached files.
5
5
  #
6
6
  # class ImageUploader < Shrine
7
7
  # plugin :validation_helpers
8
8
  #
9
9
  # Attacher.validate do
10
- # if record.guest?
11
- # validate_max_size 5*1024*1024
12
- # end
10
+ # validat_mime_type_inclusion %w[image/jpeg image/png image/gif]
11
+ # validate_max_size 5*1024*1024 if record.guest?
13
12
  # end
14
13
  # end
15
14
  #
@@ -72,7 +71,7 @@ class Shrine
72
71
  end
73
72
 
74
73
  # Validates that the file is not wider than `max`. Requires the
75
- # store_dimensions plugin.
74
+ # `store_dimensions` plugin.
76
75
  def validate_max_width(max, message: nil)
77
76
  raise Error, ":store_dimensions plugin is required" if !get.respond_to?(:width)
78
77
  if get.width && get.width > max
@@ -81,7 +80,7 @@ class Shrine
81
80
  end
82
81
 
83
82
  # Validates that the file is not narrower than `min`. Requires the
84
- # store_dimensions plugin.
83
+ # `store_dimensions` plugin.
85
84
  def validate_min_width(min, message: nil)
86
85
  raise Error, ":store_dimensions plugin is required" if !get.respond_to?(:width)
87
86
  if get.width && get.width < min
@@ -90,7 +89,7 @@ class Shrine
90
89
  end
91
90
 
92
91
  # Validates that the file is not taller than `max`. Requires the
93
- # store_dimensions plugin.
92
+ # `store_dimensions` plugin.
94
93
  def validate_max_height(max, message: nil)
95
94
  raise Error, ":store_dimensions plugin is required" if !get.respond_to?(:height)
96
95
  if get.height && get.height > max
@@ -99,7 +98,7 @@ class Shrine
99
98
  end
100
99
 
101
100
  # Validates that the file is not shorter than `min`. Requires the
102
- # store_dimensions plugin.
101
+ # `store_dimensions` plugin.
103
102
  def validate_min_height(min, message: nil)
104
103
  raise Error, ":store_dimensions plugin is required" if !get.respond_to?(:height)
105
104
  if get.height && get.height < min
@@ -1,6 +1,6 @@
1
1
  class Shrine
2
2
  module Plugins
3
- # The versions plugin enables your uploader to deal with versions, by
3
+ # The `versions` plugin enables your uploader to deal with versions, by
4
4
  # allowing you to return a Hash of files when processing.
5
5
  #
6
6
  # plugin :versions
@@ -19,16 +19,6 @@ class Shrine
19
19
  # {large: size_700, medium: size_500, small: size_300}
20
20
  # end
21
21
  #
22
- # Note that if you want to keep the original file, you can forward it as is
23
- # without explicitly downloading it (since `Shrine::UploadedFile` itself is
24
- # an IO-like object), which might avoid downloading depending on the
25
- # storage:
26
- #
27
- # process(:store) do |io, context|
28
- # # processing thumbnail
29
- # {original: io, thumbnail: thumbnail}
30
- # end
31
- #
32
22
  # Now when you access the stored attachment through the model, a hash of
33
23
  # uploaded files will be returned:
34
24
  #
@@ -51,28 +41,43 @@ class Shrine
51
41
  # user.avatar[:medium].width #=> 500
52
42
  # user.avatar[:small].width #=> 300
53
43
  #
54
- # You probably want to load the delete_raw plugin to automatically
44
+ # You probably want to load the `delete_raw` plugin to automatically
55
45
  # delete processed files after they have been uploaded.
56
46
  #
57
- # The plugin also extends the `avatar_url` method to accept versions:
47
+ # ## Original file
58
48
  #
59
- # user.avatar_url(:medium)
49
+ # If you want to keep the original file, you can forward it as is without
50
+ # explicitly downloading it (since `Shrine::UploadedFile` itself is an
51
+ # IO-like object), which might avoid downloading depending on the storage:
60
52
  #
61
- # This method plays nice when generating versions in a background job,
62
- # since it will just point to the original cached file until the versions
63
- # are done processing:
53
+ # process(:store) do |io, context|
54
+ # # processing thumbnail
55
+ # {original: io, thumbnail: thumbnail}
56
+ # end
57
+ #
58
+ # ## Fallbacks
64
59
  #
65
- # user.avatar #=> #<Shrine::UploadedFile>
66
- # user.avatar_url(:medium) #=> "http://example.com/original.jpg"
60
+ # The plugin also extends the `<attachmen>_url` method to accept versions,
61
+ # and adds automatic fallbacks:
67
62
  #
68
- # # the background job has finished generating versions
63
+ # user.avatar_url(:medium)
64
+ #
65
+ # # returns URL of that version if versions have been created,
66
+ # # otherwise returns original URL if attachment exists,
67
+ # # otherwise returns nil
69
68
  #
70
- # user.avatar_url(:medium) #=> "http://example.com/medium.jpg"
69
+ # This behaviour is convenient when using background jobs, as it allows you
70
+ # to gracefully degrade before the background job finishes.
71
71
  #
72
72
  # If you already have some versions processed in the foreground when a
73
- # background job is kicked off, you can setup explicit URL fallbacks:
73
+ # background job is kicked off (with the `recache` plugin), the
74
+ # `<attachment>_url` method won't know which version to use as a fallback.
75
+ # In that case you can specify `:fallbacks` when loading the plugin:
74
76
  #
75
- # plugin :versions, fallbacks: {:thumb_2x => :thumb, :large_2x => :large}
77
+ # plugin :versions, fallbacks: {
78
+ # :thumb_2x => :thumb,
79
+ # :large_2x => :large,
80
+ # }
76
81
  #
77
82
  # # ... (background job is kicked off)
78
83
  #
@@ -84,6 +89,8 @@ class Shrine
84
89
  #
85
90
  # user.avatar_url(:medium, download: true)
86
91
  #
92
+ # ## Context
93
+ #
87
94
  # The `context` will now also include the version name, which you can use
88
95
  # when generating a location or a default URL:
89
96
  #
@@ -95,13 +102,7 @@ class Shrine
95
102
  # "/images/defaults/#{context[:version]}.jpg"
96
103
  # end
97
104
  #
98
- # When deleting versions, any multi delete capabilities will be leveraged,
99
- # so when using Storage::S3, deleting versions will issue only a single HTTP
100
- # request. If you want to delete versions manually, you can use
101
- # `Shrine#delete`:
102
- #
103
- # versions.keys #=> [:small, :medium, :large]
104
- # ImageUploader.new(:storage).delete(versions) # deletes a hash of versions
105
+ # [image_processing]: https://github.com/janko-m/image_processing
105
106
  module Versions
106
107
  def self.load_dependencies(uploader, *)
107
108
  uploader.plugin :multi_delete
@@ -51,10 +51,11 @@ class Shrine
51
51
  #
52
52
  # ## Permissions
53
53
  #
54
- # If you want your files and folders to have certain permissions, you can
55
- # pass the `:permissions` option:
54
+ # The storage sets the default UNIX permissions to 0644 for files and 0755
55
+ # for directories, but you can change that:
56
56
  #
57
- # Shrine::Storage::FileSystem.new("directory", permissions: 0755)
57
+ # Shrine::Storage::FileSystem.new("directory", permissions: 0644)
58
+ # Shrine::Storage::FileSystem.new("directory", directory_permissions: 0755)
58
59
  #
59
60
  # ## Heroku
60
61
  #
@@ -69,9 +70,9 @@ class Shrine
69
70
  # restarts. This also means that deploying the app can cancel someone's
70
71
  # uploading if you're using backgrounding. Also, by default you cannot
71
72
  # generate URLs to files in the "tmp" directory, but you can with the
72
- # download_endpoint plugin.
73
+ # `download_endpoint` plugin.
73
74
  class FileSystem
74
- attr_reader :directory, :prefix, :host, :permissions
75
+ attr_reader :directory, :prefix, :host, :permissions, :directory_permissions
75
76
 
76
77
  # Initializes a storage for uploading to the filesystem.
77
78
  #
@@ -84,14 +85,16 @@ class Shrine
84
85
  # can use this option to set a CDN host (e.g. `//abc123.cloudfront.net`).
85
86
  #
86
87
  # :permissions
87
- # : The generated files and folders will have default UNIX permissions,
88
- # but if you want specific ones you can use this option (e.g. `0755`).
88
+ # : Changes the UNIX permissions of created files (default is 0644).
89
+ #
90
+ # :directory_permissions
91
+ # : Changes the UNIX permissions of created directories (default is 0755).
89
92
  #
90
93
  # :clean
91
94
  # : By default empty folders inside the directory are automatically
92
95
  # deleted, but if it happens that it causes too much load on the
93
96
  # filesystem, you can set this option to `false`.
94
- def initialize(directory, prefix: nil, host: nil, clean: true, permissions: nil)
97
+ def initialize(directory, prefix: nil, host: nil, clean: true, permissions: 0644, directory_permissions: 0755)
95
98
  if prefix
96
99
  @prefix = Pathname(relative(prefix))
97
100
  @directory = Pathname(directory).join(@prefix)
@@ -101,10 +104,11 @@ class Shrine
101
104
 
102
105
  @host = host
103
106
  @permissions = permissions
107
+ @directory_permissions = directory_permissions
104
108
  @clean = clean
105
109
 
106
110
  @directory.mkpath
107
- @directory.chmod(permissions) if permissions
111
+ @directory.chmod(directory_permissions) if directory_permissions
108
112
  end
109
113
 
110
114
  # Copies the file into the given location.
@@ -118,7 +122,7 @@ class Shrine
118
122
  open(id) { |file| Down.copy_to_tempfile(id, file) }
119
123
  end
120
124
 
121
- # Moves the file to the given location. This gets called by the "moving"
125
+ # Moves the file to the given location. This gets called by the `moving`
122
126
  # plugin.
123
127
  def move(io, id, shrine_metadata: {}, **upload_options)
124
128
  if io.respond_to?(:path)
@@ -173,7 +177,7 @@ class Shrine
173
177
  else
174
178
  directory.rmtree
175
179
  directory.mkpath
176
- directory.chmod(permissions) if permissions
180
+ directory.chmod(directory_permissions) if directory_permissions
177
181
  end
178
182
  end
179
183
 
@@ -203,7 +207,7 @@ class Shrine
203
207
 
204
208
  # Creates all intermediate directories for that location.
205
209
  def path!(id)
206
- path(id).dirname.mkpath
210
+ FileUtils.mkdir_p(path(id).dirname, mode: directory_permissions)
207
211
  path(id)
208
212
  end
209
213
 
@@ -4,8 +4,8 @@ require "uri"
4
4
 
5
5
  class Shrine
6
6
  module Storage
7
- # The S3 storage handles uploads to Amazon S3 service, it depends on the
8
- # [aws-sdk] gem:
7
+ # The S3 storage handles uploads to Amazon S3 service, using the [aws-sdk]
8
+ # gem:
9
9
  #
10
10
  # gem "aws-sdk", "~> 2.1"
11
11
  #
@@ -56,6 +56,19 @@ class Shrine
56
56
  # Note that these aren't applied to presigns, since presigns are generated
57
57
  # using the storage directly.
58
58
  #
59
+ # ## URL options
60
+ #
61
+ # This storage supports various URL options that will be forwarded from
62
+ # uploaded file.
63
+ #
64
+ # uploaded_file.url(public: true) # public URL without signed parameters
65
+ # uploaded_file.url(download: true) # forced download URL
66
+ #
67
+ # All other options are forwarded to the [aws-sdk] gem:
68
+ #
69
+ # uploaded_file.url(expires_in: 15)
70
+ # uploaded_file.urL(virtual_host: true)
71
+ #
59
72
  # ## CDN
60
73
  #
61
74
  # If you're using a CDN with S3 like Amazon CloudFront, you can specify
@@ -63,6 +76,27 @@ class Shrine
63
76
  #
64
77
  # Shrine::Storage::S3.new(host: "http://abc123.cloudfront.net", **s3_options)
65
78
  #
79
+ # ## Presigns
80
+ #
81
+ # This storage can generate presigns for direct uploads to Amazon S3, and
82
+ # it accepts additional options which are passed to [aws-sdk]. There are
83
+ # three places in which you can specify presign options:
84
+ #
85
+ # * in `:upload_options` option on this storage
86
+ # * in `direct_upload` plugin through `:presign_options`
87
+ # * in `Storage::S3#presign` by forwarding options
88
+ #
89
+ # ## Large files
90
+ #
91
+ # The [aws-sdk] gem has the ability to automatically use multipart
92
+ # upload/copy for larger files, where the file is split into multiple chunks
93
+ # which are uploaded/copied in parallel.
94
+ #
95
+ # By default any files that are larger than 15MB will use this multipart
96
+ # upload/copy, but you change this threshold:
97
+ #
98
+ # Shrine::Storage::S3.new(multipart_threshold: 30*1024*1024) # 30MB
99
+ #
66
100
  # ## Clearing cache
67
101
  #
68
102
  # If you're using S3 as a cache, you will probably want to periodically
@@ -5,7 +5,7 @@ class Shrine
5
5
 
6
6
  module VERSION
7
7
  MAJOR = 2
8
- MINOR = 2
8
+ MINOR = 3
9
9
  TINY = 0
10
10
  PRE = nil
11
11
 
@@ -6,15 +6,16 @@ Gem::Specification.new do |gem|
6
6
 
7
7
  gem.required_ruby_version = ">= 2.1"
8
8
 
9
- gem.summary = "Toolkit for handling file uploads in Ruby"
9
+ gem.summary = "Toolkit for file attachments in Ruby applications"
10
10
  gem.description = <<-END
11
- Shrine is a toolkit for handling file uploads in Ruby. It supports uploading,
12
- processing and deleting IO objects, backed by a storage adapter. It uses
13
- efficient streaming to minimize memory usage.
14
-
15
- Shrine comes with a high-level attachment interface for attaching uploaded
16
- files to database records, saving their location and metadata to a database
17
- column, and tying them to record's lifecycle.
11
+ Shrine is a toolkit for file attachments in Ruby applications. It supports
12
+ uploading, downloading, processing and deleting IO objects, backed by various
13
+ storage engines. It uses efficient streaming for low memory usage.
14
+
15
+ Shrine comes with a high-level interface for attaching uploaded files to
16
+ database records, saving their location and metadata to a database column, and
17
+ tying them to record's lifecycle. It natively supports background jobs and
18
+ direct uploads for fully asynchronous user experience.
18
19
  END
19
20
 
20
21
  gem.homepage = "https://github.com/janko-m/shrine"
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.2.0
4
+ version: 2.3.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-29 00:00:00.000000000 Z
11
+ date: 2016-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -277,13 +277,14 @@ dependencies:
277
277
  - !ruby/object:Gem::Version
278
278
  version: '0'
279
279
  description: |
280
- Shrine is a toolkit for handling file uploads in Ruby. It supports uploading,
281
- processing and deleting IO objects, backed by a storage adapter. It uses
282
- efficient streaming to minimize memory usage.
280
+ Shrine is a toolkit for file attachments in Ruby applications. It supports
281
+ uploading, downloading, processing and deleting IO objects, backed by various
282
+ storage engines. It uses efficient streaming for low memory usage.
283
283
 
284
- Shrine comes with a high-level attachment interface for attaching uploaded
285
- files to database records, saving their location and metadata to a database
286
- column, and tying them to record's lifecycle.
284
+ Shrine comes with a high-level interface for attaching uploaded files to
285
+ database records, saving their location and metadata to a database column, and
286
+ tying them to record's lifecycle. It natively supports background jobs and
287
+ direct uploads for fully asynchronous user experience.
287
288
  email:
288
289
  - janko.marohnic@gmail.com
289
290
  executables: []
@@ -310,6 +311,7 @@ files:
310
311
  - lib/shrine/plugins/backgrounding.rb
311
312
  - lib/shrine/plugins/backup.rb
312
313
  - lib/shrine/plugins/cached_attachment_data.rb
314
+ - lib/shrine/plugins/copy.rb
313
315
  - lib/shrine/plugins/data_uri.rb
314
316
  - lib/shrine/plugins/default_storage.rb
315
317
  - lib/shrine/plugins/default_url.rb
@@ -371,5 +373,5 @@ rubyforge_project:
371
373
  rubygems_version: 2.5.1
372
374
  signing_key:
373
375
  specification_version: 4
374
- summary: Toolkit for handling file uploads in Ruby
376
+ summary: Toolkit for file attachments in Ruby applications
375
377
  test_files: []