Skip to content

Commit

Permalink
initial extraction and gemification
Browse files Browse the repository at this point in the history
  • Loading branch information
ian committed Jan 24, 2013
0 parents commit b841dd5
Show file tree
Hide file tree
Showing 20 changed files with 780 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
.DS_Store
.rspec
pkg
vendor
8 changes: 8 additions & 0 deletions Gemfile
@@ -0,0 +1,8 @@
source :rubygems

gem 'rake'
gemspec

group :test do
gem 'rspec'
end
45 changes: 45 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,45 @@
PATH
remote: .
specs:
crowdtilt (0.0.1)
activemodel
faraday
faraday_middleware
json

GEM
remote: http://rubygems.org/
specs:
activemodel (3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
activesupport (3.2.11)
i18n (~> 0.6)
multi_json (~> 1.0)
builder (3.0.4)
diff-lcs (1.1.3)
faraday (0.8.4)
multipart-post (~> 1.1)
faraday_middleware (0.8.8)
faraday (>= 0.7.4, < 0.9)
i18n (0.6.1)
json (1.7.6)
multi_json (1.5.0)
multipart-post (1.1.5)
rake (10.0.3)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rspec-core (2.12.2)
rspec-expectations (2.12.1)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.1)

PLATFORMS
ruby

DEPENDENCIES
crowdtilt!
rake
rspec
97 changes: 97 additions & 0 deletions README.md
@@ -0,0 +1,97 @@
# Crowdtilt Ruby Library

## Introduction

This is a very rudimentary shot at implementing the Crowdtilt API. Feel free to add support for missing ones.

While continued development happens on the Crowdtilt API, I opted to forego specs conforming to the API schema since determining when changes happened were easier if the HTTP call blew up. This should really be fixed in the future once the schema solidifies.

## Usage

First start by configuring Crowdtilt:

```
Crowdtilt.configure do
key "KEY"
secret "SECRET"
env "production" # not setting this will default to "development"
end
```

If you're using Rails:

```
Crowdtilt.configure do
key "KEY"
secret "SECRET"
env Rails.env
end
```

You should be good to go. Example usage:

```
# Create a user
u = Crowdtilt::User.new(:name => 'Ian', :email => 'ian@example.org')
u.persisted? #=> false
u.save
u.persisted? #=> true
# List all users
Crowdtilt::User.all
#=> [Crowdtilt::User,...]
c = u.campaigns.create "title" => "Foo",
"description" => "Bar",
"expiration_date" => 2.weeks.from_now,
"tilt_amount" => 1000
```

## Issues

Bound to be some issues since there's barely any specs. Feel free to submit an issue.

## Endpoints Supported

[] POST /users
[] POST /users/:id/verification
[ ] GET /users/authentication?email=x&password=y
[] GET /users/:id
[] GET /users
[] PUT /users/:id
[] GET /users/:id/campaigns
[e] GET /users/:id/campaigns/:id
[ ] GET /users/:id/paid_campaigns
[] POST /users/:id/cards
[] GET /users/:id/cards/:id
[] GET /users/:id/cards
[] PUT /users/:id/cards/:id
[] DELETE /users/:id/cards/:id
[] POST /users/:id/banks
[] GET /users/:id/banks/:id
[] GET /users/:id/banks
[] PUT /users/:id/banks/:id
[] DELETE /users/:id/banks/:id
[] GET /users/:id/payments
[] POST /campaigns
[] GET /campaigns/:id
[] GET /campaigns
[] PUT /campaigns/:id
[] POST /campaigns/:id/payments
[] GET /campaigns/:id/payments/:id
[] PUT /campaigns/:id/payments/:id
[] GET /campaigns/:id/payments
[ ] GET /campaigns/:id/rejected_payments
[ ] POST /campaigns/:id/payments/:id/refund
[ ] GET /campaigns/:id/settlements
[ ] GET /campaigns/:id/settlements/:id
[ ] POST /campaigns/:id/settlements/:id/bank
[ ] POST /campaigns/:id/comments
[ ] GET /campaigns/:id/comments
[ ] GET /campaigns/:id/comments/:id
[ ] PUT /campaigns/:id/comments/:id
[ ] DELETE /campaigns/:id/comments/:id

## Todo

* The association-like chaining executes the all http call before doing the find, or other method calls. Lazy eval the associated array so we don't do 2 calls.
15 changes: 15 additions & 0 deletions Rakefile
@@ -0,0 +1,15 @@
require 'rspec/core/rake_task'
require './lib/crowdtilt/version'

RSpec::Core::RakeTask.new(:spec)

task :default => :spec

task :build do
system "gem build crowdtilt.gemspec"
end

task :release => :build do
`fury push crowdtilt-#{Zaarly::Geolocation::VERSION}.gem`
`rm crowdtilt-#{Zaarly::Geolocation::VERSION}.gem`
end
26 changes: 26 additions & 0 deletions crowdtilt.gemspec
@@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "crowdtilt/version"

Gem::Specification.new do |s|
s.name = "crowdtilt"
s.version = Crowdtilt::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Ian Hunter"]
s.email = ["ianhunter@gmail.com"]
s.homepage = "https://github.com/ihunter/crowdtilt"
s.summary = "Crowdtilt API library"
s.description = "Allows access to the Crowdtilt public API"

s.rubyforge_project = s.name

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_dependency 'activemodel'
s.add_dependency 'faraday'
s.add_dependency 'faraday_middleware'
s.add_dependency 'json'
end
74 changes: 74 additions & 0 deletions lib/crowdtilt.rb
@@ -0,0 +1,74 @@
require 'active_model'
require 'faraday'
require 'faraday_middleware'
require 'json'

require File.dirname(__FILE__) + "/crowdtilt/config"
require File.dirname(__FILE__) + "/crowdtilt/model"
require File.dirname(__FILE__) + "/crowdtilt/bank"
require File.dirname(__FILE__) + "/crowdtilt/campaign"
require File.dirname(__FILE__) + "/crowdtilt/card"
require File.dirname(__FILE__) + "/crowdtilt/user"

module Crowdtilt

class << self
def configure(&block)
@config = Crowdtilt::Config.new(&block)
end

def config
if @config.nil?
raise "Crowdtilt not initialize, please configure using Crowdtilt.configure"
end
@config
end

def request(method,*args)
conn = Faraday.new(:url => config.url) do |faraday|
# faraday.response :logger
faraday.request :json
faraday.response :json, :content_type => /\bjson$/
faraday.use :instrumentation

faraday.adapter Faraday.default_adapter
end
conn.basic_auth(config.key, config.secret)
conn.headers.update({'Content-Type' => 'application/json'})

res = conn.send method.to_sym, *args

puts
puts "#{method.to_s.upcase} #{args[0]} #{args[1]}"
puts "Response #{res.status}"
puts res.body if res.body
puts

case res.status
when 400...499
raise res.body['error']
when 500...599
# prob want to handle this differently
raise res.body['error']
else
res
end
end

def get(path)
request :get, "/v1#{path}"
end

def post(path, params={})
request :post, "/v1#{path}", params
end

def put(path, params={})
request :put, "/v1#{path}", params
end

def delete(path)
request :delete, "/v1#{path}"
end
end
end
47 changes: 47 additions & 0 deletions lib/crowdtilt/README.md
@@ -0,0 +1,47 @@
= Endpoints
[] POST /users
[] POST /users/:id/verification
[ ] GET /users/authentication?email=x&password=y
[] GET /users/:id
[] GET /users
[] PUT /users/:id
[] GET /users/:id/campaigns
[e] GET /users/:id/campaigns/:id
This returns 200 status when it's actually 404
[ ] GET /users/:id/paid_campaigns
[] POST /users/:id/cards
[] GET /users/:id/cards/:id
[] GET /users/:id/cards
[] PUT /users/:id/cards/:id
[] DELETE /users/:id/cards/:id
[] POST /users/:id/banks
[] GET /users/:id/banks/:id
[] GET /users/:id/banks
[] PUT /users/:id/banks/:id
[] DELETE /users/:id/banks/:id
[] GET /users/:id/payments
[] POST /campaigns
[] GET /campaigns/:id
[] GET /campaigns
[] PUT /campaigns/:id
[] POST /campaigns/:id/payments
This returns campaign_id, user_id, card_id, not object hashes
[] GET /campaigns/:id/payments/:id
[] PUT /campaigns/:id/payments/:id
[] GET /campaigns/:id/payments
[ ] GET /campaigns/:id/rejected_payments
[ ] POST /campaigns/:id/payments/:id/refund
[ ] GET /campaigns/:id/settlements
[ ] GET /campaigns/:id/settlements/:id
[ ] POST /campaigns/:id/settlements/:id/bank
[ ] POST /campaigns/:id/comments
[ ] GET /campaigns/:id/comments
[ ] GET /campaigns/:id/comments/:id
[ ] PUT /campaigns/:id/comments/:id
[ ] DELETE /campaigns/:id/comments/:id

= Questions
* Is there no delete user endpoint?

= Todo
* The association-like chaining executes the all http call before doing the find, or other method calls. Lazy eval the associated array so we don't do 2 calls.
41 changes: 41 additions & 0 deletions lib/crowdtilt/bank.rb
@@ -0,0 +1,41 @@
module Crowdtilt
class Bank < Model
attr_accessor :account_number, :name, :bank_code, :account_number_last_four,
:bank_code_last_four, :id, :is_valid, :metadata, :name, :user,
:user_uri, :uri

uri_prefix '/users/#{user.id}/banks'

coerce :user => 'Crowdtilt::User'

def create_json
{ "bank" => { "account_number" => account_number,
"name" => name,
"bank_code" => bank_code } }
end

def update_json
{ "bank" => { "metadata" => metadata } }
end
end

class BanksArray < Array
attr_reader :user
def initialize(user, banks)
super banks
@user = user
end

def find(id)
Crowdtilt::Bank.new Crowdtilt.get("/users/#{user.id}/banks/"+id).body['bank'].merge(:user => user)
end

def build(params)
Crowdtilt::Bank.new params.merge(:user => user.as_json)
end

def create(params)
build(params).save
end
end
end

0 comments on commit b841dd5

Please sign in to comment.