g_sheets 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cc92b3a82cf114ffe7d27920a57e044c63df59b6
4
+ data.tar.gz: 4c01053def903df907b56746493d1067914a182e
5
+ SHA512:
6
+ metadata.gz: dd009be75e2ab073a9750dd8ddd5f82739829d96d05569cffbf49087780c71d7447b80d3950237746a5e6b10f47ce09da58b163b83461d77d7e39a08c60b4348
7
+ data.tar.gz: 5b8e72be57bd46cd6f18b5af7d41f334c7ebbc8a47d571842e761ccfde70a6fd769ae5d8f38402df2fe33e2439da172e8681273aff1c7208d8434666ddc5c20b
data/.env.sample ADDED
@@ -0,0 +1,3 @@
1
+ export CLIENT_ID="your-client-id.apps.googleusercontent.com"
2
+ export CLIENT_SECRET="your-client-secret"
3
+
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+
14
+ .env
15
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.14.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in g_sheets.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # GSheets
2
+
3
+ A Google Sheets api adapter in ruby
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'g_sheets'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install g_sheets
20
+
21
+ ## Usage
22
+
23
+ ### Configuration
24
+
25
+ We're using the `dotenv` gem so you can just place your environment variables inside a file called `.env` and add that file to your `.gitignore` list; that way your authentication keys are kept safe.
26
+
27
+ If you wish to access user's data, you will need to create credentials for an `OAuth client ID`. Please see the [documentation](https://developers.google.com/identity/protocols/OAuth2) on how to get the client id and secret.
28
+
29
+ ### Getting the an OAuth token from Google
30
+
31
+ In order to make operations on a user's Google Spreadsheet you will need an authentication token. There is a sample console OAuth token generator available in `GSheets::Oauth`
32
+
33
+ ```ruby
34
+ CLIENT_ID = ENV["CLIENT_ID"]; CLIENT_SECRET = ENV["CLIENT_SECRET"]
35
+ authenticator = GSheets::Oauth::Offline.new(CLIENT_ID, CLIENT_SECRET)
36
+ uri = authenticator.get_authentication_uri
37
+
38
+ puts "Please open #{uri.to_s} in your browser, accept the permissions, and copy-paste the code"
39
+ code = $stdin.gets.chomp
40
+
41
+ refresh_token = authenticator.get_refresh_token(authentication_code: code)
42
+ access_token = authenticator.get_access_token(refresh_token: refresh_token)
43
+ ```
44
+
45
+ Save the `refresh_token` somewhere safe, as it would be used later to create a new `get_access_token` when that expires.
46
+
47
+ ## Development
48
+
49
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
50
+
51
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
52
+
53
+ You can also run `bundle exec rake console` to get a `pry` console running with all files required.
54
+
55
+ Please see the [documentation](https://developers.google.com/sheets/api/v3/data) on the sheets api if you'd like to add more functionality :)
56
+
57
+ ## Contributing
58
+
59
+ Bug reports and pull requests are welcome on GitHub at https://github.com/parasquid/g_sheets.
60
+
61
+ TODO:
62
+ * Ability to include a module into a class and magically give it crud properties:
63
+ * .where
64
+ * .find
65
+ * .create
66
+ * .order
67
+ * .delete
68
+ * Documentation and guides on how to use standalone
69
+ * Documentation and guides on how to use with Rails
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ desc "Open a pry session preloaded with this library"
9
+ task :console do
10
+ system "pry --gem"
11
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "g_sheets"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/g_sheets.gemspec ADDED
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'g_sheets/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "g_sheets"
8
+ spec.version = GSheets::VERSION
9
+ spec.authors = ["parasquid"]
10
+ spec.email = ["tristan.gomez@gmail.com"]
11
+
12
+ spec.summary = %q{Database like API for Google Spreadsheets}
13
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = "https://github.com/parasquid/g_sheets"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
20
+ # else
21
+ # raise "RubyGems 2.0 or newer is required to protect against " \
22
+ # "public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.14"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+
36
+ spec.add_development_dependency "rspec-given"
37
+ spec.add_development_dependency "guard-rspec"
38
+ spec.add_development_dependency "pry"
39
+ spec.add_development_dependency "dotenv"
40
+
41
+ spec.add_dependency "faraday", "~> 0.11.0"
42
+ spec.add_dependency "nori", "~> 2.6.0"
43
+ spec.add_dependency "google-api-client", "~> 0.10"
44
+ end
@@ -0,0 +1,63 @@
1
+ require 'signet/oauth_2/client'
2
+
3
+ module GSheets
4
+ module Oauth
5
+ class Offline
6
+ attr_reader :client_id, :client_secret, :scope, :signet_client
7
+
8
+ def initialize(
9
+ client_id,
10
+ client_secret,
11
+ scope: default_scopes,
12
+ signet_client: nil
13
+ )
14
+ @client_id = client_id
15
+ @client_secret = client_secret
16
+ @scope = scope
17
+ @signet_client = signet_client || get_signet_client
18
+ end
19
+
20
+ def get_authentication_uri
21
+ @signet_client.authorization_uri
22
+ end
23
+
24
+ def get_access_token(authentication_code: nil, refresh_token: nil)
25
+ error_message = "you must provide either an authentication_code or refresh_token".freeze
26
+ raise ArgumentError, error_message if authentication_code.nil? && refresh_token.nil?
27
+ @signet_client.code = authentication_code if authentication_code
28
+ @signet_client.refresh_token = refresh_token if refresh_token
29
+ @signet_client.fetch_access_token!
30
+ @signet_client.access_token
31
+ end
32
+
33
+ def get_refresh_token(authentication_code:)
34
+ @signet_client.code = authentication_code
35
+ @signet_client.fetch_access_token!
36
+ @signet_client.refresh_token
37
+ end
38
+
39
+ private
40
+
41
+ def default_scopes
42
+ [
43
+ "https://www.googleapis.com/auth/drive",
44
+ "https://www.googleapis.com/auth/drive.file",
45
+ "https://www.googleapis.com/auth/drive.metadata",
46
+ "https://spreadsheets.google.com/feeds",
47
+ "https://docs.google.com/feeds"
48
+ ]
49
+ end
50
+
51
+ def get_signet_client
52
+ Signet::OAuth2::Client.new(
53
+ authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
54
+ token_credential_uri: 'https://www.googleapis.com/oauth2/v3/token',
55
+ client_id: client_id,
56
+ client_secret: client_secret,
57
+ :scope => scope,
58
+ :redirect_uri => 'urn:ietf:wg:oauth:2.0:oob'
59
+ )
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,6 @@
1
+ require "g_sheets/v4/session"
2
+
3
+ module GSheets
4
+ class Session < V4::Session
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require "g_sheets/v4/sheet"
2
+
3
+ module GSheets
4
+ class Sheet < V4::Sheet
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require "g_sheets/v4/spread_sheet"
2
+
3
+ module GSheets
4
+ class SpreadSheet < V4::SpreadSheet
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ module GSheets
2
+ module V3
3
+ class Session
4
+ def initialize(access_token:, http_client: Faraday, alt: "json")
5
+ @access_token = access_token
6
+ @alt = alt
7
+ @http_client = http_client
8
+ end
9
+
10
+ def get_cells(id:, grid_id: "default", options:[])
11
+ connection.get "cells/#{id}/#{grid_id}/private/full?#{options.join('&')}"
12
+ end
13
+
14
+ def get_list(id:, grid_id: "default", options:[])
15
+ connection.get "list/#{id}/#{grid_id}/private/full?#{options.join('&')}"
16
+ end
17
+
18
+ def get_worksheets(id:)
19
+ connection.get "worksheets/#{id}/private/full"
20
+ end
21
+
22
+ def connection
23
+ @http_client.new "#{sheets_api_endpoint}?access_token=#{@access_token}&alt=#{@alt}"
24
+ end
25
+
26
+ private
27
+
28
+ def sheets_api_endpoint
29
+ "https://spreadsheets.google.com/feeds"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,47 @@
1
+ module GSheets
2
+ module V3
3
+ class SpreadSheet
4
+ def initialize(session:, id:)
5
+ @id = id
6
+ @session = session
7
+ end
8
+
9
+ def worksheets
10
+ list_work_sheets.keys.map do |title|
11
+ WorkSheet.new(session: @session, id: @id, grid_id: list_work_sheets[title])
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def list_work_sheets
18
+ result = {}
19
+ document["feed"]["entry"].each do |e|
20
+ result[get_title(e)] = get_grid_id_from_link(e["link"])
21
+ end
22
+ result
23
+ end
24
+
25
+ def document
26
+ JSON.parse(@session.get_worksheets(id: @id).body)
27
+ end
28
+
29
+ def get_title(entry)
30
+ entry["title"]["$t"]
31
+ end
32
+
33
+ def get_self_link(link)
34
+ link.select { |l| l["rel"] == "self" }.first["href"]
35
+ end
36
+
37
+ def get_grid_id(self_link)
38
+ self_link.split("/").last
39
+ end
40
+
41
+ def get_grid_id_from_link(link)
42
+ self_link = get_self_link(link)
43
+ get_grid_id(self_link)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,50 @@
1
+ module GSheets
2
+ module V3
3
+ class WorkSheet
4
+ def initialize(session:, grid_id: " default", id:)
5
+ @grid_id = grid_id
6
+ @session = session
7
+ @id = id
8
+ end
9
+
10
+ def headers
11
+ cells_first_row["feed"]["entry"].map {|e| e["content"]["$t"]}
12
+ end
13
+
14
+ def rows
15
+ data_list = worksheet_as_list["feed"]["entry"]
16
+ list = data_list.map {|entry|
17
+ [
18
+ "title: #{entry['title']['$t']}",
19
+ entry["content"]["$t"]
20
+ ].join(", ")
21
+ }
22
+
23
+ result = []
24
+ list.each do |l|
25
+ row = {}
26
+ l.split(",").each do |elem|
27
+ e = elem.split(":")
28
+ row[e.first.strip.freeze] = e.last.strip.freeze
29
+ end
30
+ result << row
31
+ end
32
+ result.map(&:values)
33
+ end
34
+
35
+ private
36
+
37
+ def cells_first_row
38
+ JSON.parse(@session.get_cells(id: @id, grid_id: @grid_id, options: header_row_options).body)
39
+ end
40
+
41
+ def worksheet_as_list
42
+ JSON.parse(@session.get_list(id: @id, grid_id: @grid_id).body)
43
+ end
44
+
45
+ def header_row_options
46
+ ["min-row=1", "max-row=1"]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,28 @@
1
+ module GSheets
2
+ module V4
3
+ class Session
4
+ def initialize(access_token:, service: Google::Apis::SheetsV4::SheetsService.new)
5
+ @access_token = access_token
6
+ @service = service
7
+ @service.authorization = access_token
8
+ end
9
+
10
+ def get_sheets_from_spreadsheet(id)
11
+ service.get_spreadsheet(id).sheets
12
+ end
13
+
14
+ def append_row_to_spreadsheet(id:, row:, sheet_name:)
15
+ service.append_spreadsheet_value(
16
+ id,
17
+ sheet_name,
18
+ {"values": [row]},
19
+ value_input_option: "RAW"
20
+ )
21
+ end
22
+
23
+ def service
24
+ @service
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module GSheets
2
+ module V4
3
+ class Sheet
4
+ def initialize(sheet:, spread_sheet:)
5
+ @sheet = sheet
6
+ @spread_sheet = spread_sheet
7
+ @session = spread_sheet.session
8
+ @sheet_name = sheet.properties.title
9
+ end
10
+
11
+ def append(row)
12
+ @session.append_row_to_spreadsheet(
13
+ id: @spread_sheet.id,
14
+ sheet_name: @sheet_name,
15
+ row: row
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module GSheets
2
+ module V4
3
+ class SpreadSheet
4
+ attr_accessor :id
5
+
6
+ def initialize(session:, id:)
7
+ @session = session
8
+ @id = id
9
+ end
10
+
11
+ def sheets
12
+ @session.get_sheets_from_spreadsheet(@id).map { |sheet|
13
+ Sheet.new(sheet: sheet, spread_sheet: self)
14
+ }
15
+ end
16
+
17
+ def session
18
+ @session
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module GSheets
2
+ VERSION = "0.2.0"
3
+ end
data/lib/g_sheets.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "dotenv/load"
2
+
3
+ require "faraday"
4
+ require "google/apis/sheets_v4"
5
+
6
+ module GSheets
7
+ # Your code goes here...
8
+ end
9
+
10
+ require "g_sheets/version"
11
+ require "g_sheets/oauth/offline"
12
+ require "g_sheets/session"
13
+ require "g_sheets/spread_sheet"
14
+ require "g_sheets/sheet"
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: g_sheets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - parasquid
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-given
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: dotenv
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faraday
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.11.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.11.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: nori
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 2.6.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 2.6.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: google-api-client
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.10'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.10'
153
+ description:
154
+ email:
155
+ - tristan.gomez@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".env.sample"
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".travis.yml"
164
+ - Gemfile
165
+ - README.md
166
+ - Rakefile
167
+ - bin/console
168
+ - bin/setup
169
+ - g_sheets.gemspec
170
+ - lib/g_sheets.rb
171
+ - lib/g_sheets/oauth/offline.rb
172
+ - lib/g_sheets/session.rb
173
+ - lib/g_sheets/sheet.rb
174
+ - lib/g_sheets/spread_sheet.rb
175
+ - lib/g_sheets/v3/session.rb
176
+ - lib/g_sheets/v3/spread_sheet.rb
177
+ - lib/g_sheets/v3/work_sheet.rb
178
+ - lib/g_sheets/v4/session.rb
179
+ - lib/g_sheets/v4/sheet.rb
180
+ - lib/g_sheets/v4/spread_sheet.rb
181
+ - lib/g_sheets/version.rb
182
+ homepage: https://github.com/parasquid/g_sheets
183
+ licenses: []
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.6.8
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: Database like API for Google Spreadsheets
205
+ test_files: []