middleman-google_drive 0.1.1 → 0.2.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 +4 -4
- data/lib/google_drive.rb +159 -0
- data/lib/middleman-google_drive/extension.rb +4 -73
- data/lib/middleman-google_drive/version.rb +1 -1
- data/lib/middleman-google_drive.rb +4 -85
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e6caa28bd80c52ae0514e07d508a62c7b4b4ebf
|
4
|
+
data.tar.gz: 1ede4e3d45234bd9f492e63048193a3c57785836
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e7a61540baef46bdd5c9b9b85ff3b4ab4e2fbc4ad31417543cb558bbab6a80c9ab7e1e530779f20f8cb5d9bc0e082b4e75506ec001e6b32783de9017bb9decc
|
7
|
+
data.tar.gz: bfa2356628d021c587b039d33f70cb8b031861fbf93a2e1e858932d325a36a9942cdaed3a8c471f43ff34d64d814335c72f34520fa792dfd551cb902064c0cbd
|
data/lib/google_drive.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'middleman-google_drive/version'
|
2
|
+
require 'google/api_client'
|
3
|
+
require 'google/api_client/client_secrets'
|
4
|
+
require 'google/api_client/auth/file_storage'
|
5
|
+
require 'google/api_client/auth/installed_app'
|
6
|
+
|
7
|
+
class GoogleDrive
|
8
|
+
def initialize
|
9
|
+
credentials = ENV['GOOGLE_DRIVE_OAUTH'] || File.expand_path(
|
10
|
+
'~/.google_drive_oauth2.json')
|
11
|
+
client_secrets = ENV['GOOGLE_CLIENT_SECRETS'] || File.expand_path(
|
12
|
+
'~/.google_client_secrets.json')
|
13
|
+
|
14
|
+
person = ENV['GOOGLE_OAUTH_PERSON']
|
15
|
+
issuer = ENV['GOOGLE_OAUTH_ISSUER']
|
16
|
+
key_path = ENV['GOOGLE_OAUTH_KEYFILE']
|
17
|
+
private_key = ENV['GOOGLE_OAUTH_PRIVATE_KEY']
|
18
|
+
|
19
|
+
# try to read the file,
|
20
|
+
# throw errors if not readable or not found
|
21
|
+
if key_path
|
22
|
+
key = Google::APIClient::KeyUtils.load_from_pkcs12(
|
23
|
+
key_path, 'notasecret')
|
24
|
+
elsif @private_key
|
25
|
+
key = OpenSSL::PKey::RSA.new(
|
26
|
+
private_key, 'notasecret')
|
27
|
+
end
|
28
|
+
|
29
|
+
if key
|
30
|
+
@client = Google::APIClient.new(
|
31
|
+
application_name: 'Middleman',
|
32
|
+
application_version: Middleman::GoogleDrive::VERSION,
|
33
|
+
authorization: Signet::OAuth2::Client.new(
|
34
|
+
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
|
35
|
+
audience: 'https://accounts.google.com/o/oauth2/token',
|
36
|
+
person: person,
|
37
|
+
issuer: issuer,
|
38
|
+
signing_key: key,
|
39
|
+
scope: ['https://www.googleapis.com/auth/drive']
|
40
|
+
)
|
41
|
+
)
|
42
|
+
@client.authorization.fetch_access_token!
|
43
|
+
else
|
44
|
+
@client = Google::APIClient.new(
|
45
|
+
application_name: 'Middleman',
|
46
|
+
application_version: Middleman::GoogleDrive::VERSION
|
47
|
+
)
|
48
|
+
begin
|
49
|
+
file_storage = Google::APIClient::FileStorage.new(credentials)
|
50
|
+
rescue URI::InvalidURIError
|
51
|
+
File.delete credentials
|
52
|
+
file_storage = Google::APIClient::FileStorage.new(credentials)
|
53
|
+
end
|
54
|
+
if file_storage.authorization.nil?
|
55
|
+
unless File.exist? client_secrets
|
56
|
+
fail ConfigurationError, 'You need to create a client_secrets.json file and save it to ~/.google_client_secrets.json.'
|
57
|
+
end
|
58
|
+
puts 'Please login via your web browser'
|
59
|
+
client_secrets = Google::APIClient::ClientSecrets.load(client_secrets)
|
60
|
+
flow = Google::APIClient::InstalledAppFlow.new(
|
61
|
+
client_id: client_secrets.client_id,
|
62
|
+
client_secret: client_secrets.client_secret,
|
63
|
+
scope: ['https://www.googleapis.com/auth/drive']
|
64
|
+
)
|
65
|
+
@client.authorization = flow.authorize(file_storage)
|
66
|
+
else
|
67
|
+
@client.authorization = file_storage.authorization
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_sheet(key)
|
73
|
+
require 'roo'
|
74
|
+
# setup the hash that we will eventually return
|
75
|
+
data = {}
|
76
|
+
drive = @client.discovered_api('drive', 'v2')
|
77
|
+
|
78
|
+
# get the file metadata
|
79
|
+
list_resp = @client.execute(
|
80
|
+
api_method: drive.files.get,
|
81
|
+
parameters: { fileId: key })
|
82
|
+
|
83
|
+
# die if there's an error
|
84
|
+
fail list_resp.error_message if list_resp.error?
|
85
|
+
|
86
|
+
# Grab the export url. We're gonna request the spreadsheet
|
87
|
+
# in excel format. Because it includes all the worksheets.
|
88
|
+
uri = list_resp.data['exportLinks'][
|
89
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
|
90
|
+
|
91
|
+
# get the export
|
92
|
+
get_resp = @client.execute(uri: uri)
|
93
|
+
|
94
|
+
# die if there's an error
|
95
|
+
fail get_resp.error_message if get_resp.error?
|
96
|
+
|
97
|
+
# get a temporary file. The export is binary, so open the tempfile in
|
98
|
+
# write binary mode
|
99
|
+
fp = Tempfile.new(['gdoc', '.xlsx'], binmode: true)
|
100
|
+
filename = fp.path
|
101
|
+
fp.write get_resp.body
|
102
|
+
fp.close
|
103
|
+
|
104
|
+
# now open the file with Roo. (Roo can't handle an IO
|
105
|
+
# object, it will only take filenames or urls, coulda done this all
|
106
|
+
# in memory, but alas...)
|
107
|
+
xls = Roo::Spreadsheet.open(filename)
|
108
|
+
xls.each_with_pagename do |title, sheet|
|
109
|
+
# if the sheet is called microcopy, copy or ends with copy, we assume
|
110
|
+
# the first column contains keys and the second contains values.
|
111
|
+
# Like tarbell.
|
112
|
+
if %w(microcopy copy).include?(title.downcase) ||
|
113
|
+
title.downcase =~ /[ -_]copy$/
|
114
|
+
data[title] = {}
|
115
|
+
sheet.each do |row|
|
116
|
+
# if the key name is reused, create an array with all the entries
|
117
|
+
if data[title].keys.include? row[0]
|
118
|
+
if data[title][row[0]].is_a? Array
|
119
|
+
data[title][row[0]] << row[1]
|
120
|
+
else
|
121
|
+
data[title][row[0]] = [data[title][row[0]], row[1]]
|
122
|
+
end
|
123
|
+
else
|
124
|
+
data[title][row[0]] = row[1]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
else
|
128
|
+
# otherwise parse the sheet into a hash
|
129
|
+
sheet.header_line = 2 # this is stupid. theres a bug in Roo.
|
130
|
+
data[title] = sheet.parse(headers: true)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
fp.unlink # delete our tempfile
|
134
|
+
data
|
135
|
+
end
|
136
|
+
|
137
|
+
def copy_doc(file_id, title=nil)
|
138
|
+
drive = client.discovered_api('drive', 'v2')
|
139
|
+
|
140
|
+
if title.nil?
|
141
|
+
copied_file = drive.files.copy.request_schema.new
|
142
|
+
else
|
143
|
+
copied_file = drive.files.copy.request_schema.new('title' => title)
|
144
|
+
end
|
145
|
+
cp_resp = client.execute(
|
146
|
+
api_method: drive.files.copy,
|
147
|
+
body_object: copied_file,
|
148
|
+
parameters: { fileId: file_id, visibility: 'PRIVATE' })
|
149
|
+
|
150
|
+
if cp_resp.error?
|
151
|
+
fail CreateError, cp_resp.error_message
|
152
|
+
else
|
153
|
+
return { id: cp_resp.data['id'], url: cp_resp.data['alternateLink'] }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class CreateError < Exception; end
|
158
|
+
class ConfigurationError < Exception; end
|
159
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'middleman-core'
|
2
|
+
require 'google_drive'
|
2
3
|
|
3
4
|
module Middleman
|
4
5
|
module GoogleDrive
|
@@ -9,83 +10,13 @@ module Middleman
|
|
9
10
|
def initialize(klass, options_hash = {}, &block)
|
10
11
|
super
|
11
12
|
|
12
|
-
|
13
|
-
@drive = @client.discovered_api('drive', 'v2')
|
13
|
+
drive = ::GoogleDrive.new
|
14
14
|
|
15
15
|
app = klass.inst # where would you store the app instance?
|
16
16
|
options.load_sheets.each do |k, v|
|
17
|
-
app.data.store(k, get_sheet(v))
|
17
|
+
app.data.store(k, drive.get_sheet(v))
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
|
-
def get_sheet(key)
|
22
|
-
# setup the hash that we will eventually return
|
23
|
-
data = {}
|
24
|
-
|
25
|
-
# get the file metadata
|
26
|
-
list_resp = @client.execute(
|
27
|
-
api_method: @drive.files.get,
|
28
|
-
parameters: { fileId: key })
|
29
|
-
|
30
|
-
# die if there's an error
|
31
|
-
fail list_resp.error_message if list_resp.error?
|
32
|
-
|
33
|
-
# Grab the export url. We're gonna request the spreadsheet
|
34
|
-
# in excel format. Because it includes all the worksheets.
|
35
|
-
uri = list_resp.data['exportLinks'][
|
36
|
-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
|
37
|
-
|
38
|
-
# get the export
|
39
|
-
get_resp = @client.execute(uri: uri)
|
40
|
-
|
41
|
-
# die if there's an error
|
42
|
-
fail get_resp.error_message if get_resp.error?
|
43
|
-
|
44
|
-
# get a temporary file. we can't just write to it because ruby's
|
45
|
-
# tempfile tries to be clever and open the file for you, except we
|
46
|
-
# need to open the file in binary mode, so thanks ruby.
|
47
|
-
fp = Tempfile.new(['gdoc', '.xlsx'])
|
48
|
-
filename = fp.path
|
49
|
-
fp.close
|
50
|
-
|
51
|
-
# since the export is binary, reopen the tempfile in write binary mode
|
52
|
-
open(filename, 'wb') do |f|
|
53
|
-
# write the digits
|
54
|
-
f.write get_resp.body
|
55
|
-
end
|
56
|
-
|
57
|
-
# now open the file a third time with Roo. (Roo can't handle an IO
|
58
|
-
# object, it will only take filenames or urls, coulda done this all
|
59
|
-
# in memory, but alas...)
|
60
|
-
xls = Roo::Spreadsheet.open(filename)
|
61
|
-
xls.each_with_pagename do |title, sheet|
|
62
|
-
# if the sheet is called microcopy, copy or ends with copy, we assume
|
63
|
-
# the first column contains keys and the second contains values.
|
64
|
-
# Like tarbell.
|
65
|
-
if %w(microcopy copy).include?(title.downcase) ||
|
66
|
-
title.downcase =~ /[ -_]copy$/
|
67
|
-
data[title] = {}
|
68
|
-
sheet.each do |row|
|
69
|
-
# if the key name is reused, create an array with all the entries
|
70
|
-
if data[title].keys.include? row[0]
|
71
|
-
if data[title][row[0]].is_a? Array
|
72
|
-
data[title][row[0]] << row[1]
|
73
|
-
else
|
74
|
-
data[title][row[0]] = [data[title][row[0]], row[1]]
|
75
|
-
end
|
76
|
-
else
|
77
|
-
data[title][row[0]] = row[1]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
else
|
81
|
-
# otherwise parse the sheet into a hash
|
82
|
-
sheet.header_line = 2 # this is stupid. theres a bug in Roo.
|
83
|
-
data[title] = sheet.parse(headers: true)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
fp.unlink # delete our tempfile
|
87
|
-
data
|
88
|
-
end
|
89
20
|
end
|
90
21
|
end
|
91
22
|
end
|
@@ -1,87 +1,6 @@
|
|
1
|
-
require 'middleman-google_drive/version'
|
2
|
-
require 'google/api_client'
|
3
|
-
require 'google/api_client/client_secrets'
|
4
|
-
require 'google/api_client/auth/file_storage'
|
5
|
-
require 'google/api_client/auth/installed_app'
|
6
|
-
|
7
|
-
module Middleman
|
8
|
-
module GoogleDrive
|
9
|
-
def self.connect
|
10
|
-
credentials = ENV['GOOGLE_DRIVE_OAUTH'] || File.expand_path(
|
11
|
-
'~/.google_drive_oauth2.json')
|
12
|
-
client_secrets = ENV['GOOGLE_CLIENT_SECRETS'] || File.expand_path(
|
13
|
-
'~/.google_client_secrets.json')
|
14
|
-
|
15
|
-
person = ENV['GOOGLE_OAUTH_PERSON']
|
16
|
-
issuer = ENV['GOOGLE_OAUTH_ISSUER']
|
17
|
-
key_path = ENV['GOOGLE_OAUTH_KEYFILE']
|
18
|
-
private_key = ENV['GOOGLE_OAUTH_PRIVATE_KEY']
|
19
|
-
|
20
|
-
# try to read the file,
|
21
|
-
# throw errors if not readable or not found
|
22
|
-
if key_path
|
23
|
-
key = Google::APIClient::KeyUtils.load_from_pkcs12(
|
24
|
-
key_path, 'notasecret')
|
25
|
-
elsif @private_key
|
26
|
-
key = OpenSSL::PKey::RSA.new(
|
27
|
-
private_key, 'notasecret')
|
28
|
-
end
|
29
|
-
|
30
|
-
if key
|
31
|
-
puts 'authenticating with key'
|
32
|
-
client = Google::APIClient.new(
|
33
|
-
application_name: 'Middleman',
|
34
|
-
application_version: Middleman::GoogleDrive::VERSION,
|
35
|
-
authorization: Signet::OAuth2::Client.new(
|
36
|
-
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
|
37
|
-
audience: 'https://accounts.google.com/o/oauth2/token',
|
38
|
-
person: person,
|
39
|
-
issuer: issuer,
|
40
|
-
signing_key: key,
|
41
|
-
scope: [
|
42
|
-
'https://www.googleapis.com/auth/drive'
|
43
|
-
]
|
44
|
-
)
|
45
|
-
)
|
46
|
-
client.authorization.fetch_access_token!
|
47
|
-
else
|
48
|
-
client = Google::APIClient.new(
|
49
|
-
application_name: 'Middleman',
|
50
|
-
application_version: Middleman::GoogleDrive::VERSION
|
51
|
-
)
|
52
|
-
begin
|
53
|
-
file_storage = Google::APIClient::FileStorage.new(credentials)
|
54
|
-
rescue URI::InvalidURIError
|
55
|
-
File.delete credentials
|
56
|
-
file_storage = Google::APIClient::FileStorage.new(credentials)
|
57
|
-
end
|
58
|
-
if file_storage.authorization.nil?
|
59
|
-
unless File.exist? client_secrets
|
60
|
-
puts 'You need to create a client_secrets.json file and save it to `~/.google_client_secrets.json`. Find instructions here: http://tarbell.readthedocs.org/en/latest/install.html#configure-google-spreadsheet-access-optional'
|
61
|
-
exit
|
62
|
-
end
|
63
|
-
puts 'Please login via your web browser'
|
64
|
-
client_secrets = Google::APIClient::ClientSecrets.load(
|
65
|
-
client_secrets)
|
66
|
-
flow = Google::APIClient::InstalledAppFlow.new(
|
67
|
-
client_id: client_secrets.client_id,
|
68
|
-
client_secret: client_secrets.client_secret,
|
69
|
-
scope: [
|
70
|
-
'https://www.googleapis.com/auth/drive'
|
71
|
-
]
|
72
|
-
)
|
73
|
-
client.authorization = flow.authorize(file_storage)
|
74
|
-
else
|
75
|
-
client.authorization = file_storage.authorization
|
76
|
-
end
|
77
|
-
end
|
78
|
-
client
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
1
|
require 'middleman-core'
|
84
|
-
require 'middleman-google_drive/extension'
|
85
2
|
|
86
|
-
|
87
|
-
|
3
|
+
Middleman::Extensions.register :google_drive do
|
4
|
+
require 'middleman-google_drive/extension'
|
5
|
+
Middleman::GoogleDrive::Extension
|
6
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-google_drive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Mark
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: middleman-core
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- LICENSE.txt
|
95
95
|
- README.md
|
96
96
|
- Rakefile
|
97
|
+
- lib/google_drive.rb
|
97
98
|
- lib/middleman-google_drive.rb
|
98
99
|
- lib/middleman-google_drive/extension.rb
|
99
100
|
- lib/middleman-google_drive/version.rb
|