sheetsu-ruby 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 08990261ab0bd01d5d09dd026ece5ff594d28acc
4
+ data.tar.gz: 8025b4063f7f53881256b96df819e2e605ad1e32
5
+ SHA512:
6
+ metadata.gz: 86efae15d670ef5e58f8815ac00a75946aa9ed4a699ac39323166b7882f929829c3cd7315c54158030067ab5b6e1de1a6608c2b38fddd76f99e656582c11a0cd
7
+ data.tar.gz: 4380e107a9e11912db44c1c35fbfdea924726eb79111b4870a38d1cd405cc83eea70afc7a19397b05d884c2cb2cb95d086d4d35e426fc5a3affe3d90d0ea0a1d
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /sheetsu-ruby-*.gem
11
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,3 @@
1
+ SimpleCov.start do
2
+ add_group "lib", "lib"
3
+ end
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at jb41.mail@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sheetsu.gemspec
4
+ gemspec
@@ -0,0 +1,245 @@
1
+ # sheetsu-ruby
2
+ Ruby bindings for the Sheetsu API (https://sheetsu.com/docs).
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'sheetsu-ruby'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install sheetsu-ruby
19
+
20
+ ## Usage
21
+
22
+ ### Generating a Client
23
+
24
+ You need to create a new Sheetsu::Client object, and populate it with your Sheetsu API URL. You can find this URL on [Sheetsu Dashboard](https://sheetsu.com/your-apis).
25
+
26
+ ```ruby
27
+ # Create new client object
28
+ client = Sheetsu::Client.new("https://sheetsu.com/apis/v1.0/020b2c0f")
29
+ ```
30
+ or
31
+ ```ruby
32
+ # Create new client object
33
+ client = Sheetsu::Client.new("020b2c0f")
34
+ ```
35
+
36
+ If you have HTTP Basic Authentication turned on for your API, you should pass `api_key` and `api_secret` here, like:
37
+ ```ruby
38
+ # Create new client object with HTTP Basic Auth keys
39
+ client = Sheetsu::Client.new("020b2c0f", api_key: "YOUR_API_KEY", api_secret: "YOUR_API_SECRET")
40
+ ```
41
+
42
+ ### CRUD
43
+
44
+ Sheetsu gives you the ability to use full CRUD on your Google Spreadsheet. Remember to populate the first row of every sheet with column names. You can look at [example spreadsheet](https://docs.google.com/spreadsheets/d/1WTwXrh2ZDXmXATZlQIuapdv4ldyhJGZg7LX8GlzPdZw/edit?usp=sharing).
45
+
46
+ ### Create
47
+ [Link to docs](https://sheetsu.com/docs#post)
48
+
49
+ To add data to Google Spreadsheets, send a hash or an array of hashes.
50
+ ```ruby
51
+ # Adds single row
52
+ client.create({ id: 7, name: "Glenn", score: "69" })
53
+
54
+ # Adds bunch of rows
55
+ rows = [
56
+ { id: 7, name: "Glenn", score: "69" },
57
+ { id: 8, name: "Brian", score: "77" },
58
+ { id: 9, name: "Joe", score: "45" }
59
+ ]
60
+ client.create(rows)
61
+ ```
62
+
63
+ By default, all writes are performed on the first sheet (worksheet). Pass name of a sheet as a 2nd param to add data to other worksheet.
64
+ ```ruby
65
+ # Adds single row to worksheet named "Sheet3"
66
+ client.create({ "foo" => "bar", "baz" => "quux" }, "Sheet3")
67
+ ```
68
+
69
+ On success returns a hash or an array of hashes with created values. On error check [errors](#errors).
70
+
71
+ ### Read
72
+ [Link to docs](https://sheetsu.com/docs#get)
73
+
74
+ Read the whole sheet
75
+ ```ruby
76
+ client.read
77
+ ```
78
+
79
+ You can pass hash with options
80
+ - `sheet` - get data from named worksheet
81
+ - `limit` - limit number of results
82
+ - `offset` - start from N first record
83
+ - `search` - hash with search params [(more below)](#search)
84
+
85
+ ```ruby
86
+ # Get first two rows from worksheet named "Sheet2"
87
+ client.read(sheet: "Sheet2", limit: 2)
88
+
89
+ # Get 5th record from worksheet named "Sheet3"
90
+ client.read(
91
+ offset: 4, # because rows are numbered from 0
92
+ limit: 1, # because only one row
93
+ sheet: "Sheet3"
94
+ )
95
+ ```
96
+
97
+ #### search
98
+ [Link to docs](https://sheetsu.com/docs#get_search)
99
+
100
+ To get rows that match search criteria, pass a hash with search params
101
+
102
+ ```ruby
103
+ # Get all rows where column 'id' is 'foo' and column 'value' is 'bar'
104
+ client.read(search: { id: "foo", value: "bar" })
105
+
106
+ # Get all rows where column 'First name' is 'Peter' and column 'Score' is '42'
107
+ client.read(search: { "First name" => "Peter", "Score" => 42 })
108
+
109
+ # Get first two row where column 'First name' is 'Peter',
110
+ # column 'Score' is '42' from sheet named "Sheet3"
111
+ client.read(
112
+ search: { "First name" => "Peter", "Score" => 42 } # search criteria
113
+ limit: 2 # first two rows
114
+ sheet: "Sheet3" # Sheet name
115
+ )
116
+ ```
117
+
118
+ On success returns an array of hashes. On error check [errors](#errors).
119
+
120
+ ### Update
121
+ [Link to docs](https://sheetsu.com/docs#patch)
122
+
123
+ To update row(s), pass column name and its value which is used to find row(s).
124
+
125
+ ```ruby
126
+ # Update all columns where 'name' is 'Peter' to have 'score' = 99 and 'last name' = 'Griffin'
127
+ client.update(
128
+ "name", # column name
129
+ "Peter", # value to search for
130
+ { "score": 99, "last name" => "Griffin" }, # hash with updates
131
+ )
132
+ ```
133
+
134
+ By default, [PATCH request](https://sheetsu.com/docs#patch) is sent, which is updating only values which are in the hash passed to the method. To send [PUT request](https://sheetsu.com/docs#put), pass 4th argument being `true`. [Read more about the difference between PUT and PATCH in our docs](https://sheetsu.com/docs#patch).
135
+
136
+
137
+ ```ruby
138
+ # Update all columns where 'name' is 'Peter' to have 'score' = 99 and 'last name' = 'Griffin'
139
+ # Empty all cells which matching, which are not 'score' or 'last name'
140
+ client.update(
141
+ "name", # column name
142
+ "Peter", # value to search for
143
+ { "score": 99, "last name" => "Griffin" }, # hash with updates
144
+ true # nullify all fields not passed in the hash above
145
+ )
146
+ ```
147
+
148
+ To perform `#update` on different than the first sheet, pass sheet name as a 5th argument.
149
+ ```ruby
150
+ # Update all columns where 'name' is 'Peter' to have 'score' = 99 and 'last name' = 'Griffin'
151
+ # In sheet named 'Sheet3'
152
+ # Empty all cells which matching, which are not 'score' or 'last name'
153
+ client.update(
154
+ "name", # column name
155
+ "Peter", # value to search for
156
+ { "score": 99, "last name" => "Griffin" }, # hash with updates
157
+ true, # nullify all fields not passed in the hash above
158
+ "Sheet3"
159
+ )
160
+ ```
161
+
162
+ On success returns an array of hashes with updated values. On error check [errors](#errors).
163
+
164
+ ### Delete
165
+ [Link to docs](https://sheetsu.com/docs#delete)
166
+
167
+ To delete row(s), pass column name and its value which is used to find row(s).
168
+
169
+ ```ruby
170
+ # Delete all rows where 'name' equals 'Peter'
171
+ client.delete(
172
+ "name", # column name
173
+ "Peter" # value to search for
174
+ )
175
+ ```
176
+
177
+ You can pass sheet name as a 3rd argument. All operations are performed on the first sheet, by default.
178
+ ```ruby
179
+ # Delete all rows where 'foo' equals 'bar' in sheet 'Sheet3'
180
+ client.delete(
181
+ "foo", # column name
182
+ "bar", # value to search for
183
+ "Sheet3" # sheet name
184
+ )
185
+ ```
186
+
187
+ If success returns `:ok` symbol. If error check [errors](#errors).
188
+
189
+ ### Errors
190
+ There are different styles of error handling. We choose to throw exceptions and signal failure loudly. You do not need to deal with any HTTP responses from the API calls directly. All exceptions are matching particular response code from Sheetsu API. You can [read more about it here](https://sheetsu.com/docs#statuses).
191
+
192
+ All exceptions are a subclass of `Sheetsu::SheetsuError`. The list of different error subclasses is listed below. You can choose to rescue each of them or rescue just the parent class (`Sheetsu::SheetsuError`).
193
+
194
+
195
+ ```ruby
196
+ Sheetsu::NotFoundError
197
+ Sheetsu::ForbiddenError
198
+ Sheetsu::LimitExceedError
199
+ Sheetsu::UnauthorizedError
200
+ ```
201
+
202
+ ## Development
203
+
204
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
205
+
206
+ 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).
207
+
208
+ Run all tests:
209
+ ```
210
+ rspec
211
+ ```
212
+
213
+ Run a single test:
214
+ ```
215
+ rspec spec/read_spec.rb
216
+ ```
217
+
218
+ ## Contributing
219
+
220
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sheetsu/sheetsu-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
221
+
222
+ ### Pull Requests
223
+
224
+ - **Add tests!** Your patch won't be accepted if it doesn't have tests.
225
+
226
+ - **Create topic branches**. Please, always create a branch with meaningful name. Don't ask us to pull from your master branch.
227
+
228
+ - **One pull request per feature**. If you want to do more than one thing, please send
229
+ multiple pull requests.
230
+
231
+ - **Send coherent history**. Make sure each individual commit in your pull
232
+ request is meaningful. If you had to make multiple intermediate commits while
233
+ developing, please squash them before sending them to us.
234
+
235
+ ### Docs
236
+
237
+ [Sheetsu documentation sits on GitHub](https://github.com/sheetsu/docs). We would love your contributions! We want to make these docs accessible and easy to understand for everyone. Please send us Pull Requests or open issues on GitHub.
238
+
239
+ # To do
240
+ 1. Allow passing whole API URLs as well as just slugs to the client, like:
241
+ ```ruby
242
+ client = Sheetsu::Client.new("https://sheetsu.com/apis/v1.0/020b2c0f")
243
+ # should be the same as
244
+ client = Sheetsu::Client.new("020b2c0f")
245
+ ```
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sheetsu"
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
@@ -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
@@ -0,0 +1,44 @@
1
+ require 'sheetsu/create'
2
+ require 'sheetsu/read'
3
+ require 'sheetsu/update'
4
+ require 'sheetsu/delete'
5
+ require 'sheetsu/util'
6
+
7
+ module Sheetsu
8
+ class Client
9
+
10
+ def initialize(api_url, auth_credentials={})
11
+ @api_url = Sheetsu::Util.parse_api_url(api_url)
12
+ @http_basic_auth = auth_credentials
13
+ end
14
+
15
+ def create(data, sheet=nil)
16
+ if data.is_a?(Hash)
17
+ Sheetsu::Create.new(@api_url, @http_basic_auth).row(data, { sheet: sheet })
18
+ elsif data.is_a?(Array)
19
+ Sheetsu::Create.new(@api_url, @http_basic_auth).rows(data, { sheet: sheet })
20
+ end
21
+ end
22
+
23
+ def read(options={})
24
+ Sheetsu::Read.new(@api_url, @http_basic_auth).rows(options)
25
+ end
26
+
27
+ def update(column, value, data, update_whole=false, sheet=nil)
28
+ options = { column: column, value: value, data: data, update_whole: update_whole, sheet: sheet }
29
+
30
+ if update_whole
31
+ Sheetsu::Update.new(@api_url, @http_basic_auth).put(options)
32
+ else
33
+ Sheetsu::Update.new(@api_url, @http_basic_auth).patch(options)
34
+ end
35
+ end
36
+
37
+ def delete(column, value, sheet=nil)
38
+ options = { column: column, value: value, sheet: sheet }
39
+
40
+ Sheetsu::Delete.new(@api_url, @http_basic_auth).rows(options)
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ require 'sheetsu/util'
2
+ require 'sheetsu/errors'
3
+ require 'sheetsu/request'
4
+
5
+ require 'json'
6
+
7
+ module Sheetsu
8
+ class Create < Sheetsu::Request
9
+
10
+ def row(row, options={})
11
+ add_options_to_url(options)
12
+
13
+ response = call(:post, row)
14
+ parse_response(response)
15
+ end
16
+
17
+ def rows(rows, options={})
18
+ add_options_to_url(options)
19
+
20
+ response = call(:post, { rows: rows })
21
+ parse_response(response)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ require 'sheetsu/util'
2
+ require 'sheetsu/errors'
3
+ require 'sheetsu/request'
4
+
5
+ require 'json'
6
+
7
+ module Sheetsu
8
+ class Delete < Sheetsu::Request
9
+
10
+ def rows(options)
11
+ add_options_to_url(options)
12
+
13
+ response = call(:delete)
14
+ parse_response(response)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module Sheetsu
2
+ class SheetsuError < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+ attr_reader :http_body
6
+
7
+ def initialize(message = nil, http_status = nil, http_body = nil)
8
+ @message = message
9
+ @http_status = http_status
10
+ @http_body = http_body
11
+ end
12
+ end
13
+
14
+ class NotFoundError < SheetsuError
15
+ end
16
+
17
+ class ForbiddenError < SheetsuError
18
+ end
19
+
20
+ class LimitExceedError < SheetsuError
21
+ end
22
+
23
+ class UnauthorizedError < SheetsuError
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ require 'sheetsu/util'
2
+ require 'sheetsu/errors'
3
+ require 'sheetsu/request'
4
+
5
+ require 'json'
6
+
7
+ module Sheetsu
8
+ class Read < Sheetsu::Request
9
+
10
+ def rows(options={})
11
+ add_options_to_url(options)
12
+
13
+ response = call(:get)
14
+ parse_response(response)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,109 @@
1
+ require 'net/http'
2
+
3
+ module Sheetsu
4
+ class Request
5
+
6
+ def initialize(url, basic_auth)
7
+ @url = url
8
+ @basic_auth = basic_auth
9
+ end
10
+
11
+ def call(method, body=nil)
12
+ http = Net::HTTP.new(uri.host, uri.port)
13
+ http.use_ssl = true
14
+
15
+ request = request(method)
16
+ request = add_headers(request)
17
+ request = add_basic_auth(request)
18
+ request = add_body(request, body)
19
+
20
+ http.request(request)
21
+ end
22
+
23
+ private
24
+
25
+ def uri
26
+ @uri ||= URI.parse(@url)
27
+ end
28
+
29
+ def request(method)
30
+ request = http_klass(method).new(uri.request_uri)
31
+ add_headers(request)
32
+
33
+ request
34
+ end
35
+
36
+ def add_headers(request)
37
+ Sheetsu::Util.default_headers.each_pair { |k,v| request[k] = v }
38
+ request
39
+ end
40
+
41
+ def add_basic_auth(request)
42
+ if @basic_auth.keys.any?
43
+ request.basic_auth(CGI.unescape(@basic_auth[:api_key]), CGI.unescape(@basic_auth[:api_secret]))
44
+ end
45
+ request
46
+ end
47
+
48
+ def add_body(request, body)
49
+ if body
50
+ request.body = body.to_json
51
+ end
52
+ request
53
+ end
54
+
55
+ def http_klass(method)
56
+ case method
57
+ when :get then Net::HTTP::Get
58
+ when :post then Net::HTTP::Post
59
+ when :put then Net::HTTP::Put
60
+ when :patch then Net::HTTP::Patch
61
+ when :delete then Net::HTTP::Delete
62
+ end
63
+ end
64
+
65
+ def parse_response(response)
66
+ Sheetsu::Util.parse_response(response)
67
+ end
68
+
69
+ def add_options_to_url(options)
70
+ add_sheet_to_url(options)
71
+ add_column_value_to_url(options)
72
+ add_query_params_to_url(options)
73
+ end
74
+
75
+ def add_column_value_to_url(options)
76
+ if options[:column] && options[:value]
77
+ @url += Sheetsu::Util.encoded_column(options)
78
+
79
+ options.delete(:column)
80
+ options.delete(:value)
81
+ end
82
+ end
83
+
84
+ def add_sheet_to_url(options)
85
+ if options[:sheet]
86
+ @url += ['/sheets/', CGI::escape(options[:sheet]).to_s].join('')
87
+
88
+ options.delete(:sheet)
89
+ end
90
+ end
91
+
92
+ def add_query_params_to_url(options)
93
+ h = Hash.new.tap do |hash|
94
+ hash[:limit] = options[:limit] if options[:limit]
95
+ hash[:offset] = options[:offset] if options[:offset]
96
+
97
+ if options[:search]
98
+ hash.merge!(options[:search])
99
+ @url += '/search'
100
+ end
101
+ end
102
+
103
+ if h.keys.any?
104
+ @url = Sheetsu::Util.append_query_string_to_url(@url, h)
105
+ end
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,25 @@
1
+ require 'sheetsu/util'
2
+ require 'sheetsu/errors'
3
+ require 'sheetsu/request'
4
+
5
+ require 'json'
6
+
7
+ module Sheetsu
8
+ class Update < Sheetsu::Request
9
+
10
+ def put(options)
11
+ add_options_to_url(options)
12
+
13
+ response = call(:put, options[:data])
14
+ parse_response(response)
15
+ end
16
+
17
+ def patch(options)
18
+ add_options_to_url(options)
19
+
20
+ response = call(:patch, options[:data])
21
+ parse_response(response)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ require 'cgi'
2
+
3
+ require 'sheetsu/version'
4
+
5
+ module Sheetsu
6
+ module Util
7
+
8
+ @sheetsu_api_url = "https://sheetsu.com/apis/v1.0/"
9
+
10
+ def self.default_headers
11
+ {
12
+ 'Accept-Encoding' => 'gzip, deflate',
13
+ 'Accept' => 'application/vnd.sheetsu.3+json',
14
+ 'Content-Type' => 'application/json',
15
+ 'User-Agent' => "Sheetsu-Ruby/#{Sheetsu::VERSION}"
16
+ }
17
+ end
18
+
19
+ def self.parse_api_url(url)
20
+ [@sheetsu_api_url, url].join('')
21
+ end
22
+
23
+ def self.append_query_string_to_url(url, options)
24
+ url + "?#{query_string(options)}"
25
+ end
26
+
27
+ def self.encoded_column(options)
28
+ ['/', CGI::escape(options[:column].to_s), '/', CGI::escape(options[:value].to_s)].join('')
29
+ end
30
+
31
+ def self.parse_response(response)
32
+ case response.code.to_i
33
+ when 200 then JSON.parse(response.body)
34
+ when 201 then JSON.parse(response.body)
35
+ when 204 then :ok
36
+ when 401 then raise Sheetsu::UnauthorizedError
37
+ when 403 then raise Sheetsu::ForbiddenError
38
+ when 404 then raise Sheetsu::NotFoundError
39
+ when 429 then raise Sheetsu::LimitExceedError
40
+ else
41
+ raise Sheetsu::SheetsuError.new(nil, response.code, response.body)
42
+ end
43
+ end
44
+
45
+ private
46
+ def self.query_string(options)
47
+ options.map do |k,v|
48
+ "#{k.to_s}=#{CGI::escape(v.to_s)}"
49
+ end.join('&')
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module Sheetsu
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sheetsu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sheetsu-ruby"
8
+ spec.version = Sheetsu::VERSION
9
+ spec.authors = ["Michael Oblak"]
10
+ spec.email = ["m@sheetsu.com"]
11
+
12
+ spec.summary = %q{Turn Google Spreadsheets into REST APIs}
13
+ spec.description = %q{Sheetsu (https://sheetsu.com) allows you to automate Google Spreadsheets and use them as a resource in a REST API. It's easier than using standard Google Spreadsheets API, because Sheetsu handles all the 'dirty' work for you.}
14
+ spec.homepage = "https://sheetsu.com"
15
+
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.11"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.5"
26
+ spec.add_development_dependency "webmock", "~> 2.3"
27
+ spec.add_development_dependency "pry", "~> 0"
28
+ spec.add_development_dependency "simplecov", "~> 0"
29
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheetsu-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Oblak
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-09 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.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
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.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
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: simplecov
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
+ description: Sheetsu (https://sheetsu.com) allows you to automate Google Spreadsheets
98
+ and use them as a resource in a REST API. It's easier than using standard Google
99
+ Spreadsheets API, because Sheetsu handles all the 'dirty' work for you.
100
+ email:
101
+ - m@sheetsu.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - ".rspec"
108
+ - ".simplecov"
109
+ - CODE_OF_CONDUCT.md
110
+ - Gemfile
111
+ - README.md
112
+ - Rakefile
113
+ - bin/console
114
+ - bin/setup
115
+ - lib/sheetsu.rb
116
+ - lib/sheetsu/create.rb
117
+ - lib/sheetsu/delete.rb
118
+ - lib/sheetsu/errors.rb
119
+ - lib/sheetsu/read.rb
120
+ - lib/sheetsu/request.rb
121
+ - lib/sheetsu/update.rb
122
+ - lib/sheetsu/util.rb
123
+ - lib/sheetsu/version.rb
124
+ - sheetsu-ruby.gemspec
125
+ homepage: https://sheetsu.com
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.8
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Turn Google Spreadsheets into REST APIs
149
+ test_files: []
150
+ has_rdoc: