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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b55941adf06f492ae066a183856e98b563a03b42
4
- data.tar.gz: 20e2056fbdc0114d14c391de431d583fc9d1a88d
3
+ metadata.gz: f94ae0f5e1dc5cacb9af02dd286d77381b91081d
4
+ data.tar.gz: 5ee09f46e1fe604ff51319ec939be08a39b4015a
5
5
  SHA512:
6
- metadata.gz: 310b40a38b5fb3c452b0e261476552b261ea7aa4a11349bb9f0e6716254323ef6fe92385a41205ec51c32b1642d6cd579fb65fd8e7696e065887616452b2acc3
7
- data.tar.gz: 2ed85c7be3f9e6c9fb97bc28ea7bb406d4d4f3eeabf625b1c811e1908d6a41bb6634ec5c5f22838b8036429b2f26dc77a3e39ea6634d3fb913534f6589a408ae
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
- def find(key)
38
- return @_files[key] unless @_files[key].nil?
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: key })
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[key] = resp.data
72
+ @_files[file_id] = resp.data
51
73
  end
52
74
 
53
- def spreadsheet(key)
54
- list_resp = find(key)
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. We're gonna request the spreadsheet
57
- # in excel format. Because it includes all the worksheets.
58
- uri = list_resp['exportLinks'][
59
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
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
- # get a temporary file. The export is binary, so open the tempfile in
68
- # write binary mode
69
- fp = Tempfile.new(['gdoc', '.xlsx'], binmode: true)
70
- filename = fp.path
71
- fp.write get_resp.body
72
- fp.close
100
+ # contents
101
+ get_resp.body
102
+ end
73
103
 
74
- # now open the file with spreadsheet
75
- ret = RubyXL::Parser.parse(filename)
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
- fp.unlink # delete our tempfile
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
- ret
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
- def prepared_spreadsheet(key)
83
- xls = spreadsheet(key)
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
- def doc(key, format = 'html')
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
- # die if there's an error
149
- fail GoogleDriveError, resp.error_message if resp.error?
150
-
151
- resp.body
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
- def copy(file_id, title = nil)
155
- drive = @client.discovered_api('drive', 'v2')
156
-
157
- if title.nil?
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, 'spreadsheet')
22
- handle_option(options.load_docs, 'text')
23
- handle_option(options.load_docs_html, 'html')
24
- handle_option(options.load_docs_archieml, '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 == 'spreadsheet'
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
- rescue ::Faraday::ConnectionFailed => exc
40
- if @drive.server?
41
- puts "== FAILED to load Google Doc \"#{exc.message}\""
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
- puts <<-MSG
44
- == Could not connect to Google Drive. Local data will be used.
45
- MSG
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
- if @drive.server?
49
- puts "== FAILED to load Google Doc \"#{exc.message}\""
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 load_doc(key, type)
67
- case type.to_s
68
- when 'spreadsheet'
69
- data = @drive.prepared_spreadsheet(key)
70
- when 'html'
71
- data = @drive.doc(key, 'html')
72
- when 'archieml'
73
- data = Archieml.load(@drive.doc(key, 'text'))
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
- data = @drive.doc(key, 'text')
108
+ puts '== No local copy of Google Doc'
109
+ return nil
76
110
  end
77
- doc = @drive.find(key)
78
- puts <<-MSG
79
- == Loaded data from Google Doc "#{doc['title']}"
80
- == #{doc['alternateLink']}
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
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  module GoogleDrive
3
- VERSION = '0.3.4'
3
+ VERSION = '0.3.5'
4
4
  end
5
5
  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
@@ -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 TestChorusApiClient < MiniTest::Test
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 test_old_find
11
- file = @drive.find '0AiOYF21HkoowdEZ4Ukkyc09nb2czQUxUYldidTB4Q1E'
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
- def test_new_find
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 test_new_prepared_spreadsheet
27
- file = @drive.prepared_spreadsheet '1vIICbbfHJ8lYSthiDWTNypZulrMResi9zPRjv4ePJJU'
28
- assert_has_key file, 'microcopy'
29
- assert_has_key file['microcopy'], 'help'
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 test_new_doc
33
- file = @drive.doc '1lH-Nr_8UBOkvk8OdcdFoDez3OFIJxkawGVkwlMB-BjQ'
34
- assert_not_nil file =~ /^<html>/
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
- file = @drive.doc '1lH-Nr_8UBOkvk8OdcdFoDez3OFIJxkawGVkwlMB-BjQ', 'text'
37
- assert_nil file =~ /^<html>/
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
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-14 00:00:00.000000000 Z
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: '0'
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: '0'
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: '0'
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: '0'
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