airtable 0.0.2
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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +122 -0
- data/Rakefile +7 -0
- data/airtable.gemspec +26 -0
- data/lib/airtable.rb +12 -0
- data/lib/airtable/client.rb +20 -0
- data/lib/airtable/record.rb +67 -0
- data/lib/airtable/record_set.rb +22 -0
- data/lib/airtable/resource.rb +17 -0
- data/lib/airtable/table.rb +73 -0
- data/lib/airtable/version.rb +3 -0
- data/test/airtable_test.rb +25 -0
- data/test/test_helper.rb +10 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 44001bc278b32cb324d355c6e89ef3ef0daee53b
|
4
|
+
data.tar.gz: f35bd0c0a6ce9b427684625d5e314913677b9e19
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f530c2ede4381894784a64eb3a4a13e6e7d77ffe632388939d84baea2bc361fe53393888e868781a7aec564e5361b664fa8466aefc3249309019451e079c6521
|
7
|
+
data.tar.gz: 1466e6989283a7475819b94b34bd819fb9e2e8345fdded5538abee6f011a48897c815294e39a142617a4ba06eec72f8296d671cda69c306a670fa41e53377089
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Nathan Esquenazi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# Airtable Ruby Client
|
2
|
+
|
3
|
+
Easily connect to [airtable](https://airtable.com) data using ruby with access to all of the airtable features.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'airtable'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install airtable
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Creating a Client
|
22
|
+
|
23
|
+
First, be sure to register for an [airtable](https://airtable.com) account, create a data worksheet and [get an api key](https://airtable.com/account). Now, setup your Airtable client:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# Pass in api key to client
|
27
|
+
@client = Airtable::Client.new("keyPCx5W")
|
28
|
+
```
|
29
|
+
|
30
|
+
Your API key carries the same privileges as your user account, so be sure to keep it secret!
|
31
|
+
|
32
|
+
### Accessing a Table
|
33
|
+
|
34
|
+
Now we can access any table in our Airsheet account by referencing the [API docs](https://airtable.com/api):
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# Pass in the app key and table name
|
38
|
+
@table = @client.table("appPo84QuCy2BPgLk", "Table Name")
|
39
|
+
```
|
40
|
+
|
41
|
+
### Querying Records
|
42
|
+
|
43
|
+
Once you have access to a table from above, we can query a set of records in the table with:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
@records = @table.records
|
47
|
+
```
|
48
|
+
|
49
|
+
We can specify a `sort` order, `limit`, and `offset` as part of our query:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
@records = @table.records(:sort => ["Name", :asc], :limit => 50)
|
53
|
+
@records # => [#<Airtable::Record :name=>"Bill Lowry", :email=>"billery@gmail.com">, ...]
|
54
|
+
@records.offset #=> "itrEN2TCbrcSN2BMs"
|
55
|
+
```
|
56
|
+
|
57
|
+
This will return the records based on the query as well as an `offset` for the next round of records. We can then access the contents of any record:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
@bill = @record.first
|
61
|
+
# => #<Airtable::Record :name=>"Bill Lowry", :email=>"billery@gmail.com", :id=>"rec02sKGVIzU65eV1">
|
62
|
+
@bill[:id] # => "rec02sKGVIzU65eV2"
|
63
|
+
@bill[:name] # => "Bill Lowry"
|
64
|
+
@bill[:email] # => "billery@gmail.com"
|
65
|
+
```
|
66
|
+
|
67
|
+
Note that you can only request a maximimum of 100 records in a single query. To retrieve more records, use the "batch" feature below.
|
68
|
+
|
69
|
+
### Batch Querying All Records
|
70
|
+
|
71
|
+
We can also query all records in the table through a series of batch requests with:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
@records = @table.all(:sort => ["Name", :asc])
|
75
|
+
```
|
76
|
+
|
77
|
+
This executes a variable number of network requests (100 records per batch) to retrieve all records in a sheet.
|
78
|
+
|
79
|
+
### Finding a Record
|
80
|
+
|
81
|
+
Records can be queried by `id` using the `find` method on a table:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
@record = @table.find("rec02sKGVIzU65eV2")
|
85
|
+
# => #<Airtable::Record :name=>"Bill Lowry", :email=>"billery@gmail.com", :id=>"rec02sKGVIzU65eV1">
|
86
|
+
```
|
87
|
+
|
88
|
+
### Inserting Records
|
89
|
+
|
90
|
+
Records can be inserted using the `create` method on a table:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
@record = Airtable::Record.new(:name => "Sarah Jaine", :email => "sarah@jaine.com")
|
94
|
+
@table.create(record)
|
95
|
+
# => #<Airtable::Record :name=>"Sarah Jaine", :email=>"sarah@jaine.com", :id=>"rec03sKOVIzU65eV4">
|
96
|
+
```
|
97
|
+
|
98
|
+
### Updating Records
|
99
|
+
|
100
|
+
Records can be updated using the `update` method on a table:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
@record[:email] = "sarahjaine@updated.com"
|
104
|
+
@table.update(record)
|
105
|
+
# => #<Airtable::Record :name=>"Sarah Jaine", :email=>"sarahjaine@updated.com", :id=>"rec03sKOVIzU65eV4">
|
106
|
+
```
|
107
|
+
|
108
|
+
### Deleting Records
|
109
|
+
|
110
|
+
Records can be updated using the `update` method on a table:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
@table.destroy(record)
|
114
|
+
```
|
115
|
+
|
116
|
+
## Contributing
|
117
|
+
|
118
|
+
1. Fork it ( https://github.com/nesquena/airtable-ruby/fork )
|
119
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
120
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
121
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
122
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/airtable.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'airtable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "airtable"
|
8
|
+
spec.version = Airtable::VERSION
|
9
|
+
spec.authors = ["Nathan Esquenazi"]
|
10
|
+
spec.email = ["nesquena@gmail.com"]
|
11
|
+
spec.summary = %q{Easily connect to airtable data using ruby}
|
12
|
+
spec.description = %q{Easily connect to airtable data using ruby with access to all of the airtable features.}
|
13
|
+
spec.homepage = "https://github.com/nesquena/airtable-ruby"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "httparty"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.6.0"
|
25
|
+
spec.add_development_dependency "fakeweb", "~> 1.3"
|
26
|
+
end
|
data/lib/airtable.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'delegate'
|
3
|
+
require "airtable/version"
|
4
|
+
require 'airtable/resource'
|
5
|
+
require 'airtable/record'
|
6
|
+
require 'airtable/record_set'
|
7
|
+
require 'airtable/table'
|
8
|
+
require 'airtable/client'
|
9
|
+
|
10
|
+
module Airtable
|
11
|
+
# Nothing for now
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Allows access to data on airtable
|
2
|
+
#
|
3
|
+
# Fetch all records from table:
|
4
|
+
#
|
5
|
+
# client = Airtable::Client.new("keyPtVG4L4sVudsCx5W")
|
6
|
+
# client.table("appXXV84QuCy2BPgLk", "Sheet Name").all
|
7
|
+
#
|
8
|
+
|
9
|
+
module Airtable
|
10
|
+
class Client
|
11
|
+
def initialize(api_key)
|
12
|
+
@api_key = api_key
|
13
|
+
end
|
14
|
+
|
15
|
+
# table("appXXV84QuCy2BPgLk", "Sheet Name")
|
16
|
+
def table(app_token, worksheet_name)
|
17
|
+
Table.new(@api_key, app_token, worksheet_name)
|
18
|
+
end
|
19
|
+
end # Client
|
20
|
+
end # Airtable
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Airtable
|
2
|
+
|
3
|
+
class Record
|
4
|
+
def initialize(attrs={})
|
5
|
+
@columns_map = attrs.keys
|
6
|
+
@attrs = HashWithIndifferentAccess.new(Hash[attrs.map { |k, v| [ to_key(k), v ] }])
|
7
|
+
@attrs.map { |k, v| define_accessor(k) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def id; @attrs["id"]; end
|
11
|
+
def id=(val); @attrs["id"] = val; end
|
12
|
+
|
13
|
+
# Return given attribute based on name or blank otherwise
|
14
|
+
def [](name)
|
15
|
+
@attrs.has_key?(to_key(name)) ? @attrs[to_key(name)] : ""
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set the given attribute to value
|
19
|
+
def []=(name, value)
|
20
|
+
@attrs[to_key(name)] = value
|
21
|
+
define_accessor(name) unless respond_to?(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"#<Airtable::Record #{attributes.map { |a, v| ":#{a}=>#{v.inspect}" }.join(", ")}>"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Hash of attributes with underscored column names
|
29
|
+
def attributes; @attrs; end
|
30
|
+
|
31
|
+
# Hash with keys based on airtable original column names
|
32
|
+
def fields; Hash[@columns_map.map { |k| [ k, @attrs[to_key(k)] ] }]; end
|
33
|
+
|
34
|
+
|
35
|
+
def method_missing(name, *args, &blk)
|
36
|
+
# Accessor for attributes
|
37
|
+
if args.empty? && blk.nil? && @attrs.has_key?(name)
|
38
|
+
@attrs[name]
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def respond_to?(method_name, include_private = false)
|
45
|
+
@attrs.has_key?(name) || super
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def to_key(string)
|
51
|
+
string.is_a?(Symbol) ? string : underscore(string).to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
def underscore(string)
|
55
|
+
string.gsub(/::/, '/').
|
56
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
57
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
58
|
+
gsub(/\s/, '_').tr("-", "_").downcase
|
59
|
+
end
|
60
|
+
|
61
|
+
def define_accessor(name)
|
62
|
+
self.class.send(:define_method, name) { @attrs[name] }
|
63
|
+
end
|
64
|
+
|
65
|
+
end # Record
|
66
|
+
|
67
|
+
end # Airtable
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Airtable
|
2
|
+
|
3
|
+
# Contains records and the offset after a record query
|
4
|
+
class RecordSet < SimpleDelegator
|
5
|
+
|
6
|
+
attr_reader :records, :offset
|
7
|
+
|
8
|
+
# results = { "records" => [{ ... }], "offset" => "abc5643" }
|
9
|
+
# response from records api
|
10
|
+
def initialize(results)
|
11
|
+
# Parse records
|
12
|
+
@records = results && results["records"] ?
|
13
|
+
results["records"].map { |r| Record.new(r["fields"].merge("id" => r["id"])) } : []
|
14
|
+
# Store offset
|
15
|
+
@offset = results["offset"]
|
16
|
+
# Assign delegation object
|
17
|
+
__setobj__(@records)
|
18
|
+
end
|
19
|
+
|
20
|
+
end # Record
|
21
|
+
|
22
|
+
end # Airtable
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Airtable
|
2
|
+
# Base class for authorized resources sending network requests
|
3
|
+
class Resource
|
4
|
+
include HTTParty
|
5
|
+
base_uri 'https://api.airtable.com/v0/'
|
6
|
+
# debug_output $stdout
|
7
|
+
|
8
|
+
attr_reader :api_key, :app_token, :worksheet_name
|
9
|
+
|
10
|
+
def initialize(api_key, app_token, worksheet_name)
|
11
|
+
@api_key = api_key
|
12
|
+
@app_token = app_token
|
13
|
+
@worksheet_name = worksheet_name
|
14
|
+
self.class.headers({'Authorization' => "Bearer #{@api_key}"})
|
15
|
+
end
|
16
|
+
end # AuthorizedResource
|
17
|
+
end # Airtable
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Airtable
|
2
|
+
|
3
|
+
class Table < Resource
|
4
|
+
# Maximum results per request
|
5
|
+
LIMIT_MAX = 100
|
6
|
+
|
7
|
+
# Fetch all records iterating through offsets until retrieving the entire collection
|
8
|
+
# all(:sort => ["Name", :desc])
|
9
|
+
def all(options={})
|
10
|
+
offset = nil
|
11
|
+
results = []
|
12
|
+
begin
|
13
|
+
options.merge!(:limit => LIMIT_MAX, :offset => offset)
|
14
|
+
response = records(options)
|
15
|
+
results += response.records
|
16
|
+
offset = response.offset
|
17
|
+
end until offset.nil? || offset.empty? || results.empty?
|
18
|
+
results
|
19
|
+
end
|
20
|
+
|
21
|
+
# Fetch records from the sheet given the list options
|
22
|
+
# Options: limit = 100, offset = "as345g", sort = ["Name", "asc"]
|
23
|
+
# records(:sort => ["Name", :desc], :limit => 50, :offset => "as345g")
|
24
|
+
def records(options={})
|
25
|
+
options["sortField"], options["sortDirection"] = options.delete(:sort) if options[:sort]
|
26
|
+
results = self.class.get(worksheet_url, query: options).parsed_response
|
27
|
+
RecordSet.new(results)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns record based given row id
|
31
|
+
def find(id)
|
32
|
+
result = self.class.get(worksheet_url + "/" + id).parsed_response
|
33
|
+
Record.new(result["fields"].merge("id" => result["id"])) if result.present? && result["id"]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Creates a record by posting to airtable
|
37
|
+
def create(record)
|
38
|
+
result = self.class.post(worksheet_url,
|
39
|
+
:body => { "fields" => record.fields }.to_json,
|
40
|
+
:headers => { "Content-type" => "application/json" }).parsed_response
|
41
|
+
if result.present? && result["id"].present?
|
42
|
+
record.id = result["id"]
|
43
|
+
record
|
44
|
+
else # failed
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Replaces record in airtable based on id
|
50
|
+
def update(record)
|
51
|
+
result = self.class.put(worksheet_url + "/" + id,
|
52
|
+
:body => { "fields" => record.fields }.to_json,
|
53
|
+
:headers => { "Content-type" => "application/json" }).parsed_response
|
54
|
+
if result.present? && result["id"].present?
|
55
|
+
record
|
56
|
+
else # failed
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Deletes record in table based on id
|
62
|
+
def destroy(id)
|
63
|
+
self.class.delete(worksheet_url + "/" + id).parsed_response
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def worksheet_url
|
69
|
+
"/#{app_token}/#{URI.encode(worksheet_name)}"
|
70
|
+
end
|
71
|
+
end # Table
|
72
|
+
|
73
|
+
end # Airtable
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Airtable do
|
4
|
+
before do
|
5
|
+
@client_key = "12345"
|
6
|
+
@app_key = "appXXV84Qu"
|
7
|
+
@sheet_name = "Test"
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "with Airtable" do
|
11
|
+
it "should allow client to be created" do
|
12
|
+
@client = Airtable::Client.new(@client_key)
|
13
|
+
assert_kind_of Airtable::Client, @client
|
14
|
+
@table = @client.table(@app_key, @sheet_name)
|
15
|
+
assert_kind_of Airtable::Table, @table
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should fetch record set" do
|
19
|
+
stub_airtable_response("https://api.airtable.com/v0/#{@app_key}/#{@sheet_name}", { "records" => [], "offset" => "abcde" })
|
20
|
+
@table = Airtable::Client.new(@client_key).table(@app_key, @sheet_name)
|
21
|
+
@records = @table.records
|
22
|
+
assert_equal "abcde", @records.offset
|
23
|
+
end
|
24
|
+
end # describe Airtable
|
25
|
+
end # Airtable
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'airtable'
|
2
|
+
require 'fakeweb'
|
3
|
+
require 'minitest/pride'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
FakeWeb.allow_net_connect = false
|
7
|
+
|
8
|
+
def stub_airtable_response(url, response)
|
9
|
+
FakeWeb.register_uri(:get, url, :body => response.to_json, :content_type => "application/json")
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: airtable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nathan Esquenazi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.6.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.6.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fakeweb
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
description: Easily connect to airtable data using ruby with access to all of the
|
84
|
+
airtable features.
|
85
|
+
email:
|
86
|
+
- nesquena@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- airtable.gemspec
|
97
|
+
- lib/airtable.rb
|
98
|
+
- lib/airtable/client.rb
|
99
|
+
- lib/airtable/record.rb
|
100
|
+
- lib/airtable/record_set.rb
|
101
|
+
- lib/airtable/resource.rb
|
102
|
+
- lib/airtable/table.rb
|
103
|
+
- lib/airtable/version.rb
|
104
|
+
- test/airtable_test.rb
|
105
|
+
- test/test_helper.rb
|
106
|
+
homepage: https://github.com/nesquena/airtable-ruby
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.0.6
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Easily connect to airtable data using ruby
|
130
|
+
test_files:
|
131
|
+
- test/airtable_test.rb
|
132
|
+
- test/test_helper.rb
|