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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3b6e4fdd59f38f10e195f07fefbf4bf1a536529
4
- data.tar.gz: bd0feb9fd0e999dad48eb87795ea11a334cd72b9
3
+ metadata.gz: 6e6caa28bd80c52ae0514e07d508a62c7b4b4ebf
4
+ data.tar.gz: 1ede4e3d45234bd9f492e63048193a3c57785836
5
5
  SHA512:
6
- metadata.gz: e6402cbecf78bd7a0d26aef9842beb4e8e2b2a60add73a27a7dad65902eac6279c5f92c84f33af7efa910aa7005f3bcd9907a90de259f079edc27c5ebd56f977
7
- data.tar.gz: c544df48fd31fbd38a7dcd7668d1d42b0bae5ee4fbc09142656e7c3b638de3d0b80e254e96e2b179eaef31842bde96a04d614b07b67ec20d048bca7ec57efab6
6
+ metadata.gz: 4e7a61540baef46bdd5c9b9b85ff3b4ab4e2fbc4ad31417543cb558bbab6a80c9ab7e1e530779f20f8cb5d9bc0e082b4e75506ec001e6b32783de9017bb9decc
7
+ data.tar.gz: bfa2356628d021c587b039d33f70cb8b031861fbf93a2e1e858932d325a36a9942cdaed3a8c471f43ff34d64d814335c72f34520fa792dfd551cb902064c0cbd
@@ -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 'roo'
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
- @client = Middleman::GoogleDrive.connect
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,5 +1,5 @@
1
1
  module Middleman
2
2
  module GoogleDrive
3
- VERSION = '0.1.1'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  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
- ::Middleman::Extensions.register(
87
- :google_drive, Middleman::GoogleDrive::Extension)
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.1.1
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-07-29 00:00:00.000000000 Z
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