middleman-google_drive 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/google_drive.rb +129 -68
- data/lib/middleman-google_drive/extension.rb +62 -34
- data/lib/middleman-google_drive/version.rb +1 -1
- data/middleman-google_drive.gemspec +4 -2
- data/test/google_drive_test.rb +39 -21
- metadata +38 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f94ae0f5e1dc5cacb9af02dd286d77381b91081d
|
4
|
+
data.tar.gz: 5ee09f46e1fe604ff51319ec939be08a39b4015a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf2289726d7874bbb5be981f93a9be956b2d653e9d1715432746ae1de28c384a0647405f4f7267900a65fcc094e38367e57676c28798bc17a177560e9d83fe8c
|
7
|
+
data.tar.gz: f51bd5d03f94478a74e7ff7dbfb0999f027ca63d66c89f1218cf92fc11ce838a8351978e4333a6ead3f98f6e4c36d9624c0c399a3ccc3f77f95439f8f53d51e2
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Middleman::GoogleDrive
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/middleman-google_drive.svg)](http://badge.fury.io/rb/middleman-google_drive)
|
4
|
+
|
3
5
|
This is an extension for Middleman that allows you to load data from a google
|
4
6
|
spreadsheet into your template data.
|
5
7
|
|
data/lib/google_drive.rb
CHANGED
@@ -1,12 +1,25 @@
|
|
1
1
|
require 'middleman-google_drive/version'
|
2
|
+
require 'mime/types'
|
2
3
|
require 'google/api_client'
|
3
4
|
require 'google/api_client/client_secrets'
|
4
5
|
require 'google/api_client/auth/file_storage'
|
5
6
|
require 'google/api_client/auth/installed_app'
|
6
7
|
require 'rubyXL'
|
7
8
|
|
9
|
+
# Convience wrapper for Google Drive
|
10
|
+
#
|
11
|
+
# You can override the location of the client secrets and oauth2 JSON files with
|
12
|
+
# the environment variables `GOOGLE_CLIENT_SECRETS` and `GOOGLE_DRIVE_OAUTH`.
|
13
|
+
#
|
14
|
+
# If you plan to run Middleman on a server, you can use Google's server to server
|
15
|
+
# authentication. This will kick in if you define the environment variables
|
16
|
+
# `GOOGLE_OAUTH_PERSON`, `GOOGLE_OAUTH_ISSUER` and either `GOOGLE_OAUTH_KEYFILE`
|
17
|
+
# or `GOOGLE_OAUTH_PRIVATE_KEY`.
|
8
18
|
class GoogleDrive
|
19
|
+
# Google API Client object
|
9
20
|
attr_reader :client
|
21
|
+
|
22
|
+
# Constructor. Loads all params from envionment variables.
|
10
23
|
def initialize
|
11
24
|
@credentials = ENV['GOOGLE_DRIVE_OAUTH'] || File.expand_path(
|
12
25
|
'~/.google_drive_oauth2.json')
|
@@ -34,29 +47,49 @@ class GoogleDrive
|
|
34
47
|
do_auth
|
35
48
|
end
|
36
49
|
|
37
|
-
|
38
|
-
|
50
|
+
## Friendly Google Drive access
|
51
|
+
|
52
|
+
# Find a Google Drive file
|
53
|
+
# Takes the key of a Google Drive file and returns a hash of meta data. The returned hash is
|
54
|
+
# formatted as a
|
55
|
+
# {Google Drive resource}[https://developers.google.com/drive/v2/reference/files#resource].
|
56
|
+
#
|
57
|
+
# @param file_id [String] file id
|
58
|
+
# @return [Hash] file meta data
|
59
|
+
def find(file_id)
|
60
|
+
return @_files[file_id] unless @_files[file_id].nil?
|
39
61
|
|
40
62
|
drive = @client.discovered_api('drive', 'v2')
|
41
63
|
|
42
64
|
# get the file metadata
|
43
65
|
resp = @client.execute(
|
44
66
|
api_method: drive.files.get,
|
45
|
-
parameters: { fileId:
|
67
|
+
parameters: { fileId: file_id })
|
46
68
|
|
47
69
|
# die if there's an error
|
48
70
|
fail GoogleDriveError, resp.error_message if resp.error?
|
49
71
|
|
50
|
-
@_files[
|
72
|
+
@_files[file_id] = resp.data
|
51
73
|
end
|
52
74
|
|
53
|
-
|
54
|
-
|
75
|
+
# Export a file
|
76
|
+
# Returns the file contents
|
77
|
+
#
|
78
|
+
# @param file_id [String] file id
|
79
|
+
# @param type [:excel, :text, :html] export type
|
80
|
+
# @return [String] file contents
|
81
|
+
def export(file_id, type)
|
82
|
+
list_resp = find(file_id)
|
83
|
+
|
84
|
+
# decide which mimetype we want
|
85
|
+
mime = mime_for(type).content_type
|
55
86
|
|
56
|
-
# Grab the export url.
|
57
|
-
|
58
|
-
|
59
|
-
|
87
|
+
# Grab the export url.
|
88
|
+
if list_resp['exportLinks'] && list_resp['exportLinks'][mime]
|
89
|
+
uri = list_resp['exportLinks'][mime]
|
90
|
+
else
|
91
|
+
raise "Google doesn't support exporting file id #{file_id} to #{type}"
|
92
|
+
end
|
60
93
|
|
61
94
|
# get the export
|
62
95
|
get_resp = @client.execute(uri: uri)
|
@@ -64,23 +97,79 @@ class GoogleDrive
|
|
64
97
|
# die if there's an error
|
65
98
|
fail GoogleDriveError, get_resp.error_message if get_resp.error?
|
66
99
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
filename = fp.path
|
71
|
-
fp.write get_resp.body
|
72
|
-
fp.close
|
100
|
+
# contents
|
101
|
+
get_resp.body
|
102
|
+
end
|
73
103
|
|
74
|
-
|
75
|
-
|
104
|
+
# Export a file and save to disk
|
105
|
+
# Returns the local path to the file
|
106
|
+
#
|
107
|
+
# @param file_id [String] file id
|
108
|
+
# @param type [:excel, :text, :html] export type
|
109
|
+
# @param filename [String] where to save the spreadsheet
|
110
|
+
# @return [String] path to the excel file
|
111
|
+
def export_to_file(file_id, type, filename = nil)
|
112
|
+
contents = export(file_id, type)
|
113
|
+
|
114
|
+
if filename.nil?
|
115
|
+
# get a temporary file. The export is binary, so open the tempfile in
|
116
|
+
# write binary mode
|
117
|
+
Tempfile.create(
|
118
|
+
['googledoc', ".#{type}"],
|
119
|
+
binmode: mime_for(type.to_s).binary?) do |fp|
|
120
|
+
filename = fp.path
|
121
|
+
fp.write contents
|
122
|
+
end
|
123
|
+
else
|
124
|
+
open(filename, 'wb') { |fp| fp.write contents }
|
125
|
+
end
|
126
|
+
filename
|
127
|
+
end
|
76
128
|
|
77
|
-
|
129
|
+
# Make a copy of a Google Drive file
|
130
|
+
#
|
131
|
+
# @param file_id [String] file id
|
132
|
+
# @param title [String] title for the newly created file
|
133
|
+
# @return [Hash] hash containing the id/key and url of the new file
|
134
|
+
def copy(file_id, title = nil, visibility = :private)
|
135
|
+
drive = @client.discovered_api('drive', 'v2')
|
78
136
|
|
79
|
-
|
137
|
+
if title.nil?
|
138
|
+
copied_file = drive.files.copy.request_schema.new
|
139
|
+
else
|
140
|
+
copied_file = drive.files.copy.request_schema.new('title' => title)
|
141
|
+
end
|
142
|
+
cp_resp = @client.execute(
|
143
|
+
api_method: drive.files.copy,
|
144
|
+
body_object: copied_file,
|
145
|
+
parameters: { fileId: file_id, visibility: visibility.to_s.upcase })
|
146
|
+
|
147
|
+
if cp_resp.error?
|
148
|
+
fail CreateError, cp_resp.error_message
|
149
|
+
else
|
150
|
+
return { id: cp_resp.data['id'], url: cp_resp.data['alternateLink'] }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
alias_method :copy_doc, :copy
|
154
|
+
|
155
|
+
# Get the mime type from a file extension
|
156
|
+
#
|
157
|
+
# @param extension [String] file ext
|
158
|
+
# @return [String, nil] mime type for the file
|
159
|
+
def mime_for(extension)
|
160
|
+
MIME::Types.of(extension.to_s).first
|
80
161
|
end
|
81
162
|
|
82
|
-
|
83
|
-
|
163
|
+
## Spreadsheet utilities
|
164
|
+
|
165
|
+
# Parse a spreadsheet
|
166
|
+
# Reduces the spreadsheet to a no-frills hash, suitable for serializing and passing around.
|
167
|
+
#
|
168
|
+
# @param filename [String] path to xls file
|
169
|
+
# @return [Hash] spreadsheet contents
|
170
|
+
def prepare_spreadsheet(filename)
|
171
|
+
# open the file with RubyXL
|
172
|
+
xls = RubyXL::Parser.parse(filename)
|
84
173
|
data = {}
|
85
174
|
xls.worksheets.each do |sheet|
|
86
175
|
title = sheet.sheet_name
|
@@ -95,13 +184,16 @@ class GoogleDrive
|
|
95
184
|
data[title] = load_table(sheet.extract_data)
|
96
185
|
end
|
97
186
|
end
|
98
|
-
data
|
187
|
+
return data
|
99
188
|
end
|
100
189
|
|
101
190
|
# Take a two-dimensional array from a spreadsheet and create a hash. The first
|
102
191
|
# column is used as the key, and the second column is the value. If the key
|
103
192
|
# occurs more than once, the value becomes an array to hold all the values
|
104
193
|
# associated with the key.
|
194
|
+
#
|
195
|
+
# @param table [Array<Array>] 2d array of cell values
|
196
|
+
# @return [Hash] spreadsheet contents
|
105
197
|
def load_microcopy(table)
|
106
198
|
data = {}
|
107
199
|
table.each_with_index do |row, i|
|
@@ -123,6 +215,9 @@ class GoogleDrive
|
|
123
215
|
end
|
124
216
|
|
125
217
|
# Take a two-dimensional array from a spreadsheet and create an array of hashes.
|
218
|
+
#
|
219
|
+
# @param table [Array<Array>] 2d array of cell values
|
220
|
+
# @return [Array<Hash>] spreadsheet contents
|
126
221
|
def load_table(table)
|
127
222
|
return [] if table.length < 2
|
128
223
|
header = table.shift # Get the header row
|
@@ -132,50 +227,26 @@ class GoogleDrive
|
|
132
227
|
end
|
133
228
|
end
|
134
229
|
|
135
|
-
|
136
|
-
doc = find(key)
|
137
|
-
|
138
|
-
# Grab the export url.
|
139
|
-
if format.to_s == 'html'
|
140
|
-
uri = doc['exportLinks']['text/html']
|
141
|
-
else
|
142
|
-
uri = doc['exportLinks']['text/plain']
|
143
|
-
end
|
144
|
-
|
145
|
-
# get the export
|
146
|
-
resp = @client.execute(uri: uri)
|
230
|
+
## Authentication
|
147
231
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
232
|
+
# Returns true if we're using a private key to autheticate (like on a server).
|
233
|
+
# @return [Boolean]
|
234
|
+
def server?
|
235
|
+
!local?
|
152
236
|
end
|
153
237
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
copied_file = drive.files.copy.request_schema.new
|
159
|
-
else
|
160
|
-
copied_file = drive.files.copy.request_schema.new('title' => title)
|
161
|
-
end
|
162
|
-
cp_resp = @client.execute(
|
163
|
-
api_method: drive.files.copy,
|
164
|
-
body_object: copied_file,
|
165
|
-
parameters: { fileId: file_id, visibility: 'PRIVATE' })
|
166
|
-
|
167
|
-
if cp_resp.error?
|
168
|
-
fail CreateError, cp_resp.error_message
|
169
|
-
else
|
170
|
-
return { id: cp_resp.data['id'], url: cp_resp.data['alternateLink'] }
|
171
|
-
end
|
238
|
+
# Returns true if we're using local oauth2 (like on your computer).
|
239
|
+
# @return [Boolean]
|
240
|
+
def local?
|
241
|
+
@key.nil?
|
172
242
|
end
|
173
|
-
alias_method :copy_doc, :copy
|
174
243
|
|
244
|
+
# Delete cached credentials
|
175
245
|
def clear_auth
|
176
246
|
File.delete @credentials if @key.nil?
|
177
247
|
end
|
178
248
|
|
249
|
+
# Authenticate with Google and create the @client object
|
179
250
|
def do_auth
|
180
251
|
if local?
|
181
252
|
@client = Google::APIClient.new(
|
@@ -225,16 +296,6 @@ Please login via your web browser. We opened the tab for you...
|
|
225
296
|
nil
|
226
297
|
end
|
227
298
|
|
228
|
-
# Returns true if we're using a private key to autheticate (like on a server).
|
229
|
-
def server?
|
230
|
-
!local?
|
231
|
-
end
|
232
|
-
|
233
|
-
# Returns true if we're using local oauth2 (like on your computer).
|
234
|
-
def local?
|
235
|
-
@key.nil?
|
236
|
-
end
|
237
|
-
|
238
299
|
class GoogleDriveError < StandardError; end
|
239
300
|
class DoesNotExist < GoogleDriveError; end
|
240
301
|
class CreateError < GoogleDriveError; end
|
@@ -18,10 +18,10 @@ module Middleman
|
|
18
18
|
|
19
19
|
@app = klass.inst
|
20
20
|
|
21
|
-
handle_option(options.load_sheets,
|
22
|
-
handle_option(options.load_docs,
|
23
|
-
handle_option(options.load_docs_html,
|
24
|
-
handle_option(options.load_docs_archieml,
|
21
|
+
handle_option(options.load_sheets, :xlsx)
|
22
|
+
handle_option(options.load_docs, :txt)
|
23
|
+
handle_option(options.load_docs_html, :html)
|
24
|
+
handle_option(options.load_docs_archieml, :archieml)
|
25
25
|
end
|
26
26
|
|
27
27
|
def handle_option(option, type)
|
@@ -29,25 +29,54 @@ module Middleman
|
|
29
29
|
option.each do |name, key|
|
30
30
|
store_data(name, load_doc(key.to_s, type))
|
31
31
|
end
|
32
|
-
elsif type ==
|
32
|
+
elsif type == :xlsx
|
33
33
|
load_doc(option.to_s, type).each do |name, sheet|
|
34
34
|
store_data(name, sheet)
|
35
35
|
end
|
36
36
|
else
|
37
37
|
store_data('doc', load_doc(option.to_s, type))
|
38
38
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_doc(key, type)
|
42
|
+
doc = @drive.find(key)
|
43
|
+
puts <<-MSG
|
44
|
+
== Loading data from Google Doc "#{doc['title']}"
|
45
|
+
== #{doc['alternateLink']}
|
46
|
+
MSG
|
47
|
+
filename = data_path("#{key}.#{type}")
|
48
|
+
|
49
|
+
case type.to_sym
|
50
|
+
when :xlsx
|
51
|
+
if @drive.server?
|
52
|
+
filename = @drive.export_to_file(key, :xlsx)
|
53
|
+
else
|
54
|
+
@drive.export_to_file(key, :xlsx, filename)
|
55
|
+
end
|
56
|
+
ret = @drive.prepare_spreadsheet(filename)
|
57
|
+
File.unlink(filename) if @drive.server?
|
58
|
+
when :archieml
|
59
|
+
if @drive.server?
|
60
|
+
ret = Archieml.load(@drive.export(key, :txt))
|
61
|
+
else
|
62
|
+
@drive.export_to_file(key, :txt, filename)
|
63
|
+
ret = Archieml.load(File.read(filename))
|
64
|
+
end
|
42
65
|
else
|
43
|
-
|
44
|
-
|
45
|
-
|
66
|
+
if @drive.server?
|
67
|
+
ret = @drive.export(key, type)
|
68
|
+
else
|
69
|
+
@drive.export_to_file(key, type, filename)
|
70
|
+
ret = File.read(filename)
|
71
|
+
end
|
46
72
|
end
|
73
|
+
return ret
|
74
|
+
rescue ::Faraday::ConnectionFailed => exc
|
75
|
+
puts "== FAILED to load Google Doc \"#{exc.message}\""
|
76
|
+
return load_local_copy(filename)
|
47
77
|
rescue ::GoogleDrive::GoogleDriveError => exc
|
48
|
-
|
49
|
-
|
50
|
-
else
|
78
|
+
puts "== FAILED to load Google Doc \"#{exc.message}\""
|
79
|
+
unless @drive.server?
|
51
80
|
puts <<-MSG
|
52
81
|
|
53
82
|
Could not load the Google Doc.
|
@@ -57,36 +86,35 @@ Things to check:
|
|
57
86
|
- Make sure you're logging in with the correct account
|
58
87
|
- Make sure you have access to the document
|
59
88
|
|
60
|
-
Google said "#{exc.message}." It might be a lie.
|
61
89
|
MSG
|
62
90
|
@drive.clear_auth
|
63
91
|
end
|
92
|
+
return load_local_copy(filename)
|
64
93
|
end
|
65
94
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
95
|
+
def load_local_copy(filename)
|
96
|
+
if File.exist? filename
|
97
|
+
puts '== Loading Google Doc from local cache'
|
98
|
+
type = File.extname(filename).gsub('.','').to_sym
|
99
|
+
case type
|
100
|
+
when :xlsx
|
101
|
+
return @drive.prepare_spreadsheet(filename)
|
102
|
+
when :archieml
|
103
|
+
return Archieml.load(File.read(filename))
|
104
|
+
else
|
105
|
+
return File.read(filename)
|
106
|
+
end
|
74
107
|
else
|
75
|
-
|
108
|
+
puts '== No local copy of Google Doc'
|
109
|
+
return nil
|
76
110
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
MSG
|
82
|
-
data
|
111
|
+
end
|
112
|
+
|
113
|
+
def data_path(basename)
|
114
|
+
File.join(@app.root, @app.data_dir, basename)
|
83
115
|
end
|
84
116
|
|
85
117
|
def store_data(key, data)
|
86
|
-
backup_file = File.join(@app.root, @app.data_dir, "#{key}.json")
|
87
|
-
File.open(backup_file, 'w') do |f|
|
88
|
-
f.write(JSON.pretty_generate(data))
|
89
|
-
end
|
90
118
|
@app.data.store(key, data)
|
91
119
|
end
|
92
120
|
end
|
@@ -22,9 +22,11 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_runtime_dependency 'middleman-core', '~> 3'
|
23
23
|
spec.add_runtime_dependency 'retriable', '~> 1.4'
|
24
24
|
spec.add_runtime_dependency 'google-api-client', '< 0.8'
|
25
|
-
spec.add_runtime_dependency 'rubyXL'
|
26
|
-
spec.add_runtime_dependency 'archieml'
|
25
|
+
spec.add_runtime_dependency 'rubyXL', '~> 3.3.7'
|
26
|
+
spec.add_runtime_dependency 'archieml', '~> 0.1.1'
|
27
|
+
spec.add_runtime_dependency 'mime-types', '~> 2.4.3'
|
27
28
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
28
29
|
spec.add_development_dependency 'rake'
|
29
30
|
spec.add_development_dependency 'minitest'
|
31
|
+
spec.add_development_dependency 'yard'
|
30
32
|
end
|
data/test/google_drive_test.rb
CHANGED
@@ -1,40 +1,58 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
|
+
require 'fileutils'
|
2
3
|
require 'google_drive'
|
3
4
|
|
4
5
|
# Test the client lib!
|
5
|
-
class
|
6
|
+
class TestGoogleDrive < MiniTest::Test
|
6
7
|
def setup
|
7
8
|
@drive = ::GoogleDrive.new
|
9
|
+
@old_sheet_file_id = '0AiOYF21HkoowdEZ4Ukkyc09nb2czQUxUYldidTB4Q1E'
|
10
|
+
@new_sheet_file_id = '1vIICbbfHJ8lYSthiDWTNypZulrMResi9zPRjv4ePJJU'
|
11
|
+
@doc_file_id = '1lH-Nr_8UBOkvk8OdcdFoDez3OFIJxkawGVkwlMB-BjQ'
|
8
12
|
end
|
9
13
|
|
10
|
-
def
|
11
|
-
file = @drive.find
|
14
|
+
def test_find
|
15
|
+
file = @drive.find @old_sheet_file_id
|
12
16
|
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
17
|
|
21
|
-
|
22
|
-
file = @drive.find '1vIICbbfHJ8lYSthiDWTNypZulrMResi9zPRjv4ePJJU'
|
18
|
+
file = @drive.find @new_sheet_file_id
|
23
19
|
assert_equal file['title'], 'Example Middleman Google Drive worksheet'
|
24
20
|
end
|
25
21
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
def test_export
|
23
|
+
content = @drive.export @doc_file_id, :txt
|
24
|
+
assert_nil content =~ /^<html>/
|
25
|
+
|
26
|
+
content = @drive.export @doc_file_id, :html
|
27
|
+
assert_not_nil content =~ /^<html>/
|
30
28
|
end
|
31
29
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
30
|
+
def test_export_to_file
|
31
|
+
filename = @drive.export_to_file(@doc_file_id, :html)
|
32
|
+
assert_equal '.html', File.extname(filename)
|
33
|
+
assert File.exist?(filename)
|
34
|
+
assert_not_nil File.read(filename) =~ /^<html>/
|
35
|
+
File.unlink(filename)
|
36
|
+
|
37
|
+
[@new_sheet_file_id, @old_sheet_file_id].each do |file_id|
|
38
|
+
filename = @drive.export_to_file(file_id, :xlsx)
|
39
|
+
assert_equal '.xlsx', File.extname(filename)
|
40
|
+
assert File.exist?(filename)
|
41
|
+
File.unlink(filename)
|
42
|
+
end
|
43
|
+
end
|
35
44
|
|
36
|
-
|
37
|
-
|
45
|
+
def test_prepare_spreadsheet
|
46
|
+
[@old_sheet_file_id, @new_sheet_file_id].each do |file_id|
|
47
|
+
#filename = "/tmp/google_drive_#{file_id}.xlsx"
|
48
|
+
filename = @drive.export_to_file(file_id, :xlsx, filename)
|
49
|
+
assert_equal '.xlsx', File.extname(filename)
|
50
|
+
assert File.exist?(filename)
|
51
|
+
data = @drive.prepare_spreadsheet(filename)
|
52
|
+
assert_has_key data, 'microcopy'
|
53
|
+
assert_has_key data['microcopy'], 'help'
|
54
|
+
File.unlink(filename)
|
55
|
+
end
|
38
56
|
end
|
39
57
|
|
40
58
|
def test_copy_file
|
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.3.
|
4
|
+
version: 0.3.5
|
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: 2015-03-
|
12
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: middleman-core
|
@@ -57,30 +57,44 @@ dependencies:
|
|
57
57
|
name: rubyXL
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 3.3.7
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - "
|
67
|
+
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 3.3.7
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: archieml
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
76
|
+
version: 0.1.1
|
77
77
|
type: :runtime
|
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:
|
83
|
+
version: 0.1.1
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: mime-types
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 2.4.3
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 2.4.3
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: bundler
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +137,20 @@ dependencies:
|
|
123
137
|
- - ">="
|
124
138
|
- !ruby/object:Gem::Version
|
125
139
|
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: yard
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
126
154
|
description:
|
127
155
|
email:
|
128
156
|
- ryan@mrk.cc
|