shrine-cloudinary 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +55 -7
- data/lib/shrine/storage/cloudinary.rb +22 -24
- data/shrine-cloudinary.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88a038d6cf9285136e6a82d4ddf674f91e476802
|
4
|
+
data.tar.gz: a62342009fd3960a2aeed8e2dd67897bc60d568f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8804baaf7341ecabdd1592648a3ab1181e87612e2b145c05314bfd20f384b7c4d5f062fc66ae9d00961979b4a725d58cdfda2a68ba113501f7c6eba0701c332b
|
7
|
+
data.tar.gz: 8bba0e77831e522c76d03616be52b04f6806c50089d8eb689bae7f8a9188cdf822973f1fd7cfed19137a4dc17f7d9bf91e4fde19e21985e462960bc3942c5dbc
|
data/README.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
Provides [Cloudinary] storage for [Shrine].
|
4
4
|
|
5
|
+
Cloudinary provides storage with advanced on-the-fly processing (as well as
|
6
|
+
processing on upload) for both images and videos, but can also store any other
|
7
|
+
types of files.
|
8
|
+
|
5
9
|
## Installation
|
6
10
|
|
7
11
|
```ruby
|
@@ -30,6 +34,13 @@ require "shrine/storage/cloudinary"
|
|
30
34
|
Shrine.storages[:store] = Shrine::Storage::Cloudinary.new
|
31
35
|
```
|
32
36
|
|
37
|
+
### Direct uploads
|
38
|
+
|
39
|
+
Cloudinary supports uploading files directly to their service, thus bypassing
|
40
|
+
your application. The easiest way to do that is to setup [direct unsigned
|
41
|
+
uploads]. Follow the linked blog post for instructions, and see the [demo] app
|
42
|
+
for a complete implementation.
|
43
|
+
|
33
44
|
### Copying
|
34
45
|
|
35
46
|
If you're using storage as cache where files are accessible over internet,
|
@@ -37,7 +48,7 @@ moving the cached file to Cloudinary storage will not require another upload.
|
|
37
48
|
Instead only the file URL will be passed to Cloudinary, then Cloudinary will
|
38
49
|
internally download it and store the file.
|
39
50
|
|
40
|
-
### Videos
|
51
|
+
### Images, Videos or Raw
|
41
52
|
|
42
53
|
The storage defaults the resource type to "image", but you can change that
|
43
54
|
by passing the `:resource_type` option:
|
@@ -54,6 +65,14 @@ You can choose to store your files in a subdirectory with the `:prefix` option:
|
|
54
65
|
Shrine::Storage::Cloudinary.new(prefix: "uploads")
|
55
66
|
```
|
56
67
|
|
68
|
+
### Controlling access
|
69
|
+
|
70
|
+
You can [control access] to uploaded files with the `:type` option:
|
71
|
+
|
72
|
+
```rb
|
73
|
+
Shrine::Storage::Cloudinary.new(type: "private") # upload, private or authenticated
|
74
|
+
```
|
75
|
+
|
57
76
|
### Upload options
|
58
77
|
|
59
78
|
If you want some [Cloudinary options] to be applied to all uploads, you can
|
@@ -86,8 +105,7 @@ end
|
|
86
105
|
You can pass transformation options to the URLs:
|
87
106
|
|
88
107
|
```rb
|
89
|
-
user.avatar_url(width: 100, height: 100)
|
90
|
-
user.avatar_url(width: 0.2, crop: :scale)
|
108
|
+
user.avatar_url(width: 100, height: 100, crop: :fit) # :crop is mandatory here
|
91
109
|
```
|
92
110
|
|
93
111
|
See [Rails image manipulation] for all URL options you can pass in.
|
@@ -126,9 +144,31 @@ user.avatar.metadata["cloudinary"] #=>
|
|
126
144
|
# }
|
127
145
|
```
|
128
146
|
|
129
|
-
|
130
|
-
|
131
|
-
|
147
|
+
## Responsive breakpoints
|
148
|
+
|
149
|
+
Cloudinary has a feature for automagically generating [responsive breakpoints]
|
150
|
+
for images. In Shrine you can leverage this via `:upload_options` and
|
151
|
+
`:store_data`:
|
152
|
+
|
153
|
+
```rb
|
154
|
+
Shrine::Storage::Cloudinary.new(
|
155
|
+
store_data: true,
|
156
|
+
upload_options: {responsive_breakpoints: {...}},
|
157
|
+
**cloudinary_options
|
158
|
+
)
|
159
|
+
```
|
160
|
+
|
161
|
+
Now each upload will generate responsive breakpoints, and the result will be
|
162
|
+
saved in the uploaded file's metadata hash under "cloudinary".
|
163
|
+
|
164
|
+
If the `:responsive_breakpoints` value needs to be dynamic, you can use the
|
165
|
+
upload_options plugin:
|
166
|
+
|
167
|
+
```rb
|
168
|
+
Shrine.plugin :upload_options, store: ->(io, context) do
|
169
|
+
{responsive_breakpoints: {...}}
|
170
|
+
end
|
171
|
+
```
|
132
172
|
|
133
173
|
### Large files
|
134
174
|
|
@@ -171,7 +211,7 @@ with other storages:
|
|
171
211
|
```rb
|
172
212
|
cloudinary = Shrine::Storage::Cloudinary.new
|
173
213
|
# ...
|
174
|
-
cloudinary.clear!
|
214
|
+
cloudinary.clear!
|
175
215
|
```
|
176
216
|
|
177
217
|
## Contributing
|
@@ -191,13 +231,21 @@ Afterwards you can run the tests:
|
|
191
231
|
$ bundle exec rake test
|
192
232
|
```
|
193
233
|
|
234
|
+
## Inspiration
|
235
|
+
|
236
|
+
This gem has been inspired by [cloudinary]'s CarrierWave integration.
|
237
|
+
|
194
238
|
## License
|
195
239
|
|
196
240
|
[MIT](http://opensource.org/licenses/MIT)
|
197
241
|
|
198
242
|
[Cloudinary]: http://cloudinary.com/
|
199
243
|
[Shrine]: https://github.com/janko-m/shrine
|
244
|
+
[cloudinary]: https://github.com/cloudinary/cloudinary_gem
|
200
245
|
[Cloudinary options]: http://cloudinary.com/documentation/upload_images#remote_upload
|
201
246
|
[Rails image manipulation]: http://cloudinary.com/documentation/rails_image_manipulation
|
202
247
|
[responsive breakpoints]: http://cloudinary.com/blog/introducing_intelligent_responsive_image_breakpoints_solutions
|
203
248
|
[explicit API]: http://cloudinary.com/documentation/image_upload_api_reference#explicit
|
249
|
+
[direct unsigned uploads]: http://cloudinary.com/blog/direct_upload_made_easy_from_browser_or_mobile_app_to_the_cloud
|
250
|
+
[demo]: /demo
|
251
|
+
[control access]: http://cloudinary.com/documentation/upload_images#control_access_to_images
|
@@ -5,18 +5,20 @@ require "down"
|
|
5
5
|
class Shrine
|
6
6
|
module Storage
|
7
7
|
class Cloudinary
|
8
|
-
attr_reader :prefix, :resource_type, :upload_options
|
8
|
+
attr_reader :prefix, :resource_type, :type, :upload_options
|
9
9
|
|
10
|
-
def initialize(prefix: nil,
|
10
|
+
def initialize(prefix: nil, resource_type: "image", type: "upload", store_data: nil, upload_options: {}, large: nil)
|
11
11
|
@prefix = prefix
|
12
12
|
@large = large
|
13
13
|
@resource_type = resource_type
|
14
|
-
@
|
14
|
+
@type = type
|
15
|
+
@upload_options = upload_options
|
15
16
|
@store_data = store_data
|
16
17
|
end
|
17
18
|
|
18
19
|
def upload(io, id, shrine_metadata: {}, **upload_options)
|
19
20
|
options = {public_id: public_id(id)}
|
21
|
+
options.update(default_options)
|
20
22
|
options.update(@upload_options)
|
21
23
|
options.update(upload_options)
|
22
24
|
|
@@ -33,11 +35,11 @@ class Shrine
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def update(id, **options)
|
36
|
-
|
38
|
+
::Cloudinary::Uploader.explicit(public_id(id), default_options.merge(options))
|
37
39
|
end
|
38
40
|
|
39
|
-
def move(io, id,
|
40
|
-
|
41
|
+
def move(io, id, shrine_metadata: {}, **upload_options)
|
42
|
+
::Cloudinary::Uploader.rename(io.storage.public_id(io.id), public_id(id), default_options)
|
41
43
|
end
|
42
44
|
|
43
45
|
def movable?(io, id)
|
@@ -49,32 +51,32 @@ class Shrine
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def read(id)
|
52
|
-
|
54
|
+
::Cloudinary::Downloader.download(url(id), default_options)
|
53
55
|
end
|
54
56
|
|
55
57
|
def exists?(id)
|
56
|
-
result =
|
58
|
+
result = ::Cloudinary::Api.resources_by_ids([public_id(id)], default_options)
|
57
59
|
result.fetch("resources").any?
|
58
60
|
end
|
59
61
|
|
60
62
|
def delete(id)
|
61
|
-
|
63
|
+
::Cloudinary::Uploader.destroy(public_id(id), default_options)
|
62
64
|
end
|
63
65
|
|
64
66
|
def multi_delete(ids)
|
65
67
|
public_ids = ids.map { |id| public_id(id) }
|
66
|
-
|
68
|
+
::Cloudinary::Api.delete_resources(public_ids, default_options)
|
67
69
|
end
|
68
70
|
|
69
71
|
def url(id, **options)
|
70
|
-
|
72
|
+
::Cloudinary::Utils.cloudinary_url(path(id), default_options.merge(options))
|
71
73
|
end
|
72
74
|
|
73
75
|
def clear!(**options)
|
74
76
|
if prefix
|
75
|
-
|
77
|
+
::Cloudinary::Api.delete_resources_by_prefix(prefix, default_options.merge(options))
|
76
78
|
else
|
77
|
-
|
79
|
+
::Cloudinary::Api.delete_all_resources(default_options.merge(options))
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -96,21 +98,17 @@ class Shrine
|
|
96
98
|
|
97
99
|
def store(io, chunk_size: nil, **options)
|
98
100
|
if remote?(io)
|
99
|
-
|
101
|
+
::Cloudinary::Uploader.upload(io.url, **options)
|
100
102
|
else
|
101
103
|
io = io.download if io.is_a?(UploadedFile)
|
102
104
|
if large?(io)
|
103
|
-
|
105
|
+
::Cloudinary::Uploader.upload_large(io, chunk_size: chunk_size, **options)
|
104
106
|
else
|
105
|
-
|
107
|
+
::Cloudinary::Uploader.upload(io, **options)
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
110
|
-
def type
|
111
|
-
upload_options[:type] || "upload"
|
112
|
-
end
|
113
|
-
|
114
112
|
def remote?(io)
|
115
113
|
io.is_a?(UploadedFile) && io.url.to_s =~ /^ftp:|^https?:/
|
116
114
|
end
|
@@ -119,6 +117,10 @@ class Shrine
|
|
119
117
|
io.size >= @large if @large
|
120
118
|
end
|
121
119
|
|
120
|
+
def default_options
|
121
|
+
{resource_type: resource_type, type: type}
|
122
|
+
end
|
123
|
+
|
122
124
|
def update_id!(result, id)
|
123
125
|
uploaded_id = result.fetch("public_id")
|
124
126
|
uploaded_id = uploaded_id.match("#{prefix}/").post_match if prefix
|
@@ -140,10 +142,6 @@ class Shrine
|
|
140
142
|
metadata.update(retrieved_metadata)
|
141
143
|
end
|
142
144
|
|
143
|
-
[:Uploader, :Downloader, :Utils, :Api].each do |name|
|
144
|
-
define_method(name.downcase) { ::Cloudinary.const_get(name) }
|
145
|
-
end
|
146
|
-
|
147
145
|
MIME_TYPES = {
|
148
146
|
# Images
|
149
147
|
"jpg" => "image/jpeg",
|
data/shrine-cloudinary.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shrine-cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
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-
|
11
|
+
date: 2016-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shrine
|