paperclip-google-drive 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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