paperclip-google-drive 0.2.4 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69f1e775714355167b9e85e90dfd7253f1d8b20d
4
- data.tar.gz: 56a69a0462cccee0ba272ecc6cfd6ca857ca0e3b
3
+ metadata.gz: 06f945a112a7fc9c7edc1c8b925bb957011f26ba
4
+ data.tar.gz: 7ff404b4f10d203c306efebe144ca86e5f449a06
5
5
  SHA512:
6
- metadata.gz: 115f4d3fb27f33dd9d21a48a377e7b3445dfb817778464c91dabf8d9cf8ab56952f5cc53ddce1d1ab94f9b852aa51f53adee01afe51d41abebc5e73ea69a3178
7
- data.tar.gz: afb020197387bc07cec4cc69df47600adb46eb7f8ab54ead3f59dedbd41de49d75f7b3793b2df1729cbfdce2e6466cb88316ac36dd05c40f81817a8c7696c8cb
6
+ metadata.gz: c228c2ff00f14992a98974fb94d4da90e230d7b357feb93ab4805f49923ceec9a2aeb09922b0b7fd53107c788673ff46fc261539ce3db6683c2223f3716ed64f
7
+ data.tar.gz: 68d6878eea81fb2b9fec1607ad32a77f932c1e0199ba0630ac506833b9f88b10aafe7b42b1ad9f1ea1c3380b217c4451bd1af5a8026ee74b32e1f0ca29570f6f
@@ -32,47 +32,76 @@ module Paperclip
32
32
  # scope
33
33
  # scope=
34
34
  # save
35
- def self.from_config(config, options = {})
36
- fail(ArgumentError, 'You must to specified the application_name option') unless options[:application_name]
37
-
38
- if config.is_a?(String)
39
- config = Paperclip::GoogleDrive::Config.new(config)
35
+ class << self
36
+ def from_config(config_path, options = {})
37
+ validate_options(options)
38
+ config = get_cofiguration(config_path, options)
39
+ credentials = Google::Auth::UserRefreshCredentials.new(
40
+ client_id: config.client_id,
41
+ client_secret: config.client_secret,
42
+ scope: config.scope,
43
+ redirect_uri: 'urn:ietf:wg:oauth:2.0:oob'
44
+ )
45
+ if config.refresh_token
46
+ credentials.refresh_token = config.refresh_token
47
+ credentials.fetch_access_token!
48
+ else
49
+ $stderr.print("\n1. Open this page:\n%s\n\n" % credentials.authorization_uri)
50
+ $stderr.print('2. Enter the authorization code shown in the page: ')
51
+ credentials.code = $stdin.gets.chomp
52
+ credentials.fetch_access_token!
53
+ config.refresh_token = credentials.refresh_token
54
+ end
55
+ config.save
56
+ init_drive_service(options[:application_name], credentials)
40
57
  end
41
58
 
42
- config.scope ||= DEFAULT_SCOPE
43
-
44
- if options[:client_id] && options[:client_secret]
45
- config.client_id = options[:client_id]
46
- config.client_secret = options[:client_secret]
47
- elsif (options[:client_id] && !options[:client_secret]) ||
48
- (!options[:client_id] && options[:client_secret])
49
- fail(ArgumentError, 'client_id and client_secret must be both specified or both omitted')
59
+ # @param config_path [ String ]
60
+ # @param options [ Hash ]
61
+ # @return [ Paperclip::GoogleDrive::Config ]
62
+ def get_cofiguration(config_path, options)
63
+ if config_path.is_a?(String)
64
+ config = Paperclip::GoogleDrive::Config.new(config_path)
65
+ else
66
+ raise(ArgumentError, 'You must set a valid config_path path')
67
+ end
68
+ config.scope ||= DEFAULT_SCOPE
69
+ config_from_options(config, options)
50
70
  end
51
71
 
52
- credentials = Google::Auth::UserRefreshCredentials.new(
53
- client_id: config.client_id,
54
- client_secret: config.client_secret,
55
- scope: config.scope,
56
- redirect_uri: 'urn:ietf:wg:oauth:2.0:oob')
72
+ # @param options [ Hash ]
73
+ # @param config [ Paperclip::GoogleDrive::Config ]
74
+ # @return [ Paperclip::GoogleDrive::Config ]
75
+ def config_from_options(config, options)
76
+ if options[:client_id] && options[:client_secret]
77
+ config.client_id = options[:client_id]
78
+ config.client_secret = options[:client_secret]
79
+ end
80
+ config
81
+ end
57
82
 
58
- if config.refresh_token
59
- credentials.refresh_token = config.refresh_token
60
- credentials.fetch_access_token!
61
- else
62
- $stderr.print("\n1. Open this page:\n%s\n\n" % credentials.authorization_uri)
63
- $stderr.print('2. Enter the authorization code shown in the page: ')
64
- credentials.code = $stdin.gets.chomp
65
- credentials.fetch_access_token!
66
- config.refresh_token = credentials.refresh_token
83
+ # @param options [ Hash ]
84
+ def validate_options(options)
85
+ raise(ArgumentError, 'You must specify the application_name option') unless options[:application_name]
86
+ raise(ArgumentError, 'client_id and client_secret must be both specified or both omitted') if invalid_client_options?(options)
67
87
  end
68
88
 
69
- config.save
89
+ # @param options [ Hash ]
90
+ # @return [ Boolean ]
91
+ def invalid_client_options?(options)
92
+ (options[:client_id] && !options[:client_secret]) || (!options[:client_id] && options[:client_secret])
93
+ end
70
94
 
71
- # Initialize the API
72
- client = Google::Apis::DriveV3::DriveService.new
73
- client.client_options.application_name = options[:application_name]
74
- client.authorization = credentials
75
- client
95
+ # @param application_name [ String ]
96
+ # @param credentials [ Google::Auth::UserRefreshCredentials ]
97
+ # @return [ Google::Apis::DriveV3::DriveService ]
98
+ def init_drive_service(application_name, credentials)
99
+ # Initialize the API
100
+ client = Google::Apis::DriveV3::DriveService.new
101
+ client.client_options.application_name = application_name
102
+ client.authorization = credentials
103
+ client
104
+ end
76
105
  end
77
106
  end
78
107
  end
@@ -2,7 +2,7 @@ require "paperclip/google_drive/rake"
2
2
 
3
3
  namespace :google_drive do
4
4
  desc "Authorize Google Drive account: "
5
- task :authorize, [:client_secret_path, :application_name] do |t, args|
5
+ task :authorize, [:client_secret_path, :application_name] do |_t, args|
6
6
  client_secret_path = args[:client_secret_path]
7
7
  application_name = args[:application_name]
8
8
  Paperclip::GoogleDrive::Rake.authorize(client_secret_path, application_name)
@@ -11,44 +11,48 @@ require 'paperclip/google_drive/session'
11
11
  require 'fileutils'
12
12
 
13
13
  module Paperclip
14
-
15
14
  module Storage
16
- # * self.extended(base) add instance variable to attachment on call
17
- # * url return url to show on site with style options
18
- # * path(style) return title that used to insert file to store or find it in store
19
- # * public_url_for title return url to file if find by title or url to default image if set
20
- # * search_for_title(title) take title, search in given folder and if it finds a file, return id of a file or nil
21
- # * metadata_by_id(file_i get file metadata from store, used to back url or find out value of trashed
22
- # * exists?(style) check either exists file with title or not
23
- # * default_image return url to default url if set in option
24
- # * find_public_folder return id of Public folder, must be in options
25
- # return id of Public folder, must be in options
26
- # * file_title return base pattern of title or custom one set by user
27
- # * original_extension return extension of file
28
-
15
+ # * self.extended(base) add instance variable to attachment on call
16
+ # * url return url to show on site with style options
17
+ # * path(style) return title that used to insert file to store or find it in store
18
+ # * public_url_for title return url to file if find by title or url to default image if set
19
+ # * search_for_title(title) take title, search in given folder and if it finds a file, return id of a file or nil
20
+ # * metadata_by_id(file_i get file metadata from store, used to back url or find out value of trashed
21
+ # * exists?(style) check either exists file with title or not
22
+ # * default_image return url to default url if set in option
23
+ # * find_public_folder return id of Public folder, must be in options
24
+ # return id of Public folder, must be in options
25
+ # * file_title return base pattern of title or custom one set by user
26
+ # * original_extension return extension of file
29
27
  module GoogleDrive
30
- def self.extended(base)
31
- begin
32
- require 'google-api-client'
33
- rescue LoadError => e
34
- e.message << "(You may need to install the google-api-client gem)"
35
- raise e
36
- end unless defined?(Google)
37
-
38
- base.instance_eval do
39
- @google_drive_client_secret_path = @options[:google_drive_client_secret_path]
40
- @google_drive_options = @options[:google_drive_options] || { application_name: 'test-app' }
41
- fail(ArgumentError, 'You must to provide a valid google_drive_client_secret_path option') unless @google_drive_client_secret_path
42
- google_api_client # Force validations of credentials
28
+ class << self
29
+ def extended(base)
30
+ check_gem_is_installed
31
+ base.instance_eval do
32
+ @google_drive_client_secret_path = @options[:google_drive_client_secret_path]
33
+ @google_drive_options = @options[:google_drive_options] || { application_name: 'test-app' }
34
+ raise(ArgumentError, 'You must provide a valid google_drive_client_secret_path option') unless @google_drive_client_secret_path
35
+ raise(ArgumentError, 'You must set the public_folder_id option') unless @google_drive_options[:public_folder_id]
36
+ google_api_client # Force validations of credentials
37
+ end
38
+ end
39
+
40
+ def check_gem_is_installed
41
+ begin
42
+ require 'google-api-client'
43
+ rescue LoadError => e
44
+ e.message << '(You may need to install the google-api-client gem)'
45
+ raise e
46
+ end unless defined?(Google)
43
47
  end
44
48
  end
45
49
 
46
- #
50
+ # Main process to upload a file
47
51
  def flush_writes
48
52
  @queued_for_write.each do |style, file|
49
53
  raise FileExists, "file \"#{path(style)}\" already exists in your Google Drive" if exists?(path(style))
50
54
 
51
- name, mime_type = name_for_file(style), "#{ file.content_type }"
55
+ name, mime_type = name_for_file_from(style), "#{ file.content_type }"
52
56
 
53
57
  file_metadata = {
54
58
  name: name,
@@ -57,7 +61,7 @@ module Paperclip
57
61
  parents: [find_public_folder]
58
62
  }
59
63
 
60
- result = google_api_client.create_file(
64
+ google_api_client.create_file(
61
65
  file_metadata,
62
66
  fields: 'id',
63
67
  upload_source: file.binmode,
@@ -68,12 +72,12 @@ module Paperclip
68
72
  @queued_for_write = {}
69
73
  end
70
74
 
71
- #
75
+ # Process to destroy a file
72
76
  def flush_deletes
73
77
  @queued_for_delete.each do |path|
74
- Paperclip.log("Delete: #{path}")
78
+ Paperclip.log("Delete: #{ path }")
75
79
  file_id = search_for_title(path)
76
- result = google_api_client.delete_file(file_id) unless file_id.nil?
80
+ google_api_client.delete_file(file_id) unless file_id.nil?
77
81
  end
78
82
  @queued_for_delete = []
79
83
  end
@@ -91,21 +95,37 @@ module Paperclip
91
95
 
92
96
  alias_method :google_drive, :google_api_client
93
97
 
98
+ # This could be used to scale image as Google does. e.i. `<url>=s220`,
99
+ # where 220 is the width in pixeles OR as Paperclip does.
100
+ # @params args [ Array ]
101
+ # @return [ String ]
102
+ # ex.
103
+ # 1. If you want the medium version of your image (Paperclip way)
104
+ # some_model.avatar.url(:medium)
105
+ # 2. If you want a custom version of your image/pdf (Google way)
106
+ # some_model.avatar.url(:custom, width: 500)
94
107
  def url(*args)
95
108
  if present?
96
109
  style = args.first.is_a?(Symbol) ? args.first : default_style
97
110
  options = args.last.is_a?(Hash) ? args.last : {}
98
- public_url_for(path(style))
111
+ if style == :custom
112
+ custom_width = options[:width] || 220
113
+ file_name = name_for_file_from(default_style)
114
+ else
115
+ custom_width = nil
116
+ file_name = name_for_file_from(style)
117
+ end
118
+
119
+ public_url_for(file_name, custom_width)
99
120
  else
100
121
  default_image
101
122
  end
102
123
  end
103
124
 
104
- def path(style)
105
- name_for_file(style)
106
- end
107
-
108
- def name_for_file(style)
125
+ # Gets full title/name
126
+ # @param style [ String ]
127
+ # @return [ String ]
128
+ def name_for_file_from(style)
109
129
  file_name = instance.instance_exec(style, &file_title)
110
130
  style_suffix = (style != default_style ? "_#{style}" : "")
111
131
  if original_extension.present? && file_name =~ /#{original_extension}$/
@@ -113,26 +133,37 @@ module Paperclip
113
133
  else
114
134
  file_name + style_suffix + original_extension.to_s
115
135
  end
116
- end # full title
136
+ end
137
+
138
+ alias_method :path, :name_for_file_from
117
139
 
118
140
  # Gets the public url for a passed filename
119
141
  # @param title [ String ]
142
+ # @param custom_width [ Integer ]
120
143
  # @return [ String ] with url
121
- def public_url_for(title)
144
+ def public_url_for(title, custom_width)
122
145
  searched_id = search_for_title(title) #return id if any or style
123
146
  if searched_id.nil? # it finds some file
124
147
  default_image
125
148
  else
126
149
  metadata = metadata_by_id(searched_id)
127
- full_image_for(metadata.thumbnail_link) #web_content_link #or metadata.web_view_link?
150
+ custom_image_for(metadata.thumbnail_link, custom_width)
128
151
  end
129
152
  end
130
153
 
131
- # Removes the last parameter `=s220` which is inchaged to scale the retrieved image
154
+ # Retrieves the specific image with a custom size. It is resized by GDrive API if you
155
+ # pass the :custom as style option. In other cases it removes the last parameter `=s220`
156
+ # which is inchaged to do the scaling process.
132
157
  # @param drive_thumbnail_link [ String ]
158
+ # @param custom_width [ Integer ]
133
159
  # @return [ String ]
134
- def full_image_for(drive_thumbnail_link)
135
- drive_thumbnail_link.split(/=s/)[0]
160
+ def custom_image_for(drive_thumbnail_link, custom_width=nil)
161
+ file_url, current_width = drive_thumbnail_link.split(/=s/)
162
+ new_file_url = if custom_width.nil?
163
+ file_url
164
+ else
165
+ "#{ file_url }=s#{ custom_width }"
166
+ end
136
167
  end
137
168
 
138
169
  # Takes the file title/name and search it in a given folder
@@ -146,26 +177,37 @@ module Paperclip
146
177
  q: "name contains '#{ name }' and '#{ find_public_folder }' in parents",
147
178
  fields: 'files(id, name)'
148
179
  )
149
- if result.files.length > 0 # TODO: change these coditionals
180
+ if result.files.length > 0
150
181
  result.files[0].id
151
182
  else
152
183
  nil
153
184
  end
154
185
  end
155
186
 
187
+ # Gets a file from GDrive
156
188
  # @parent file_id [ String ]
157
189
  # @return [ Google::Apis::DriveV3::File ]
158
190
  def metadata_by_id(file_id)
159
191
  if file_id.is_a? String
160
192
  client = google_api_client
161
- result = client.get_file(
193
+ metadata = client.get_file(
162
194
  file_id,
163
195
  fields: 'id, name, thumbnailLink'
164
196
  )
165
- result
197
+ validate_metadata(metadata)
198
+ metadata
166
199
  end
167
200
  end
168
201
 
202
+ # Raises an error in case that the Google Drive API does not response
203
+ # with the minimum required information.
204
+ # @params [ Google::Apis::DriveV3::File ]
205
+ def validate_metadata(metadata)
206
+ raise 'the file id was not retrieved' if metadata.id.nil?
207
+ raise 'the file name was not retrieved' if metadata.name.nil?
208
+ raise 'the file thumbnail_link was not retrieved' if metadata.thumbnail_link.nil?
209
+ end
210
+
169
211
  # Checks if the image already exits
170
212
  # @param style [ String ]
171
213
  # @return [ Boolean ]
@@ -185,14 +227,13 @@ module Paperclip
185
227
  title = @google_drive_options[:default_url]
186
228
  searched_id = search_for_title(title) # id
187
229
  metadata = metadata_by_id(searched_id) unless searched_id.nil?
188
- full_image_for(metadata.thumbnail_link) #web_view_link #web_content_link
230
+ custom_image_for(metadata.thumbnail_link)
189
231
  else
190
232
  'No picture' # ---- ?
191
233
  end
192
234
  end
193
235
 
194
236
  def find_public_folder
195
- raise KeyError, "You must set the public_folder_id option" unless @google_drive_options[:public_folder_id]
196
237
  if @google_drive_options[:public_folder_id].is_a? Proc
197
238
  instance.instance_exec(&@google_drive_options[:public_folder_id])
198
239
  else
@@ -1,3 +1,3 @@
1
1
  module PaperclipGoogleDrive
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-google-drive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diego Gomez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-15 00:00:00.000000000 Z
11
+ date: 2016-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paperclip