shrine-google_drive_storage 0.1.1 → 0.2.1
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.
- checksums.yaml +4 -4
- data/lib/shrine/storage/google_drive_storage.rb +112 -184
- data/lib/shrine/version.rb +1 -1
- data/shrine-google_drive_storage.gemspec +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 20ce8cde9408e42b0f6760dcc15037cf42f6791d
|
|
4
|
+
data.tar.gz: deaa6b58b6a306508fddcff85fa2e27af192d481
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ac056acfc70909e7aba8497a64d5d5903cd34d895eb9e8106a0bad783fd97a5e1075ab396f515b8681ce7ff0d11bb03ee2579d311fdcb711fc19db77a77b554
|
|
7
|
+
data.tar.gz: e0e1a102ac83ff4d9ea0a6def751001ba2505c36d2e3d9c9571c3ae531afa69cc46e5035bc99d7b5ae2ffa9aa07b35e5f004ffb4657bd504073e8d0ada1ce7a5
|
|
@@ -45,28 +45,20 @@ class Shrine
|
|
|
45
45
|
|
|
46
46
|
def upload(io, id, shrine_metadata: {}, **_options)
|
|
47
47
|
# uploads `io` to the location `id`
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
file_metadata,
|
|
63
|
-
fields: 'id',
|
|
64
|
-
upload_source: file.binmode,
|
|
65
|
-
content_type: file.content_type,
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
after_upload
|
|
69
|
-
@queued_for_write = {}
|
|
48
|
+
shrine_metadata = {
|
|
49
|
+
name: id,
|
|
50
|
+
description: 'shrine file on google drive',
|
|
51
|
+
mimeType: mime_type,
|
|
52
|
+
parents: folder_id
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
google_api_client.create_file(
|
|
56
|
+
shrine_metadata,
|
|
57
|
+
fields: 'id, name',
|
|
58
|
+
upload_source: io.to_io,
|
|
59
|
+
content_type: shrine_metadata["mime_type"]
|
|
60
|
+
)
|
|
61
|
+
message = "Uploaded file #{file.name} with Id: #{file.id}"
|
|
70
62
|
end
|
|
71
63
|
|
|
72
64
|
def google_api_client
|
|
@@ -83,178 +75,133 @@ class Shrine
|
|
|
83
75
|
|
|
84
76
|
def url(id, **_options)
|
|
85
77
|
# URL to the remote file, accepts options for customizing the URL
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
public_url_custom_thumbnail_from(file_name, custom_width)
|
|
93
|
-
else
|
|
94
|
-
file_name = filename_from(style)
|
|
95
|
-
public_url_for(file_name)
|
|
96
|
-
end
|
|
97
|
-
else
|
|
98
|
-
default_image
|
|
99
|
-
end
|
|
78
|
+
client = google_api_client
|
|
79
|
+
metadata = client.get_file(
|
|
80
|
+
id,
|
|
81
|
+
fields: 'webViewLink'
|
|
82
|
+
)
|
|
83
|
+
metadata.web_view_link
|
|
100
84
|
end
|
|
101
85
|
|
|
102
|
-
def is_valid_for_custom_thumb?
|
|
103
|
-
content_type =~ /image/ || content_type =~ /pdf/
|
|
104
|
-
end
|
|
105
86
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
87
|
+
def download(id)
|
|
88
|
+
client = google_api_client
|
|
89
|
+
tempfile = Tempfile.new(["googledrive", File.extname(id)], binmode: true)
|
|
90
|
+
client.get_file(
|
|
91
|
+
id,
|
|
92
|
+
download_dest: tempfile)
|
|
93
|
+
tempfile.tap(&:open)
|
|
94
|
+
end
|
|
111
95
|
|
|
112
96
|
def open(id)
|
|
113
97
|
# returns the remote file as an IO-like object
|
|
114
|
-
if file_id.is_a? String
|
|
115
98
|
client = google_api_client
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
99
|
+
io = client.get_file(
|
|
100
|
+
id,
|
|
101
|
+
download_dest: StringIO.new
|
|
119
102
|
)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
end
|
|
103
|
+
io.rewind
|
|
104
|
+
io
|
|
123
105
|
end
|
|
124
106
|
|
|
125
|
-
# Raises an error in case that the Google Drive API does not response
|
|
126
|
-
# with the minimum required information.
|
|
127
|
-
# @params [ Google::Apis::DriveV3::File ]
|
|
128
|
-
def validate_metadata(metadata)
|
|
129
|
-
raise 'the file id was not retrieved' if metadata.id.nil?
|
|
130
|
-
raise 'the file name was not retrieved' if metadata.name.nil?
|
|
131
|
-
raise 'the file web_content_link was not retrieved' if metadata.web_content_link.nil?
|
|
132
|
-
raise 'the file web_view_link was not retrieved' if metadata.web_view_link.nil?
|
|
133
|
-
raise 'the file trashed was not retrieved' if metadata.trashed.nil?
|
|
134
|
-
end
|
|
135
107
|
|
|
136
108
|
def exists?(id)
|
|
137
109
|
# checks if the file exists on the storage
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Gets the file metadata if it exists
|
|
149
|
-
# in other case returns the defaul image
|
|
150
|
-
# @param title [ String ]
|
|
151
|
-
# @param block [ Proc ]
|
|
152
|
-
def metadata_or_default_img_from(title, &block)
|
|
153
|
-
searched_id = search_for_title(title) #return id if any or style
|
|
154
|
-
if searched_id.nil? # it finds some file
|
|
155
|
-
default_image
|
|
156
|
-
else
|
|
157
|
-
metadata = metadata_by_id(searched_id)
|
|
158
|
-
yield metadata
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def default_image
|
|
163
|
-
if @google_drive_options[:default_url] #if default image is set
|
|
164
|
-
title = @google_drive_options[:default_url]
|
|
165
|
-
searched_id = search_for_title(title) # id
|
|
166
|
-
if searched_id.nil?
|
|
167
|
-
raise 'Default image not found, please double check its name'
|
|
110
|
+
client = google_api_client
|
|
111
|
+
client.get_file(id) do |_, err|
|
|
112
|
+
if err
|
|
113
|
+
if err.status_code == 404
|
|
114
|
+
false
|
|
115
|
+
else
|
|
116
|
+
raise err
|
|
117
|
+
end
|
|
168
118
|
else
|
|
169
|
-
|
|
170
|
-
effective_url_from(metadata.web_content_link)
|
|
119
|
+
true
|
|
171
120
|
end
|
|
172
|
-
else
|
|
173
|
-
'No picture' # ---- ?
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def find_public_folder
|
|
178
|
-
if @google_drive_options[:public_folder_id].is_a? Proc
|
|
179
|
-
instance.instance_exec(&@google_drive_options[:public_folder_id])
|
|
180
|
-
else
|
|
181
|
-
@google_drive_options[:public_folder_id]
|
|
182
121
|
end
|
|
183
122
|
end
|
|
184
123
|
|
|
185
124
|
def delete(id)
|
|
186
125
|
# deletes the file from the storage
|
|
187
|
-
|
|
188
|
-
Shrine.log("Delete: #{ path }")
|
|
189
|
-
file_id = search_for_title(path)
|
|
190
|
-
google_api_client.delete_file(file_id) unless file_id.nil?
|
|
191
|
-
end
|
|
192
|
-
@queued_for_delete = []
|
|
193
|
-
end
|
|
126
|
+
google_api_client.delete_file(id) unless id.nil?
|
|
194
127
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if original_extension.present? && file_name =~ /#{original_extension}$/
|
|
199
|
-
file_name.sub(original_extension, "#{style_suffix}#{original_extension}")
|
|
200
|
-
else
|
|
201
|
-
file_name + style_suffix + original_extension.to_s
|
|
202
|
-
end
|
|
203
|
-
end
|
|
128
|
+
rescue Google::Apis::ClientError => e
|
|
129
|
+
# The object does not exist, Shrine expects us to be ok
|
|
130
|
+
return true if e.status_code == 404
|
|
204
131
|
|
|
205
|
-
|
|
132
|
+
raise e
|
|
133
|
+
end
|
|
206
134
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
custom_thumbnail_image_for(metadata.thumbnail_link, 1000)
|
|
215
|
-
else
|
|
216
|
-
metadata.web_view_link
|
|
135
|
+
def multi_delete(ids)
|
|
136
|
+
client = google_api_client
|
|
137
|
+
ids.each_slice(100) do |ids|
|
|
138
|
+
client.batch do |client|
|
|
139
|
+
ids.each do |id|
|
|
140
|
+
client.delete_object(id)
|
|
141
|
+
end
|
|
217
142
|
end
|
|
218
143
|
end
|
|
219
144
|
end
|
|
220
145
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
146
|
+
def create_folder(name)
|
|
147
|
+
client = google_api_client
|
|
148
|
+
file_metadata = {
|
|
149
|
+
name: name,
|
|
150
|
+
mime_type: 'application/vnd.google-apps.folder'
|
|
151
|
+
}
|
|
152
|
+
file = client.create_file(file_metadata, fields: 'id, name')
|
|
153
|
+
message = "Created folder #{file.name} with folder id: #{file.id}"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def find_folder_id(name)
|
|
157
|
+
client = google_api_client
|
|
158
|
+
page_token = nil
|
|
159
|
+
begin
|
|
160
|
+
response = client.list_files(q: "mimeType = 'application/vnd.google-apps.folder' and name contains '#{ name }'",
|
|
161
|
+
spaces: 'drive',
|
|
162
|
+
fields:'nextPageToken, files(id, name)',
|
|
163
|
+
page_token: page_token)
|
|
164
|
+
for file in response.files
|
|
165
|
+
# Process change
|
|
166
|
+
message = "Found folder: #{file.name} ID: #{file.id}"
|
|
167
|
+
end
|
|
168
|
+
page_token = response.next_page_token
|
|
169
|
+
end while !page_token.nil?
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def insert_in_folder(file_id, folder_id)
|
|
173
|
+
client = google_api_client
|
|
174
|
+
file = client.update_file(file_id,
|
|
175
|
+
add_parents: folder_id,
|
|
176
|
+
fields: 'id, name, parents')
|
|
177
|
+
message = "File #{file.name} with ID #{file.id} inserted into folder #{file.parents}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def move_file(file_id, new_folder_id)
|
|
181
|
+
client = google_api_client
|
|
182
|
+
# Retrieve the existing parents to remove
|
|
183
|
+
file = client.get_file(file_id,
|
|
184
|
+
fields: 'parents')
|
|
185
|
+
previous_parents = file.parents.join(',')
|
|
186
|
+
# Move the file to the new folder
|
|
187
|
+
file = client.update_file(file_id,
|
|
188
|
+
add_parents: new_folder_id,
|
|
189
|
+
remove_parents: previous_parents,
|
|
190
|
+
fields: 'id, name, parents')
|
|
191
|
+
message = "File #{file.name} with ID #{file.id} moved to folder #{file.parents}"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def file_name(file_id)
|
|
195
|
+
client = google_api_client
|
|
196
|
+
metadata = client.get_file(
|
|
197
|
+
file_id,
|
|
198
|
+
fields: 'id, name'
|
|
199
|
+
)
|
|
200
|
+
metadata.name
|
|
229
201
|
end
|
|
230
202
|
|
|
231
|
-
|
|
232
|
-
# pass the :custom_thumb as style option. In other cases, it removes the last parameter
|
|
233
|
-
# `=s220` which is inchaged to do the scaling process.
|
|
234
|
-
# @param drive_thumbnail_link [ String ] with the form: https://<url value>=s220
|
|
235
|
-
# @param custom_width [ Integer ] ex. 512
|
|
236
|
-
# @return [ String ]
|
|
237
|
-
def custom_thumbnail_image_for(drive_thumbnail_link, custom_width)
|
|
238
|
-
file_url, current_width = drive_thumbnail_link.split(/=s/)
|
|
239
|
-
"#{ file_url }=s#{ custom_width }"
|
|
240
|
-
end
|
|
203
|
+
alias_method :object_name
|
|
241
204
|
|
|
242
|
-
# TOO SLOW and PERMISSIONS ISSUES
|
|
243
|
-
# Seems that the retrieved file url is only visible for the
|
|
244
|
-
# user which is owner and is currently log in GDrive.
|
|
245
|
-
#
|
|
246
|
-
# Gets the effective url from the web content link
|
|
247
|
-
# These are a series of steps to hack the way that GDrive API
|
|
248
|
-
# handle its urls. It consists in catch a Google::Apis::RedirectError error
|
|
249
|
-
# and take the correct url where is located the file.
|
|
250
|
-
# @param driver_web_content_link [ String ]
|
|
251
|
-
# @return [ String ]
|
|
252
|
-
def effective_url_from(drive_web_content_link)
|
|
253
|
-
redirect_url = drive_web_content_link.split(/&export=/)[0]
|
|
254
|
-
google_drive.http(:get, redirect_url) do |result, err|
|
|
255
|
-
err.header[:location].split('&continue=')[1]
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
205
|
|
|
259
206
|
# Takes the file title/name and search it in a given folder
|
|
260
207
|
# If it finds a file, return id of a file or nil
|
|
@@ -264,7 +211,7 @@ class Shrine
|
|
|
264
211
|
raise 'You are trying to search a file with NO name' if name.nil? || name.empty?
|
|
265
212
|
client = google_api_client
|
|
266
213
|
result = client.list_files(page_size: 1,
|
|
267
|
-
q: "name contains '#{ name }'
|
|
214
|
+
q: "name contains '#{ name }'",
|
|
268
215
|
fields: 'files(id, name)'
|
|
269
216
|
)
|
|
270
217
|
if result.files.length > 0
|
|
@@ -274,25 +221,6 @@ class Shrine
|
|
|
274
221
|
end
|
|
275
222
|
end
|
|
276
223
|
|
|
277
|
-
#
|
|
278
|
-
# Error classes
|
|
279
|
-
#
|
|
280
|
-
|
|
281
|
-
class FileExists < ArgumentError
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
private
|
|
285
|
-
|
|
286
|
-
def file_title
|
|
287
|
-
return @google_drive_options[:path] if @google_drive_options[:path] #path: proc
|
|
288
|
-
eval %(proc { |style| "\#{id}_\#{#{name}.original_filename}"})
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# @return [String] with the extension of file
|
|
292
|
-
def original_extension
|
|
293
|
-
File.extname(original_filename)
|
|
294
|
-
end
|
|
295
|
-
|
|
296
224
|
end
|
|
297
225
|
end
|
|
298
226
|
end
|
data/lib/shrine/version.rb
CHANGED
|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.authors = ["Scott Near"]
|
|
10
10
|
spec.email = ["scott.a.near@gmail.com"]
|
|
11
11
|
|
|
12
|
-
spec.summary = "Provides Google
|
|
13
|
-
spec.description = "Provides Google Drive Storage
|
|
12
|
+
spec.summary = "Provides Google Drive Storage for Shrine."
|
|
13
|
+
spec.description = "Provides Google Drive Storage for Shrine."
|
|
14
14
|
spec.homepage = "https://github.com/verynear/shrine-google_drive_storage"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shrine-google_drive_storage
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Near
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-06-
|
|
11
|
+
date: 2017-06-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: shrine
|
|
@@ -140,7 +140,7 @@ dependencies:
|
|
|
140
140
|
- - ">="
|
|
141
141
|
- !ruby/object:Gem::Version
|
|
142
142
|
version: 4.2.0
|
|
143
|
-
description: Provides Google Drive Storage
|
|
143
|
+
description: Provides Google Drive Storage for Shrine.
|
|
144
144
|
email:
|
|
145
145
|
- scott.a.near@gmail.com
|
|
146
146
|
executables:
|
|
@@ -191,5 +191,5 @@ rubyforge_project:
|
|
|
191
191
|
rubygems_version: 2.6.10
|
|
192
192
|
signing_key:
|
|
193
193
|
specification_version: 4
|
|
194
|
-
summary: Provides Google
|
|
194
|
+
summary: Provides Google Drive Storage for Shrine.
|
|
195
195
|
test_files: []
|