Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New release #27

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ tmp
*.a
mkmf.log
.DS_Store
.idea
.env.docker
*.log
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM ruby:2.4.2

ENV LIB_HOME /home/lib

WORKDIR $LIB_HOME
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ source 'https://rubygems.org'

# Specify your gem's dependencies in airtable.gemspec
gemspec

gem 'pry'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is pry needed here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its for development purposes. Really helpful. Gemfile is not pushed to the gem file so used only for development environment of gem file only.

20 changes: 15 additions & 5 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
require "bundler/gem_tasks"
require 'rake/testtask'
require 'bundler'
Bundler.setup
Bundler::GemHelper.install_tasks

Rake::TestTask.new do |t|
t.libs << 'test'
t.pattern = "test/*_test.rb"
require 'rspec/core/rake_task'

desc 'Run all tests'
RSpec::Core::RakeTask.new(:spec) do |t|
t.ruby_opts = %w[-w]
end

desc 'Run RuboCop on the lib directory'
task :rubocop do
sh 'bundle exec rubocop lib'
end

task default: %i[spec rubocop]
41 changes: 21 additions & 20 deletions airtable.gemspec
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'airtable/version'

Gem::Specification.new do |spec|
spec.name = "airtable"
spec.version = Airtable::VERSION
spec.authors = ["Nathan Esquenazi", "Alexander Sorokin"]
spec.email = ["[email protected]", "[email protected]"]
spec.summary = %q{Easily connect to airtable data using ruby}
spec.description = %q{Easily connect to airtable data using ruby with access to all of the airtable features.}
spec.homepage = "https://github.com/nesquena/airtable-ruby"
spec.license = "MIT"
spec.name = 'airtable'
spec.version = Airtable::VERSION
spec.authors = ['Nathan Esquenazi', 'Alexander Sorokin']
spec.email = ['[email protected]', '[email protected]']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to put your name here. Nathan wrote original version, so we'll put his name into Readme/Acknowledgements.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@syrnick thx!. Will do it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

spec.summary = 'Easily connect to airtable data using ruby'
spec.description = 'Easily connect to airtable data using ruby with access to all of the airtable features.'
spec.homepage = 'https://github.com/nesquena/airtable-ruby'
spec.license = 'MIT'

spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.files = `git ls-files -z`.split("\x0")
spec.bindir = 'exe'
spec.executables = `git ls-files -- exe/*`.split("\n").map {|f| File.basename(f)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is exe/ better than bin/ ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 2.0.0'

spec.add_dependency "httparty", "~> 0.14.0"
spec.add_dependency "activesupport", ">= 3.0"

spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "rake"
spec.add_development_dependency "minitest", "~> 5.6.0"
spec.add_development_dependency "webmock", "~> 2.1.0"
spec.add_development_dependency 'bundler', '~> 1.6'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec', '~> 3.7'
spec.add_development_dependency 'rubocop', '~> 0.51'
spec.add_development_dependency 'simplecov', '~> 0.15'
spec.add_development_dependency 'vcr', '~> 4.0'
spec.add_development_dependency 'webmock', '~> 3.1'
end
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '2.1'
volumes:
app-gems:
driver: local
services:
lib:
build:
context: .
dockerfile: Dockerfile
env_file:
- .env.docker
volumes:
- app-gems:/usr/local/bundle
- .:/home/lib

5 changes: 5 additions & 0 deletions exe/airtable
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
$stderr.sync = true
require 'airtable'
require 'airtable/cli'
::Airtable::CLI.start
48 changes: 39 additions & 9 deletions lib/airtable.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
require 'httparty'
require 'delegate'
require 'active_support/core_ext/hash'

require 'airtable/version'
require 'airtable/resource'
require 'airtable/record'
require 'airtable/record_set'
require 'airtable/table'
require 'logger'

# Airtable wrapper library
module Airtable
class << self
DEFAULT_URL = 'https://api.airtable.com/v0'.freeze
attr_writer :log_path

def debug?
!ENV['DEBUG'].nil?
end

def log_path
@log_path ||= 'airtable.log'
end

def logger
@logger ||= ::Logger.new(@log_path)
end

def server_url
@server_url ||= ENV.fetch('AIRTABLE_ENDPOINT_URL') { DEFAULT_URL }
end

def reset!
@log_path = nil
@logger = nil
@server_url = nil
end
end
end

require 'airtable/response'
require 'airtable/request'
require 'airtable/entity'
require 'airtable/client'
require 'airtable/error'

# require 'airtable/resource'
# require 'airtable/record'
# require 'airtable/record_set'
83 changes: 83 additions & 0 deletions lib/airtable/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require 'optparse'
require 'airtable'

# * Build a command-line tool to allow simple command-line interactions:
# Interactions:
# * retrieve record JSON by record ID and table ID
# * retrieve all values for a single field ID or name from a table (allow adding viewId and filterByFormula)
# * update single record field

module Airtable
class CLI
class << self
SUPPORTED_OPERATIONS = [
"record",
"values",
"update_record_field"
]

def start
run(ARGV, $stderr, $stdout)
end

def run(args, err=$stderr, out=$stdout)
trap_interrupt
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: airtable [options]"
parser.separator ""
parser.separator "Common options:"
parser.on("-kKEY", "--api_key=KEY", "Airtable API key") do |key|
options[:api_key] = key
end
parser.on("-oOPERATION", "--operation OPERATION", "Operation what need to make") do |operation|
options[:operation] = operation
end
parser.on("-tNAME", "--table NAME", "Table Name") do |table|
options[:table_name] = table
end
parser.on("-bBASE_ID", "--base BASE_ID", "Base ID") do |base_id|
options[:base_id] = base_id
end
parser.on("-rRECORD_ID", "--record RECORD_ID", "Record ID") do |record_id|
options[:record_id] = record_id
end
parser.on_tail("-h", "--help", "Show this message") do
puts parser
exit
end
parser.on_tail("--version", "Show version") do
puts ::Airtable::Version
exit
end
parser.separator ""
parser.separator "Supported Operations"
SUPPORTED_OPERATIONS.each do |operation|
parser.separator "\t* #{operation}"
end
parser.separator ""
parser.parse!(args)
if options.empty?
puts parser
else
case options.delete(:operation)
when "record"
print_record(options)
else
puts parser
end
end
end
end

def print_record(options)
record = ::Airtable::Client.new(options[:api_key]).base(options[:base_id]).table(options[:table_name]).find(options[:record_id])
puts ({:id => record.id, :fields => record.fields, createdTime: record.created_at}).to_json
end

def trap_interrupt
trap('INT') {exit!(1)}
end
end
end
end
37 changes: 22 additions & 15 deletions lib/airtable/client.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# Allows access to data on airtable
#
# Fetch all records from table:
#
# client = Airtable::Client.new("keyPtVG4L4sVudsCx5W")
# client.table("appXXV84QuCy2BPgLk", "Sheet Name").all
#

module Airtable
# Main client to Airtable
class Client
def initialize(api_key)
@api_key = api_key
# @return [String] Airtable API Key
attr_reader :api_key

# Initialize new Airtable client
# @param api_key [String] API Key for access Airtable
# @return [::Airtable::Client] Airtable client object
def initialize(api_key = nil)
@api_key = api_key || ENV['AIRTABLE_KEY']
raise Airtable::MissingApiKeyError if @api_key.nil? || @api_key.empty?
end

# table("appXXV84QuCy2BPgLk", "Sheet Name")
def table(app_token, worksheet_name)
Table.new(@api_key, app_token, worksheet_name)
# Get the Base Airtable Entity by id
# @param id [String] Id of Base on Airtable
# @return [::Airtable::Entity::Base] Airtable Base entity object
def base(id)
::Airtable::Entity::Base.new(self, id)
end
end # Client
end # Airtable

# table("appXXV84QuCy2BPgLk", "Sheet Name")
# def table(app_token, worksheet_name)
# Table.new(@api_key, app_token, worksheet_name)
# end
end
end
8 changes: 8 additions & 0 deletions lib/airtable/entity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Airtable
module Entity
end
end

require 'airtable/entity/base'
require 'airtable/entity/table'
require 'airtable/entity/record'
29 changes: 29 additions & 0 deletions lib/airtable/entity/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Airtable
module Entity
# Airtable Base entity
class Base
def initialize(client, id)
@id = id
@client = client
end

def table(name)
::Airtable::Entity::Table.new(self, name)
end

def __make_request__(method, path, data)
url = [::Airtable.server_url, @id, path].join('/')
resp = ::Airtable::Request.new(url, data, @client.api_key).request(method)
if resp.success?
resp.result
else
raise_correct_error_for(resp)
end
end

def raise_correct_error_for(resp)
;
end
end
end
end
Loading