paperclip-google-drive 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +120 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/paperclip-google-drive.rb +5 -0
- data/lib/paperclip/google_drive.rb +2 -0
- data/lib/paperclip/google_drive/config.rb +44 -0
- data/lib/paperclip/google_drive/railtie.rb +10 -0
- data/lib/paperclip/google_drive/rake.rb +38 -0
- data/lib/paperclip/google_drive/session.rb +79 -0
- data/lib/paperclip/google_drive/tasks.rake +11 -0
- data/lib/paperclip/storage/google_drive.rb +220 -0
- data/lib/paperclip/version.rb +3 -0
- data/paperclip-google-drive.gemspec +37 -0
- metadata +219 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e4b3dff7c90edf224a4aa0eb34a9171e8c4500d2
|
4
|
+
data.tar.gz: f0f885e0894000ecaf130bd67b4deafcac437682
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb808cd7e7467354fc158e8171a26a47a041a75b30fbba81bce4244c44ca8b6ceb453c5ac3f646c26e2ca8eb2323711f6a865603ac3e3ad20e4c4317a2648236
|
7
|
+
data.tar.gz: c6d63cc09d0071fe9b57c9eff052b7ed28d57107cf1bc5920daab0d7ca53fe01527df3fc70b8c61fa69fc49278a625b46ec25d9de0a6b8fdb793212449cef8d1
|
data/.gitignore
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
*.log
|
2
|
+
*.gem
|
3
|
+
*.rbc
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.yardoc
|
7
|
+
Gemfile.lock
|
8
|
+
InstalledFiles
|
9
|
+
_yardoc
|
10
|
+
coverage
|
11
|
+
doc/
|
12
|
+
lib/bundler/man
|
13
|
+
pkg
|
14
|
+
rdoc
|
15
|
+
spec/reports
|
16
|
+
test/tmp
|
17
|
+
test/version_tmp
|
18
|
+
tmp
|
19
|
+
*.rbc
|
20
|
+
*.sassc
|
21
|
+
.sass-cache
|
22
|
+
capybara-*.html
|
23
|
+
.rspec
|
24
|
+
/.bundle
|
25
|
+
/vendor/bundle
|
26
|
+
/log/*
|
27
|
+
/tmp/*
|
28
|
+
/db/*.sqlite3
|
29
|
+
/public/system/*
|
30
|
+
/coverage/
|
31
|
+
/spec/tmp/*
|
32
|
+
**.orig
|
33
|
+
rerun.txt
|
34
|
+
pickle-email-*.html
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ivan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# PaperclipGoogledrive
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/paperclip-googledrive.png)](http://badge.fury.io/rb/paperclip-googledrive)
|
3
|
+
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/evinsou/paperclip-googledrive)
|
4
|
+
|
5
|
+
PaperclipGoogledrive is a gem that extends paperclip storage for Google Drive (V3). Works with Rails 3.x. and later.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'paperclip-googledrive', github: 'degzcs/paperclip-googledrive'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install paperclip-googledrive
|
20
|
+
|
21
|
+
## Google Drive Setup
|
22
|
+
|
23
|
+
Google Drive is a free service for file storage files. In order to use this storage you need a Google (or Google Apps) user which will own the files, and a Google API client.
|
24
|
+
|
25
|
+
1. Go to the [Google Developers console](https://console.developers.google.com/project) and create a new project, this option is on the top, next to the Google APIs logo.
|
26
|
+
|
27
|
+
2. Go to "API Manager > Library" in the section "Google Apps APIs" and enable "Drive API". If you are getting an "Access Not Configured" error while uploading files, this is due to this API not being enabled.
|
28
|
+
|
29
|
+
3. Go to "API Manager > Credentials" and click on "OAuth Client ID" before to select "Other" type you must specify `http://localhost` for application home page.
|
30
|
+
|
31
|
+
4. Now you will have a Client ID, Client Secret, and Redirect URL. So, download the client_secret_XXXXX.json file and rename it to client_secrete.json.
|
32
|
+
|
33
|
+
5. Run the authorization task:
|
34
|
+
```sh
|
35
|
+
$ rake google_drive:authorize"[path/to/client_secret.json application_name]"
|
36
|
+
```
|
37
|
+
NOTE:
|
38
|
+
- the `path/to/client_secret.json` path is the file downloaded from Google console (it will be overrided with the fresh token).
|
39
|
+
- the application_name param is the name that you set for the application credentials on Google console.
|
40
|
+
|
41
|
+
6. The Rake task will give you an auth url. Simply go to that url (while signed in as the designated uploads owner), authorize the app, then enter code from url in the console. The rake task will override valid `client_secret.json` which you can use to connect with GoogleDrive from now on.
|
42
|
+
|
43
|
+
7. Create a folder in which the files will be uploaded; note the folder's ID.
|
44
|
+
|
45
|
+
## Configuration
|
46
|
+
|
47
|
+
Example:
|
48
|
+
```ruby
|
49
|
+
class Product < ActiveRecord::Base
|
50
|
+
has_attached_file :photo,
|
51
|
+
:storage => :google_drive,
|
52
|
+
:google_drive_client_secret_path => "#{Rails.root}/config/client_secret.json"
|
53
|
+
end
|
54
|
+
```
|
55
|
+
The `:google_drive_client_secret_path` option
|
56
|
+
|
57
|
+
Thise is obtained from your Google Drive app settings and the authorization Rake task.
|
58
|
+
|
59
|
+
Example `path/to/client_secret.json`:
|
60
|
+
```json
|
61
|
+
{
|
62
|
+
"client_id": "4444-1111.apps.googleusercontent.com",
|
63
|
+
"client_secret": "1yErh1pR_7asdf8tqdYM2LcuL",
|
64
|
+
"scope": "https://www.googleapis.com/auth/drive",
|
65
|
+
"refresh_token": "1/_sVZIgY5thPetbWDTTTasdDID5Rkvq6UEfYshaDs5dIKoUAKgjE9f"
|
66
|
+
}
|
67
|
+
```
|
68
|
+
It is good practice to not include the credentials directly in the JSON file. Instead you can set them in environment variables and embed them with ERB.
|
69
|
+
|
70
|
+
## Options
|
71
|
+
|
72
|
+
The `:google_drive_options` option
|
73
|
+
|
74
|
+
This is a hash containing any of the following options:
|
75
|
+
- `:path` – block, works similarly to Paperclip's `:path` option
|
76
|
+
- `:public_folder_id`- id of folder that must be created in google drive and set public permissions on it
|
77
|
+
- `:default_image` - an image in Public folder that used for attachments if attachment is not present
|
78
|
+
- `:application_name` - is the name that you set for the application credentials on Google console.
|
79
|
+
|
80
|
+
The :path option should be a block that returns a path that the uploaded file should be saved to. The block yields the attachment style and is executed in the scope of the model instance. For example:
|
81
|
+
```ruby
|
82
|
+
class Product < ActiveRecord::Base
|
83
|
+
has_attached_file :photo,
|
84
|
+
:storage => :google_drive,
|
85
|
+
:google_drive_client_secret_path => "#{Rails.root}/config/client_secret.json"
|
86
|
+
:styles => { :medium => "300x300" },
|
87
|
+
:google_drive_options => {
|
88
|
+
:path => proc { |style| "#{style}_#{id}_#{photo.original_filename}" }
|
89
|
+
}
|
90
|
+
end
|
91
|
+
```
|
92
|
+
For example, a new product is created with the ID of 14, and a some_photo.jpg as its photo. The following files would be saved to the Google Drive:
|
93
|
+
|
94
|
+
Public/14_some_photo.jpg
|
95
|
+
Public/14_some_photo_medium.jpg
|
96
|
+
|
97
|
+
The another file is called some_photo_medium.jpg because style names (other than original) will always be appended to the filenames, for better management.
|
98
|
+
|
99
|
+
## Misc
|
100
|
+
|
101
|
+
Useful links
|
102
|
+
[Google APIs console](https://code.google.com/apis/console/)
|
103
|
+
|
104
|
+
[Google Drive scopes](https://developers.google.com/drive/scopes)
|
105
|
+
|
106
|
+
[Enable the Drive API and SDK](https://developers.google.com/drive/enable-sdk)
|
107
|
+
|
108
|
+
[Quickstart](https://developers.google.com/drive/quickstart-ruby#step_1_enable_the_drive_api)
|
109
|
+
|
110
|
+
## License
|
111
|
+
|
112
|
+
[MIT License](https://github.com/evinsou/paperclip-googledrive/blob/master/LICENSE)
|
113
|
+
|
114
|
+
## Contributing
|
115
|
+
|
116
|
+
1. Fork it
|
117
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
118
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
119
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
120
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "alegra"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Author: Mateusz Czerwinski <mtczerwinski@gmail.com>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
require 'json'
|
4
|
+
require 'googleauth'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Paperclip
|
8
|
+
module GoogleDrive
|
9
|
+
# @api private
|
10
|
+
class Config
|
11
|
+
FIELDS = %w(client_id client_secret scope refresh_token).freeze
|
12
|
+
attr_accessor(*FIELDS)
|
13
|
+
|
14
|
+
def initialize(config_path)
|
15
|
+
@config_path = config_path
|
16
|
+
if ::File.exist?(config_path)
|
17
|
+
JSON.parse(::File.read(config_path)).each do |key, value|
|
18
|
+
instance_variable_set("@#{key}", value) if FIELDS.include?(key)
|
19
|
+
end
|
20
|
+
if !client_id
|
21
|
+
auth_client = Google::Auth::ClientId.from_file(config_path)
|
22
|
+
@client_id = auth_client.id
|
23
|
+
@client_secret = auth_client.secret
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
::File.open(@config_path, 'w', 0600) { |f| f.write(to_json) }
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def to_json
|
35
|
+
hash = {}
|
36
|
+
FIELDS.each do |field|
|
37
|
+
value = __send__(field)
|
38
|
+
hash[field] = value if value
|
39
|
+
end
|
40
|
+
JSON.pretty_generate(hash)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'google/apis/drive_v3'
|
2
|
+
require 'googleauth'
|
3
|
+
require 'paperclip/google_drive/session'
|
4
|
+
|
5
|
+
module Paperclip
|
6
|
+
module GoogleDrive
|
7
|
+
module Rake
|
8
|
+
extend self
|
9
|
+
##
|
10
|
+
# Ensure valid credentials, either by restoring from the saved credentials
|
11
|
+
# files or intitiating an OAuth2 authorization. If authorization is required,
|
12
|
+
# the user's default browser will be launched to approve the request.
|
13
|
+
#
|
14
|
+
# @param client_secret_path [ String ] with the location of the JSON file downloaded from Google console
|
15
|
+
# @param application_name [ String ] given in the Google console > credentials > OAuth 2.0 client IDs section
|
16
|
+
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials
|
17
|
+
def authorize(client_secret_path, application_name)
|
18
|
+
client = Paperclip::GoogleDrive::Session.from_config(client_secret_path, application_name: application_name)
|
19
|
+
# # List the 10 most recently modified files.
|
20
|
+
# response = client.list_files(page_size: 10, fields: 'nextPageToken, files(id, name)')
|
21
|
+
# puts 'Files:'
|
22
|
+
# puts 'No files found' if response.files.empty?
|
23
|
+
# response.files.each do |file|
|
24
|
+
# puts "#{file.name} (#{file.id})"
|
25
|
+
# end
|
26
|
+
if client
|
27
|
+
puts "\nAuthorization completed.\n\n"
|
28
|
+
puts "The credentials were saved into #{ client_secret_path}.\n"
|
29
|
+
puts "You can use these credentials as follows: \n"
|
30
|
+
puts "Paperclip::GoogleDrive::Session.from_config(#{client_secret_path}, application_name: #{application_name})"
|
31
|
+
puts "\n"
|
32
|
+
else
|
33
|
+
raise 'There where something wrong in the initialization of the google client (Google::Apis::DriveV3::DriveService)'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Author: Hiroshi Ichikawa <http://gimite.net/>
|
2
|
+
# The license of this source is "New BSD Licence"
|
3
|
+
require 'google/apis/drive_v3'
|
4
|
+
require 'googleauth'
|
5
|
+
require 'paperclip/google_drive/config'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
module Paperclip
|
9
|
+
module GoogleDrive
|
10
|
+
# A session for Google Drive operations.
|
11
|
+
#
|
12
|
+
# Use from_credentials, from_access_token, from_service_account_key or from_config
|
13
|
+
# class method to construct a Paperclip::GoogleDrive::Session object.
|
14
|
+
class Session
|
15
|
+
|
16
|
+
DEFAULT_SCOPE = Google::Apis::DriveV3::AUTH_DRIVE
|
17
|
+
|
18
|
+
# Returns Google::Apis::DriveV3::DriveService constructed from a config JSON file at +config+.
|
19
|
+
#
|
20
|
+
# +config+ is the path to the config file.
|
21
|
+
#
|
22
|
+
# This will prompt the credential via command line for the first time and save it to
|
23
|
+
# +config+ for later usages.
|
24
|
+
#
|
25
|
+
# See https://github.com/gimite/google-drive-ruby/blob/master/doc/authorization.md for a usage example.
|
26
|
+
#
|
27
|
+
# You can also provide a config object that must respond to:
|
28
|
+
# client_id
|
29
|
+
# client_secret
|
30
|
+
# refesh_token
|
31
|
+
# refresh_token=
|
32
|
+
# scope
|
33
|
+
# scope=
|
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)
|
40
|
+
end
|
41
|
+
|
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')
|
50
|
+
end
|
51
|
+
|
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')
|
57
|
+
|
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
|
67
|
+
end
|
68
|
+
|
69
|
+
config.save
|
70
|
+
|
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
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "paperclip/google_drive/rake"
|
2
|
+
|
3
|
+
namespace :google_drive do
|
4
|
+
desc "Authorize Google Drive account: "
|
5
|
+
task :authorize, [:client_secret_path, :application_name] do |t, args|
|
6
|
+
client_secret_path = args[:client_secret_path]
|
7
|
+
application_name = args[:application_name]
|
8
|
+
Paperclip::GoogleDrive::Rake.authorize(client_secret_path, application_name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
require 'active_support/inflector/methods'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'yaml'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
require 'google/apis/drive_v3'
|
8
|
+
require 'googleauth'
|
9
|
+
require 'paperclip/google_drive/session'
|
10
|
+
|
11
|
+
require 'fileutils'
|
12
|
+
|
13
|
+
module Paperclip
|
14
|
+
|
15
|
+
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
|
+
|
29
|
+
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
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
def flush_writes
|
48
|
+
@queued_for_write.each do |style, file|
|
49
|
+
raise FileExists, "file \"#{path(style)}\" already exists in your Google Drive" if exists?(path(style))
|
50
|
+
|
51
|
+
name, mime_type = name_for_file(style), "#{ file.content_type }"
|
52
|
+
|
53
|
+
file_metadata = {
|
54
|
+
name: name,
|
55
|
+
description: 'paperclip file on google drive',
|
56
|
+
mimeType: mime_type,
|
57
|
+
parents: [find_public_folder]
|
58
|
+
}
|
59
|
+
|
60
|
+
result = google_api_client.create_file(
|
61
|
+
file_metadata,
|
62
|
+
fields: '*',
|
63
|
+
upload_source: file.binmode,
|
64
|
+
content_type: file.content_type,
|
65
|
+
)
|
66
|
+
end
|
67
|
+
after_flush_writes
|
68
|
+
@queued_for_write = {}
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
def flush_deletes
|
73
|
+
@queued_for_delete.each do |path|
|
74
|
+
Paperclip.log("delete #{path}")
|
75
|
+
file_id = search_for_title(path)
|
76
|
+
result = google_api_client.delete_file(file_id) unless file_id.nil?
|
77
|
+
end
|
78
|
+
@queued_for_delete = []
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [ Google::Apis::DriveV3::DriveService ]
|
82
|
+
def google_api_client
|
83
|
+
@google_api_client ||= begin
|
84
|
+
# Initialize the client & Google+ API
|
85
|
+
::Paperclip::GoogleDrive::Session.from_config(
|
86
|
+
@google_drive_client_secret_path,
|
87
|
+
application_name: @google_drive_options[:application_name]
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
alias_method :google_drive, :google_api_client
|
93
|
+
|
94
|
+
def url(*args)
|
95
|
+
if present?
|
96
|
+
style = args.first.is_a?(Symbol) ? args.first : default_style
|
97
|
+
options = args.last.is_a?(Hash) ? args.last : {}
|
98
|
+
public_url_for(path(style))
|
99
|
+
else
|
100
|
+
default_image
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def path(style)
|
105
|
+
name_for_file(style)
|
106
|
+
end
|
107
|
+
|
108
|
+
def name_for_file(style)
|
109
|
+
file_name = instance.instance_exec(style, &file_title)
|
110
|
+
style_suffix = (style != default_style ? "_#{style}" : "")
|
111
|
+
if original_extension.present? && file_name =~ /#{original_extension}$/
|
112
|
+
file_name.sub(original_extension, "#{style_suffix}#{original_extension}")
|
113
|
+
else
|
114
|
+
file_name + style_suffix + original_extension.to_s
|
115
|
+
end
|
116
|
+
end # full title
|
117
|
+
|
118
|
+
# Gets the public url for a passed filename
|
119
|
+
# @param title [ String ]
|
120
|
+
# @return [ String ] with url
|
121
|
+
def public_url_for(title)
|
122
|
+
searched_id = search_for_title(title) #return id if any or style
|
123
|
+
if searched_id.nil? # it finds some file
|
124
|
+
default_image
|
125
|
+
else
|
126
|
+
metadata = metadata_by_id(searched_id)
|
127
|
+
metadata.web_content_link #or metadata.web_view_link?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Takes the file title/name and search it in a given folder
|
132
|
+
# If it finds a file, return id of a file or nil
|
133
|
+
# @param name [ String ]
|
134
|
+
# @return [ String ] or NilClass
|
135
|
+
def search_for_title(name)
|
136
|
+
raise 'You are trying to search a file with NO name' if name.nil? || name.empty?
|
137
|
+
client = google_api_client
|
138
|
+
result = client.list_files(
|
139
|
+
q: "name contains '#{ name }' and '#{ find_public_folder }' in parents",
|
140
|
+
fields: '*'
|
141
|
+
)
|
142
|
+
if result.files.length > 0 # TODO: change these coditionals
|
143
|
+
result.files[0].id # WTF: get the first file???
|
144
|
+
elsif result.files.length == 0
|
145
|
+
nil
|
146
|
+
else
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# @parent file_id [ String ]
|
152
|
+
# @return [ Google::Apis::DriveV3::File ]
|
153
|
+
def metadata_by_id(file_id)
|
154
|
+
if file_id.is_a? String
|
155
|
+
client = google_api_client
|
156
|
+
result = client.get_file(
|
157
|
+
file_id,
|
158
|
+
fields: '*'
|
159
|
+
)
|
160
|
+
result
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Checks if the image already exits
|
165
|
+
# @param style [ String ]
|
166
|
+
# @return [ Boolean ]
|
167
|
+
def exists?(style = default_style)
|
168
|
+
return false if not present?
|
169
|
+
result_id = search_for_title(path(style))
|
170
|
+
if result_id.nil?
|
171
|
+
false
|
172
|
+
else
|
173
|
+
data = metadata_by_id(result_id)
|
174
|
+
!data.trashed # if trashed -> not exists
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def default_image
|
179
|
+
if @google_drive_options[:default_url] #if default image is set
|
180
|
+
title = @google_drive_options[:default_url]
|
181
|
+
searched_id = search_for_title(title) # id
|
182
|
+
metadata = metadata_by_id(searched_id) unless searched_id.nil?
|
183
|
+
metadata.web_content_link
|
184
|
+
else
|
185
|
+
'No picture' # ---- ?
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def find_public_folder
|
190
|
+
raise KeyError, "You must set the public_folder_id option" unless @google_drive_options[:public_folder_id]
|
191
|
+
if @google_drive_options[:public_folder_id].is_a? Proc
|
192
|
+
instance.instance_exec(&@google_drive_options[:public_folder_id])
|
193
|
+
else
|
194
|
+
@google_drive_options[:public_folder_id]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
#
|
199
|
+
# Error classes
|
200
|
+
#
|
201
|
+
|
202
|
+
class FileExists < ArgumentError
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
def file_title
|
208
|
+
return @google_drive_options[:path] if @google_drive_options[:path] #path: proc
|
209
|
+
eval %(proc { |style| "\#{id}_\#{#{name}.original_filename}"})
|
210
|
+
end
|
211
|
+
|
212
|
+
# @return [String] with the extension of file
|
213
|
+
def original_extension
|
214
|
+
File.extname(original_filename)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "paperclip/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "paperclip-google-drive"
|
8
|
+
spec.version = PaperclipGoogleDrive::VERSION
|
9
|
+
spec.authors = ['Diego Gomez']
|
10
|
+
spec.email = ["diego.f.gomez.pardo@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Extends Paperclip with Google Drive storage}
|
13
|
+
spec.description = %q{paperclip-google-drive extends paperclip support of storage for google drive storage}
|
14
|
+
spec.homepage = "https://github.com/degzcs/paperclip-googledrive"
|
15
|
+
|
16
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.required_ruby_version = ">= 2.0.0"
|
23
|
+
spec.license = "MIT"
|
24
|
+
|
25
|
+
spec.add_dependency "paperclip", ">= 5.1.0"
|
26
|
+
spec.add_dependency 'google-api-client', "~> 0.9.20"
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
+
spec.add_development_dependency "vcr", "~> 3"
|
32
|
+
spec.add_development_dependency "webmock", "~> 2.1"
|
33
|
+
spec.add_development_dependency "jazz_fingers", "~> 4"
|
34
|
+
spec.add_development_dependency('activerecord', '>= 4.2.0')
|
35
|
+
spec.add_development_dependency('sqlite3')
|
36
|
+
spec.add_development_dependency('railties')
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: paperclip-google-drive
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Diego Gomez
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: paperclip
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-api-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.20
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.20
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.13'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.13'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: vcr
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: jazz_fingers
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activerecord
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 4.2.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 4.2.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: railties
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: paperclip-google-drive extends paperclip support of storage for google
|
168
|
+
drive storage
|
169
|
+
email:
|
170
|
+
- diego.f.gomez.pardo@gmail.com
|
171
|
+
executables:
|
172
|
+
- console
|
173
|
+
- setup
|
174
|
+
extensions: []
|
175
|
+
extra_rdoc_files: []
|
176
|
+
files:
|
177
|
+
- ".gitignore"
|
178
|
+
- ".ruby-version"
|
179
|
+
- Gemfile
|
180
|
+
- LICENSE
|
181
|
+
- README.md
|
182
|
+
- Rakefile
|
183
|
+
- bin/console
|
184
|
+
- bin/setup
|
185
|
+
- lib/paperclip-google-drive.rb
|
186
|
+
- lib/paperclip/google_drive.rb
|
187
|
+
- lib/paperclip/google_drive/config.rb
|
188
|
+
- lib/paperclip/google_drive/railtie.rb
|
189
|
+
- lib/paperclip/google_drive/rake.rb
|
190
|
+
- lib/paperclip/google_drive/session.rb
|
191
|
+
- lib/paperclip/google_drive/tasks.rake
|
192
|
+
- lib/paperclip/storage/google_drive.rb
|
193
|
+
- lib/paperclip/version.rb
|
194
|
+
- paperclip-google-drive.gemspec
|
195
|
+
homepage: https://github.com/degzcs/paperclip-googledrive
|
196
|
+
licenses:
|
197
|
+
- MIT
|
198
|
+
metadata: {}
|
199
|
+
post_install_message:
|
200
|
+
rdoc_options: []
|
201
|
+
require_paths:
|
202
|
+
- lib
|
203
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: 2.0.0
|
208
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
requirements: []
|
214
|
+
rubyforge_project:
|
215
|
+
rubygems_version: 2.5.1
|
216
|
+
signing_key:
|
217
|
+
specification_version: 4
|
218
|
+
summary: Extends Paperclip with Google Drive storage
|
219
|
+
test_files: []
|