middleman-google_drive 0.3.4 → 0.3.5

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: 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