middleman-google_drive 0.2.1 → 0.2.2

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: 5bf7956b153e220ffa3c09c0aaa15a06d72683df
4
- data.tar.gz: f7b3ccb5e1bd511e070037bef2def79c27935f68
3
+ metadata.gz: 2857e937b68c10de7780fa28220f3d70e6953f29
4
+ data.tar.gz: a4c19ba124ac231e4795d86047d6c8a5aafd7786
5
5
  SHA512:
6
- metadata.gz: 6cabc9eb4a1a5b3eb1b8486df8f5a9d98c4202223efcf74c4ed85e6f93c53bb0a34dad5b0b240a1c45ec2f0bcadf5f12d85c0296d934c8b7406a0ebeba8fda6b
7
- data.tar.gz: aa172b233c0582022b8ec4233a69e8f0f4bc3e7066b1033de6632db662a79ad26ec734c1da73962268d038fe894b1c880c3313039871f51f91af3087f91a117a
6
+ metadata.gz: 27ebca38276d76f625c781204b68fed14ed387a204d1c7a9543b58bb35d020548dde02cb6d04198e90bd37d5f2dc0292ae56b4fc92008d5098cc555d52d46509
7
+ data.tar.gz: 4822b82da85d3ddc9e20d963170c5802267f54e81749acb185d0d1eb31bf8ccb5965200a3410b381e8acb4bc3cdd43884fca6fbbd1b9a048f297f34d5ec109c0
data/Rakefile CHANGED
@@ -1,2 +1,12 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'bundler/setup'
3
+ require 'rake/testtask'
4
+ require 'rake/clean'
2
5
 
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/*_test.rb']
9
+ end
10
+
11
+ desc 'Run tests'
12
+ task default: :test
data/lib/google_drive.rb CHANGED
@@ -5,94 +5,65 @@ require 'google/api_client/auth/file_storage'
5
5
  require 'google/api_client/auth/installed_app'
6
6
 
7
7
  class GoogleDrive
8
+ attr_reader :client
8
9
  def initialize
9
- credentials = ENV['GOOGLE_DRIVE_OAUTH'] || File.expand_path(
10
+ @credentials = ENV['GOOGLE_DRIVE_OAUTH'] || File.expand_path(
10
11
  '~/.google_drive_oauth2.json')
11
- client_secrets = ENV['GOOGLE_CLIENT_SECRETS'] || File.expand_path(
12
+ @client_secrets = ENV['GOOGLE_CLIENT_SECRETS'] || File.expand_path(
12
13
  '~/.google_client_secrets.json')
13
14
 
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']
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']
18
19
 
19
20
  # try to read the file,
20
21
  # throw errors if not readable or not found
21
- if key_path
22
- key = Google::APIClient::KeyUtils.load_from_pkcs12(
23
- key_path, 'notasecret')
22
+ if @key_path
23
+ @key = Google::APIClient::KeyUtils.load_from_pkcs12(
24
+ @key_path, 'notasecret')
24
25
  elsif @private_key
25
- key = OpenSSL::PKey::RSA.new(
26
- private_key, 'notasecret')
26
+ @key = OpenSSL::PKey::RSA.new(
27
+ @private_key, 'notasecret')
27
28
  end
28
29
 
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
30
+ @_files = {}
31
+ @_spreadsheets = {}
32
+
33
+ do_auth
70
34
  end
71
35
 
72
- def get_sheet(key)
73
- require 'roo'
74
- # setup the hash that we will eventually return
75
- data = {}
36
+ def find(key)
37
+ return @_files[key] unless @_files[key].nil?
38
+
76
39
  drive = @client.discovered_api('drive', 'v2')
77
40
 
78
41
  # get the file metadata
79
- list_resp = @client.execute(
42
+ resp = @client.execute(
80
43
  api_method: drive.files.get,
81
44
  parameters: { fileId: key })
82
45
 
83
46
  # die if there's an error
84
- fail list_resp.error_message if list_resp.error?
47
+ fail GoogleDriveError, resp.error_message if resp.error?
48
+
49
+ @_files[key] = resp.data
50
+ end
51
+
52
+ def spreadsheet(key)
53
+ require 'roo'
54
+
55
+ list_resp = find(key)
85
56
 
86
57
  # Grab the export url. We're gonna request the spreadsheet
87
58
  # in excel format. Because it includes all the worksheets.
88
- uri = list_resp.data['exportLinks'][
59
+ uri = list_resp['exportLinks'][
89
60
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
90
61
 
91
62
  # get the export
92
63
  get_resp = @client.execute(uri: uri)
93
64
 
94
65
  # die if there's an error
95
- fail get_resp.error_message if get_resp.error?
66
+ fail GoogleDriveError, get_resp.error_message if get_resp.error?
96
67
 
97
68
  # get a temporary file. The export is binary, so open the tempfile in
98
69
  # write binary mode
@@ -101,10 +72,17 @@ class GoogleDrive
101
72
  fp.write get_resp.body
102
73
  fp.close
103
74
 
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)
75
+ # now open the file with Roo
76
+ ret = Roo::Spreadsheet.open(filename)
77
+
78
+ fp.unlink # delete our tempfile
79
+
80
+ ret
81
+ end
82
+
83
+ def prepared_spreadsheet(key)
84
+ xls = spreadsheet(key)
85
+ data = {}
108
86
  xls.each_with_pagename do |title, sheet|
109
87
  # if the sheet is called microcopy, copy or ends with copy, we assume
110
88
  # the first column contains keys and the second contains values.
@@ -126,15 +104,33 @@ class GoogleDrive
126
104
  end
127
105
  else
128
106
  # otherwise parse the sheet into a hash
129
- sheet.header_line = 2 # this is stupid. theres a bug in Roo.
107
+ sheet.header_line = 2 # a bug in Roo.
130
108
  data[title] = sheet.parse(headers: true)
131
109
  end
132
110
  end
133
- fp.unlink # delete our tempfile
134
111
  data
135
112
  end
136
113
 
137
- def copy_doc(file_id, title=nil)
114
+ def doc(key, format = 'html')
115
+ doc = find(key)
116
+
117
+ # Grab the export url.
118
+ if format.to_s == 'html'
119
+ uri = doc['exportLinks']['text/html']
120
+ else
121
+ uri = doc['exportLinks']['text/plain']
122
+ end
123
+
124
+ # get the export
125
+ resp = @client.execute(uri: uri)
126
+
127
+ # die if there's an error
128
+ fail GoogleDriveError, resp.error_message if resp.error?
129
+
130
+ resp.body
131
+ end
132
+
133
+ def copy(file_id, title = nil)
138
134
  drive = @client.discovered_api('drive', 'v2')
139
135
 
140
136
  if title.nil?
@@ -153,7 +149,74 @@ class GoogleDrive
153
149
  return { id: cp_resp.data['id'], url: cp_resp.data['alternateLink'] }
154
150
  end
155
151
  end
152
+ alias_method :copy_doc, :copy
153
+
154
+ def redo_auth
155
+ File.delete @credentials if @key.nil?
156
+ do_auth
157
+ end
158
+
159
+ def do_auth
160
+ if local?
161
+ @client = Google::APIClient.new(
162
+ application_name: 'Middleman',
163
+ application_version: Middleman::GoogleDrive::VERSION
164
+ )
165
+ begin
166
+ file_storage = Google::APIClient::FileStorage.new(@credentials)
167
+ rescue URI::InvalidURIError
168
+ File.delete @credentials
169
+ file_storage = Google::APIClient::FileStorage.new(@credentials)
170
+ end
171
+ if file_storage.authorization.nil?
172
+ unless File.exist? @client_secrets
173
+ fail ConfigurationError, 'You need to create a client_secrets.json file and save it to ~/.google_client_secrets.json.'
174
+ end
175
+ puts <<-MSG
176
+
177
+ Please login via your web browser. We opened the tab for you...
178
+
179
+ MSG
180
+ client_secrets = Google::APIClient::ClientSecrets.load(@client_secrets)
181
+ flow = Google::APIClient::InstalledAppFlow.new(
182
+ client_id: client_secrets.client_id,
183
+ client_secret: client_secrets.client_secret,
184
+ scope: ['https://www.googleapis.com/auth/drive']
185
+ )
186
+ @client.authorization = flow.authorize(file_storage)
187
+ else
188
+ @client.authorization = file_storage.authorization
189
+ end
190
+ else
191
+ @client = Google::APIClient.new(
192
+ application_name: 'Middleman',
193
+ application_version: Middleman::GoogleDrive::VERSION,
194
+ authorization: Signet::OAuth2::Client.new(
195
+ token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
196
+ audience: 'https://accounts.google.com/o/oauth2/token',
197
+ person: @person,
198
+ issuer: @issuer,
199
+ signing_key: @key,
200
+ scope: ['https://www.googleapis.com/auth/drive']
201
+ )
202
+ )
203
+ @client.authorization.fetch_access_token!
204
+ end
205
+ nil
206
+ end
207
+
208
+ # Returns true if we're using a private key to autheticate (like on a server).
209
+ def server?
210
+ ! @key.nil?
211
+ end
212
+
213
+ # Returns true if we're using local oauth2 (like on your computer).
214
+ def local?
215
+ @key.nil?
216
+ end
156
217
 
157
- class CreateError < Exception; end
158
- class ConfigurationError < Exception; end
218
+ class GoogleDriveError < StandardError; end
219
+ class DoesNotExist < GoogleDriveError; end
220
+ class CreateError < GoogleDriveError; end
221
+ class ConfigurationError < GoogleDriveError; end
159
222
  end
@@ -12,9 +12,43 @@ module Middleman
12
12
 
13
13
  drive = ::GoogleDrive.new
14
14
 
15
- app = klass.inst # where would you store the app instance?
15
+ app = klass.inst
16
+ app.set :drive, drive # so you can access the drive api directly
16
17
  options.load_sheets.each do |k, v|
17
- app.data.store(k, drive.get_sheet(v))
18
+ loop do
19
+ begin
20
+ app.data.store(k, drive.prepared_spreadsheet(v))
21
+ doc = drive.find(v)
22
+ puts <<-MSG
23
+ == Loaded data.#{k} from Google Doc "#{doc['title']}"
24
+ == #{doc['alternateLink']}
25
+ MSG
26
+ break
27
+ rescue ::GoogleDrive::GoogleDriveError => exc
28
+ if drive.server?
29
+ puts "== FAILED to load Google Doc \"#{exc.message}\""
30
+ break
31
+ end
32
+
33
+ puts <<-MSG
34
+
35
+ Could not load the Google Doc.
36
+
37
+ Things to check:
38
+ - Make sure the Google Doc key is correct
39
+ - Make sure you're logging in with the correct account
40
+ - Make sure you have access to the document
41
+
42
+ Google said "#{exc.message}." It might be a lie.
43
+
44
+ Would you like to try again? [Y/n]
45
+ MSG
46
+ resp = $stdin.read 1
47
+ break unless resp.strip.empty? || resp =~ /[Yy]/
48
+
49
+ drive.redo_auth
50
+ end
51
+ end
18
52
  end
19
53
  end
20
54
  end
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  module GoogleDrive
3
- VERSION = '0.2.1'
3
+ VERSION = '0.2.2'
4
4
  end
5
5
  end
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency 'google-api-client', '>= 0.7.1'
24
24
  spec.add_runtime_dependency 'roo', '~> 1.13.2'
25
25
  spec.add_development_dependency 'bundler', '~> 1.6'
26
- spec.add_development_dependency 'rake', '>= 10.3.2'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'minitest'
27
28
  end
@@ -0,0 +1,50 @@
1
+ require 'minitest/autorun'
2
+ require 'google_drive'
3
+
4
+ # Test the client lib!
5
+ class TestChorusApiClient < MiniTest::Test
6
+ def setup
7
+ @drive = ::GoogleDrive.new
8
+ end
9
+
10
+ def test_old_find
11
+ file = @drive.find '0AiOYF21HkoowdEZ4Ukkyc09nb2czQUxUYldidTB4Q1E'
12
+ assert_equal file['title'], 'Example Middleman Google Drive worksheet'
13
+ end
14
+
15
+ def test_old_prepared_spreadsheet
16
+ file = @drive.prepared_spreadsheet '0AiOYF21HkoowdEZ4Ukkyc09nb2czQUxUYldidTB4Q1E'
17
+ assert_has_key file, 'microcopy'
18
+ assert_has_key file['microcopy'], 'help'
19
+ end
20
+
21
+ def test_new_find
22
+ file = @drive.find '1vIICbbfHJ8lYSthiDWTNypZulrMResi9zPRjv4ePJJU'
23
+ assert_equal file['title'], 'Example Middleman Google Drive worksheet'
24
+ end
25
+
26
+ def test_new_prepared_spreadsheet
27
+ file = @drive.prepared_spreadsheet '1vIICbbfHJ8lYSthiDWTNypZulrMResi9zPRjv4ePJJU'
28
+ assert_has_key file, 'microcopy'
29
+ assert_has_key file['microcopy'], 'help'
30
+ end
31
+
32
+ def test_new_doc
33
+ file = @drive.doc '1lH-Nr_8UBOkvk8OdcdFoDez3OFIJxkawGVkwlMB-BjQ'
34
+ assert_not_nil file =~ /^<html>/
35
+
36
+ file = @drive.doc '1lH-Nr_8UBOkvk8OdcdFoDez3OFIJxkawGVkwlMB-BjQ', 'text'
37
+ assert_nil file =~ /^<html>/
38
+ end
39
+
40
+ def test_copy_file
41
+ end
42
+
43
+ def assert_has_key(hash, key, msg=nil)
44
+ assert hash.key?(key), msg || "The key '#{key}' is missing from #{hash}"
45
+ end
46
+
47
+ def assert_not_nil(thing, msg=nil)
48
+ assert !thing.nil?, msg
49
+ end
50
+ 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.2.1
4
+ version: 0.2.2
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-08-20 00:00:00.000000000 Z
12
+ date: 2014-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: middleman-core
@@ -73,14 +73,28 @@ dependencies:
73
73
  requirements:
74
74
  - - '>='
75
75
  - !ruby/object:Gem::Version
76
- version: 10.3.2
76
+ version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - '>='
82
82
  - !ruby/object:Gem::Version
83
- version: 10.3.2
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: minitest
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
84
98
  description:
85
99
  email:
86
100
  - ryan@mrk.cc
@@ -100,6 +114,7 @@ files:
100
114
  - lib/middleman-google_drive/version.rb
101
115
  - lib/middleman_extension.rb
102
116
  - middleman-google_drive.gemspec
117
+ - test/google_drive_test.rb
103
118
  homepage: https://github.com/voxmedia/middleman-google_drive
104
119
  licenses:
105
120
  - BSD
@@ -120,8 +135,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
135
  version: '0'
121
136
  requirements: []
122
137
  rubyforge_project:
123
- rubygems_version: 2.2.2
138
+ rubygems_version: 2.4.1
124
139
  signing_key:
125
140
  specification_version: 4
126
141
  summary: Pull content from a google spreadsheet to use in your middleman site.
127
- test_files: []
142
+ test_files:
143
+ - test/google_drive_test.rb