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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b7fcd9c23ef5b5c97e5083d68fa883319edc155
4
- data.tar.gz: 647ed18c25768aace7c773daedc7714e5aef6309
3
+ metadata.gz: 20ce8cde9408e42b0f6760dcc15037cf42f6791d
4
+ data.tar.gz: deaa6b58b6a306508fddcff85fa2e27af192d481
5
5
  SHA512:
6
- metadata.gz: 44023b697469e030042fc1a1658959cda9dfb153bf82b51d8433737f53b900a8218b3b42191d901ee6b6fb9e43677daff99055796aa679bc71e8283b00b0a8f6
7
- data.tar.gz: b38a40f54baf375d24239cf7b47c588bda05e1f670ebf275c2dc91e70d78d56202fadee066ac44e316e5988e3329140980d7e1b1d8ce88c0aaa424b845e4744f
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
- @queued_for_write.each do |style, file|
50
- raise FileExists, "file \"#{path(style)}\" already exists in your Google Drive" if exists?(path(style))
51
-
52
- name, mime_type = filename_from(style), "#{ file.content_type }"
53
-
54
- file_metadata = {
55
- name: name,
56
- description: 'shrine file on google drive',
57
- mimeType: mime_type,
58
- parents: [find_public_folder]
59
- }
60
-
61
- google_api_client.create_file(
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
- if present?
87
- style = args.first.is_a?(Symbol) ? args.first : default_style
88
- options = args.last.is_a?(Hash) ? args.last : {}
89
- if style == :custom_thumb && is_valid_for_custom_thumb?
90
- custom_width = options[:width] || 220
91
- file_name = filename_from(default_style)
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
- # def download(id)
107
- # tempfile = Tempfile.new(["googlestorage", File.extname(id)], binmode: true)
108
- # storage_api.get_object(@bucket, object_name(id), download_dest: tempfile)
109
- # tempfile.tap(&:open)
110
- # end
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
- metadata = client.get_file(
117
- file_id,
118
- fields: 'id, name, thumbnailLink, webContentLink, webViewLink, trashed'
99
+ io = client.get_file(
100
+ id,
101
+ download_dest: StringIO.new
119
102
  )
120
- validate_metadata(metadata)
121
- metadata
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
- return false if not present?
139
- result_id = search_for_title(path(style))
140
- if result_id.nil?
141
- false
142
- else
143
- data = metadata_by_id(result_id)
144
- !data.trashed # if trashed -> not exists
145
- end
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
- metadata = metadata_by_id(searched_id)
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
- @queued_for_delete.each do |path|
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
- def filename_from(style)
196
- file_name = instance.instance_exec(style, &file_title)
197
- style_suffix = (style != default_style ? "_#{style}" : "")
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
- alias_method :path, :filename_from
132
+ raise e
133
+ end
206
134
 
207
- # Gets the public url for a passed filename
208
- # @param title [ String ]
209
- # @return [ String ] with url
210
- def public_url_for(title)
211
- metadata_or_default_img_from(title) do |metadata|
212
- # effective_url_from(metadata.web_content_link)
213
- if content_type =~ /image/
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
- # Gets the public url for a passed filename
222
- # @param title [ String ]
223
- # @param custom_width [ Integer ]
224
- # @return [ String ] with url
225
- def public_url_custom_thumbnail_from(title, custom_width)
226
- metadata_or_default_img_from(title) do |metadata|
227
- custom_thumbnail_image_for(metadata.thumbnail_link, custom_width)
228
- end
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
- # Retrieves the specific image with a custom size. It is resized by GDrive API if you
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 }' and '#{ find_public_folder }' in parents",
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
@@ -1,5 +1,5 @@
1
1
  module Shrine
2
2
  module GoogleDriveStorage
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.1"
4
4
  end
5
5
  end
@@ -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 Cloud Storage storage for Shrine."
13
- spec.description = "Provides Google Drive Storage storage for Shrine."
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.1.1
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-27 00:00:00.000000000 Z
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 storage for Shrine.
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 Cloud Storage storage for Shrine.
194
+ summary: Provides Google Drive Storage for Shrine.
195
195
  test_files: []