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 +4 -4
- data/lib/paperclip/google_drive/session.rb +62 -33
- data/lib/paperclip/google_drive/tasks.rake +1 -1
- data/lib/paperclip/storage/google_drive.rb +91 -50
- data/lib/paperclip/version.rb +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: 06f945a112a7fc9c7edc1c8b925bb957011f26ba
|
4
|
+
data.tar.gz: 7ff404b4f10d203c306efebe144ca86e5f449a06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
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
|
-
#
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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 |
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
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
|
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
|
-
|
150
|
+
custom_image_for(metadata.thumbnail_link, custom_width)
|
128
151
|
end
|
129
152
|
end
|
130
153
|
|
131
|
-
#
|
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
|
135
|
-
drive_thumbnail_link.split(/=s/)
|
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
|
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
|
-
|
193
|
+
metadata = client.get_file(
|
162
194
|
file_id,
|
163
195
|
fields: 'id, name, thumbnailLink'
|
164
196
|
)
|
165
|
-
|
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
|
-
|
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
|
data/lib/paperclip/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2016-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: paperclip
|