lapse 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.travis.yml +9 -0
- data/Contributing.markdown +19 -0
- data/Gemfile +22 -0
- data/LICENSE +22 -0
- data/Rakefile +22 -0
- data/Readme.markdown +64 -0
- data/lapse.gemspec +24 -0
- data/lib/lapse/client/configuration.rb +24 -0
- data/lib/lapse/client.rb +96 -0
- data/lib/lapse/error.rb +51 -0
- data/lib/lapse/response.rb +3 -0
- data/lib/lapse/transport/http.rb +171 -0
- data/lib/lapse/transport.rb +11 -0
- data/lib/lapse/version.rb +4 -0
- data/lib/lapse.rb +26 -0
- data/test/lapse/client_test.rb +53 -0
- data/test/lapse/transport/http_test.rb +8 -0
- data/test/lapse_test.rb +11 -0
- data/test/support/client_macros.rb +9 -0
- data/test/test_helper.rb +20 -0
- metadata +112 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
## Submitting a Pull Request
|
2
|
+
|
3
|
+
1. [Fork the repository.][fork]
|
4
|
+
2. [Create a topic branch.][branch]
|
5
|
+
3. Add tests for your unimplemented feature or bug fix.
|
6
|
+
4. Run `bundle exec rake`. If your tests pass, return to step 3.
|
7
|
+
5. Implement your feature or bug fix.
|
8
|
+
6. Run `bundle exec rake`. If your tests fail, return to step 5.
|
9
|
+
7. Run `open coverage/index.html`. If your changes are not completely covered
|
10
|
+
by your tests, return to step 3.
|
11
|
+
8. Add documentation for your feature or bug fix.
|
12
|
+
9. Run `bundle exec rake doc`. If your changes are not 100% documented, go
|
13
|
+
back to step 8.
|
14
|
+
10. Add, commit, and push your changes.
|
15
|
+
11. [Submit a pull request.][pr]
|
16
|
+
|
17
|
+
[fork]: http://help.github.com/fork-a-repo/
|
18
|
+
[branch]: http://learn.github.com/p/branching.html
|
19
|
+
[pr]: http://help.github.com/send-pull-requests/
|
data/Gemfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Gem dependencies
|
4
|
+
puts gemspec
|
5
|
+
|
6
|
+
gem 'rake', :group => [:development, :test]
|
7
|
+
|
8
|
+
# Development dependencies
|
9
|
+
group :development do
|
10
|
+
gem 'yard'
|
11
|
+
gem 'redcarpet', :platform => 'ruby'
|
12
|
+
end
|
13
|
+
|
14
|
+
# Testing dependencies
|
15
|
+
group :test do
|
16
|
+
gem 'minitest'
|
17
|
+
gem 'minitest-wscolor' if RUBY_VERSION >= '1.9.3'
|
18
|
+
gem 'webmock', :require => 'webmock/minitest'
|
19
|
+
gem 'mocha', :require => 'mocha/setup'
|
20
|
+
gem 'simplecov', :require => false
|
21
|
+
gem 'hashie' #unknown why this is required for certain dev envs to work (ahem, adam)
|
22
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Seesaw Decisions Corporation
|
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/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.libs << 'test'
|
7
|
+
t.pattern = 'test/**/*_test.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'yard'
|
14
|
+
YARD::Rake::YardocTask.new(:doc) do |task|
|
15
|
+
task.files = ['Readme.markdown', 'LICENSE', 'lib/**/*.rb']
|
16
|
+
task.options = [
|
17
|
+
'--output-dir', 'doc',
|
18
|
+
'--markup', 'markdown',
|
19
|
+
]
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
end
|
data/Readme.markdown
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Lapse
|
2
|
+
|
3
|
+
Lapse, as in teeter-Lapse, let's you work with the Seesaw API in Ruby.
|
4
|
+
|
5
|
+
All networking is done with Net::HTTP so you don't have to worry about version conflicts with whatever networking library you may be using.
|
6
|
+
|
7
|
+
Read the [documentation](http://rubydoc.info/github/seesawco/Lapse-rb/master/frames) online.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
``` ruby
|
14
|
+
gem 'Lapse'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
``` shell
|
20
|
+
$ bundle
|
21
|
+
```
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
``` shell
|
26
|
+
$ gem install Lapse
|
27
|
+
```
|
28
|
+
|
29
|
+
## Configuration
|
30
|
+
|
31
|
+
Should you wish to configure the client in an initializer, you can do the following:
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
Lapse::Client.configure do |client|
|
35
|
+
client.api_host = "some.api-host.com"
|
36
|
+
client.api_scheme = "http"
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
A client takes an optional access token when you initialize it. If you don't provide one, you can still use it to make unauthenticated requests. If you do provide one, it will set the authorization header for all requests.
|
43
|
+
|
44
|
+
``` ruby
|
45
|
+
> client = Lapse::Client.new(access_token: 'your_access_token')
|
46
|
+
> current_user = client.me
|
47
|
+
> current_user.username
|
48
|
+
#=> "soffes"
|
49
|
+
> decision = client.decision(5, 3276)
|
50
|
+
#=> "Which lamp for the new apartment?"
|
51
|
+
> slug = client.slug('d/3I0n0g')
|
52
|
+
> slug.decision.user.username
|
53
|
+
#=> "soffes"
|
54
|
+
```
|
55
|
+
|
56
|
+
## Supported Ruby Versions
|
57
|
+
|
58
|
+
Lapse is tested under 1.8.7, 1.9.2, 1.9.3, 2.0.0, JRuby 1.7.2 (1.9 mode), and Rubinius 2.0.0 (1.9 mode).
|
59
|
+
|
60
|
+
[![Build Status](https://travis-ci.org/seesawco/Lapse-rb.png?branch=master)](https://travis-ci.org/seesawco/Lapse-rb)
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
See the [contributing guide](Contributing.markdown).
|
data/lapse.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'lapse/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'lapse'
|
8
|
+
gem.version = Lapse::VERSION
|
9
|
+
gem.authors = ['Sam Soffes', 'Aaron Gotwalt', 'Adam Ryan']
|
10
|
+
gem.email = ['sam@soff.es', 'gotwalt@gmail.com', 'adam.g.ryan@gmail.com']
|
11
|
+
gem.description = 'Ruby gem for working with the Everlapse API.'
|
12
|
+
gem.summary = gem.description
|
13
|
+
gem.homepage = 'https://github.com/seesawco/lapse-rb'
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ['lib']
|
20
|
+
|
21
|
+
gem.required_ruby_version = '>= 1.8.7'
|
22
|
+
gem.add_dependency 'multi_json', '~> 1.6'
|
23
|
+
gem.add_dependency 'hashie', '~> 1.2.0'
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lapse
|
2
|
+
class Client
|
3
|
+
# Client methods for working with configuration.
|
4
|
+
module Configuration
|
5
|
+
# Get the configuration from the API.
|
6
|
+
#
|
7
|
+
# @return [Hashie::Mash] A hash of configuration data.
|
8
|
+
# @example
|
9
|
+
# Totter.configuration
|
10
|
+
def configuration
|
11
|
+
get('configuration').body
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get the featured timelines and users for Explore.
|
15
|
+
#
|
16
|
+
# @return [Hashie::Mash] A hash of timelines and users data.
|
17
|
+
# @example
|
18
|
+
# Totter.explore
|
19
|
+
def explore
|
20
|
+
get('explore').body
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/lapse/client.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'Lapse/transport'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Lapse
|
5
|
+
# API client for interacting with the Seesaw API
|
6
|
+
class Client
|
7
|
+
Dir[File.expand_path('../client/*.rb', __FILE__)].each { |f| require f }
|
8
|
+
|
9
|
+
include Configuration
|
10
|
+
|
11
|
+
attr_reader :access_token
|
12
|
+
attr_reader :api_scheme
|
13
|
+
attr_reader :api_host
|
14
|
+
attr_reader :api_version
|
15
|
+
attr_reader :transport
|
16
|
+
attr_reader :result_format
|
17
|
+
|
18
|
+
# Default parameters for the client
|
19
|
+
DEFAULTS = {
|
20
|
+
:api_scheme => 'https',
|
21
|
+
:api_host => 'everlapse.com',
|
22
|
+
:api_version => '1',
|
23
|
+
:result_format => :mashie,
|
24
|
+
:transport => :http
|
25
|
+
}
|
26
|
+
|
27
|
+
# The current configuration parameters for all clients
|
28
|
+
def self.options
|
29
|
+
@options ||= Hashie::Mash.new(DEFAULTS.dup)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets the current configuration parameters for all clients
|
33
|
+
def self.options=(val)
|
34
|
+
@options = val
|
35
|
+
end
|
36
|
+
|
37
|
+
# Allows the setting of configuration parameters in a configure block.
|
38
|
+
def self.configure
|
39
|
+
yield options
|
40
|
+
end
|
41
|
+
|
42
|
+
# Initialize a new client.
|
43
|
+
#
|
44
|
+
# @param options [Hash] optionally specify `:access_token`, `:api_scheme`, `:api_host`, ':api_url', `:api_version`, `:client_token`, or `:transport`.
|
45
|
+
def initialize(options = {})
|
46
|
+
options = { :access_token => options } if options.is_a? String
|
47
|
+
options = self.class.options.merge(options)
|
48
|
+
|
49
|
+
# Parse `api_url` option
|
50
|
+
if url = options.delete(:api_url)
|
51
|
+
uri = URI.parse(url)
|
52
|
+
options[:api_scheme] = uri.scheme
|
53
|
+
options[:api_host] = uri.host + (uri.port != 80 && uri.port != 443 ? ":#{uri.port}" : '')
|
54
|
+
end
|
55
|
+
|
56
|
+
@access_token = options[:access_token] if options[:access_token]
|
57
|
+
@api_scheme = options[:api_scheme]
|
58
|
+
@api_host = options[:api_host]
|
59
|
+
@api_version = options[:api_version]
|
60
|
+
@client_token = options[:client_token] if options[:client_token]
|
61
|
+
@transport = options[:transport]
|
62
|
+
@result_format = options[:result_format]
|
63
|
+
|
64
|
+
# Include transport
|
65
|
+
transport_module = Lapse::Transport::TRANSPORT_MAP[@transport]
|
66
|
+
raise 'Invalid transport' unless transport_module
|
67
|
+
self.extend transport_module
|
68
|
+
end
|
69
|
+
|
70
|
+
# API base URL.
|
71
|
+
#
|
72
|
+
# @return [String] API base URL
|
73
|
+
def base_url
|
74
|
+
"#{@api_scheme}://#{@api_host}/v#{@api_version}/"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Is the client has an access token.
|
78
|
+
#
|
79
|
+
# @return [Boolean] true if it is using one and false if it is not
|
80
|
+
def authenticated?
|
81
|
+
@access_token != nil and @access_token.length > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
# Is the client using SSL.
|
85
|
+
#
|
86
|
+
# @return [Boolean] true if it is using SSL and false if it is not
|
87
|
+
def ssl?
|
88
|
+
@api_scheme == 'https'
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns the current status of HTTP stubbing
|
92
|
+
def self.stubbed?
|
93
|
+
@@stubbed
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/lapse/error.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Lapse
|
2
|
+
# Standard Lapse error
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# Raised when Lapse returns a 400 HTTP status code
|
6
|
+
class BadRequest < Error; end
|
7
|
+
|
8
|
+
# Raised when Lapse returns a 401 HTTP status code
|
9
|
+
class Unauthorized < Error; end
|
10
|
+
|
11
|
+
# Raised when Lapse returns a 403 HTTP status code
|
12
|
+
class Forbidden < Error; end
|
13
|
+
|
14
|
+
# Raised when Lapse returns a 404 HTTP status code
|
15
|
+
class NotFound < Error; end
|
16
|
+
|
17
|
+
# Raised when Lapse returns a 406 HTTP status code
|
18
|
+
class NotAcceptable < Error; end
|
19
|
+
|
20
|
+
# Raised when Lapse returns a 422 HTTP status code
|
21
|
+
class UnprocessableEntity < Error; end
|
22
|
+
|
23
|
+
# Raised when Lapse returns a 500 HTTP status code
|
24
|
+
class InternalServerError < Error; end
|
25
|
+
|
26
|
+
# Raised when Lapse returns a 501 HTTP status code
|
27
|
+
class NotImplemented < Error; end
|
28
|
+
|
29
|
+
# Raised when Lapse returns a 502 HTTP status code
|
30
|
+
class BadGateway < Error; end
|
31
|
+
|
32
|
+
# Raised when Lapse returns a 503 HTTP status code
|
33
|
+
class ServiceUnavailable < Error; end
|
34
|
+
|
35
|
+
# Raised when a unique ID is required but not provided
|
36
|
+
class UniqueIDRequired < Error; end
|
37
|
+
|
38
|
+
# Status code to exception map
|
39
|
+
ERROR_MAP = {
|
40
|
+
400 => Lapse::BadRequest,
|
41
|
+
401 => Lapse::Unauthorized,
|
42
|
+
403 => Lapse::Forbidden,
|
43
|
+
404 => Lapse::NotFound,
|
44
|
+
406 => Lapse::NotAcceptable,
|
45
|
+
422 => Lapse::UnprocessableEntity,
|
46
|
+
500 => Lapse::InternalServerError,
|
47
|
+
501 => Lapse::NotImplemented,
|
48
|
+
502 => Lapse::BadGateway,
|
49
|
+
503 => Lapse::ServiceUnavailable
|
50
|
+
}
|
51
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
|
2
|
+
module Lapse
|
3
|
+
module Transport
|
4
|
+
# Default HTTP API transport adapter
|
5
|
+
module HTTP
|
6
|
+
require 'net/http'
|
7
|
+
require 'net/https'
|
8
|
+
require 'uri'
|
9
|
+
require 'multi_json'
|
10
|
+
require 'hashie'
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def http
|
15
|
+
return @http if @http
|
16
|
+
|
17
|
+
uri = URI.parse(self.base_url)
|
18
|
+
@http = Net::HTTP.new(uri.host, uri.port)
|
19
|
+
@http.use_ssl = self.ssl?
|
20
|
+
@http
|
21
|
+
end
|
22
|
+
|
23
|
+
def request(method, path, params = nil)
|
24
|
+
uri = URI.parse("#{self.base_url}#{path}")
|
25
|
+
|
26
|
+
# if the request requires parameters in the query string, merge them in
|
27
|
+
if params and !can_post_data?(method)
|
28
|
+
query_values = uri.query ? URI.decode_www_form(uri.query).inject({}) {|h,(k,v)| h[k]=v; h} : {}
|
29
|
+
uri.query = to_url_params((query_values || {}).merge(params))
|
30
|
+
end
|
31
|
+
|
32
|
+
# Build request
|
33
|
+
request = build_request(method, uri)
|
34
|
+
|
35
|
+
# Add headers
|
36
|
+
request['Authorization'] = "Bearer #{self.access_token}" if authenticated?
|
37
|
+
request['X-Seesaw-Client-Token'] = @client_token if @client_token
|
38
|
+
request['Content-Type'] = 'application/json'
|
39
|
+
|
40
|
+
# Add params as JSON if they exist
|
41
|
+
request.body = MultiJson.dump(params) if can_post_data?(method) and params
|
42
|
+
|
43
|
+
# Request
|
44
|
+
response = http.request(request)
|
45
|
+
|
46
|
+
# Check for errors
|
47
|
+
handle_error(response)
|
48
|
+
|
49
|
+
# Return the raw response object
|
50
|
+
response
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_request(method, uri)
|
54
|
+
case method
|
55
|
+
when :get
|
56
|
+
Net::HTTP::Get.new(uri.request_uri)
|
57
|
+
when :post
|
58
|
+
Net::HTTP::Post.new(uri.request_uri)
|
59
|
+
when :put
|
60
|
+
Net::HTTP::Put.new(uri.request_uri)
|
61
|
+
when :delete
|
62
|
+
Net::HTTP::Delete.new(uri.request_uri)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_url_params(hash)
|
67
|
+
params = []
|
68
|
+
hash.each_pair do |key, value|
|
69
|
+
params << param_for(key, value).flatten
|
70
|
+
end
|
71
|
+
params.sort.join('&')
|
72
|
+
end
|
73
|
+
|
74
|
+
def param_for(key, value, parent = nil)
|
75
|
+
if value.is_a?(Hash)
|
76
|
+
params = []
|
77
|
+
value.each_pair do |value_key, value_value|
|
78
|
+
value_parent = parent ? parent + "[#{key}]" : key.to_s
|
79
|
+
params << param_for(value_key, value_value, value_parent)
|
80
|
+
end
|
81
|
+
params
|
82
|
+
else
|
83
|
+
["#{parent ? parent + "[#{key}]" : key.to_s}=#{CGI::escape(value.to_s)}"]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_error(response)
|
88
|
+
# Find error or return
|
89
|
+
return unless error = Lapse::ERROR_MAP[response.code.to_i]
|
90
|
+
|
91
|
+
# Try to add a useful message
|
92
|
+
message = nil
|
93
|
+
begin
|
94
|
+
message = MultiJson.load(response.body)['error_description']
|
95
|
+
rescue MultiJson::DecodeError => e
|
96
|
+
end
|
97
|
+
|
98
|
+
# Raise error
|
99
|
+
raise error.new(message)
|
100
|
+
end
|
101
|
+
|
102
|
+
def json_request(*args)
|
103
|
+
# Perform request, pass result format
|
104
|
+
Response.new(request(*args), result_format)
|
105
|
+
end
|
106
|
+
|
107
|
+
def boolean_from_response(*args)
|
108
|
+
response = request(*args)
|
109
|
+
(200..299).include? response.code.to_i
|
110
|
+
end
|
111
|
+
|
112
|
+
def can_post_data?(method)
|
113
|
+
[:post, :put].include?(method)
|
114
|
+
end
|
115
|
+
|
116
|
+
[:get, :post, :put, :delete].each do |method|
|
117
|
+
define_method method do |*args|
|
118
|
+
json_request(method, *args)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Response class responsible for deserializing API calls
|
123
|
+
# @attr [Object] body The parsed response
|
124
|
+
# @attr [Hash] headers HTTP headers returned as part of the response
|
125
|
+
class Response
|
126
|
+
attr_accessor :body, :headers
|
127
|
+
|
128
|
+
# Initializes a new result
|
129
|
+
#
|
130
|
+
# @param http_response [Net::HTTPResponse] the raw response to parse
|
131
|
+
def initialize(http_response, result_format = :mashie)
|
132
|
+
@result_format = result_format
|
133
|
+
@headers = parse_headers(http_response.to_hash)
|
134
|
+
@body = parse_body(http_response.body)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
# Parses raw headers in to a reasonable hash
|
140
|
+
def parse_headers(raw_headers)
|
141
|
+
# raw headers from net_http have an array for each result. Flatten them out.
|
142
|
+
raw_headers.inject({}) do |remainder, (k, v)|
|
143
|
+
remainder[k] = [v].flatten.first
|
144
|
+
remainder
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Parses the raw body in to a Hashie::Mash object, an array of Hashie::Mashes, or, if all else fails, returns a hash.
|
149
|
+
def parse_body(body)
|
150
|
+
# Parse JSON
|
151
|
+
object = MultiJson.load(body)
|
152
|
+
|
153
|
+
case @result_format
|
154
|
+
when :mashie
|
155
|
+
# Hash
|
156
|
+
return Hashie::Mash.new(object) if object.is_a? Hash
|
157
|
+
# Array
|
158
|
+
begin
|
159
|
+
return object.map { |h| Hashie::Mash.new(h) } if object.is_a? Array
|
160
|
+
rescue
|
161
|
+
# sometimes, for things like string arrays, we'll end up with an error. Fall through.
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
object
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Lapse
|
2
|
+
# Transports are a way for the client to communicate with the API.
|
3
|
+
module Transport
|
4
|
+
Dir[File.expand_path('../transport/*.rb', __FILE__)].each { |f| require f }
|
5
|
+
|
6
|
+
# Transport adapter map
|
7
|
+
TRANSPORT_MAP = {
|
8
|
+
:http => Lapse::Transport::HTTP
|
9
|
+
}
|
10
|
+
end
|
11
|
+
end
|
data/lib/lapse.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'Lapse/version'
|
2
|
+
require 'Lapse/client'
|
3
|
+
require 'Lapse/error'
|
4
|
+
|
5
|
+
# Lapse, as in teeter-Lapse, let's you work with the Seesaw API in Ruby.
|
6
|
+
module Lapse
|
7
|
+
class << self
|
8
|
+
# Alias for Lapse::Client.new
|
9
|
+
#
|
10
|
+
# @return [Lapse::Client]
|
11
|
+
def new(options = {})
|
12
|
+
Client.new(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Delegate to Lapse::Client.new
|
16
|
+
def method_missing(method, *args, &block)
|
17
|
+
return super unless new.respond_to?(method)
|
18
|
+
new.send(method, *args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Forward respond_to? to Lapse::Client.new
|
22
|
+
def respond_to?(method, include_private = false)
|
23
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ClientTest < Lapse::TestCase
|
4
|
+
def test_initialization
|
5
|
+
client = Lapse::Client.new(:access_token => 'asdf1234')
|
6
|
+
assert_equal 'asdf1234', client.access_token
|
7
|
+
assert client.authenticated?
|
8
|
+
|
9
|
+
client = Lapse::Client.new('asdf1234')
|
10
|
+
assert_equal 'asdf1234', client.access_token
|
11
|
+
|
12
|
+
client = Lapse::Client.new
|
13
|
+
refute client.authenticated?
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_base_url
|
17
|
+
client = Lapse::Client.new
|
18
|
+
assert_equal 'https://everlapse.com/v1/', client.base_url
|
19
|
+
|
20
|
+
client = Lapse::Client.new(:api_scheme => 'http', :api_host => 'example.com', :api_version => 42)
|
21
|
+
assert_equal 'http://example.com/v42/', client.base_url
|
22
|
+
|
23
|
+
client = Lapse::Client.new(:api_url => 'http://example.com')
|
24
|
+
assert_equal 'http://example.com/v1/', client.base_url
|
25
|
+
|
26
|
+
client = Lapse::Client.new(:api_url => 'http://localhost:3000')
|
27
|
+
assert_equal 'http://localhost:3000/v1/', client.base_url
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_ssl?
|
31
|
+
client = Lapse::Client.new
|
32
|
+
assert client.ssl?
|
33
|
+
|
34
|
+
client = Lapse::Client.new(:api_scheme => 'http')
|
35
|
+
refute client.ssl?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_configuration
|
39
|
+
Lapse::Client.configure do |client|
|
40
|
+
client.api_host = 'blah'
|
41
|
+
client.api_scheme = 'gopher'
|
42
|
+
client.result_format = :hash
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_equal 'blah', Lapse::Client.new.api_host
|
46
|
+
assert_equal 'gopher', Lapse::Client.new.api_scheme
|
47
|
+
Lapse::Client.new.result_format
|
48
|
+
|
49
|
+
# forcibly reset the configuration
|
50
|
+
Lapse::Client.options = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/test/lapse_test.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
module ClientMacros
|
2
|
+
def local_client
|
3
|
+
client = Lapse::Client.new(:access_token => '9774e653f7b3c1de5f21b61adc08ba24', :api_host => 'localhost:5000', :api_scheme => 'http')
|
4
|
+
end
|
5
|
+
|
6
|
+
def unauthenticated_monkeybars_production_client
|
7
|
+
Lapse::Client.new(:client_token => '29756b7591819c57e01ac2c6d9ae5311')
|
8
|
+
end
|
9
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require :test
|
4
|
+
|
5
|
+
require 'simplecov'
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter "/test/"
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'minitest/autorun'
|
11
|
+
require 'Lapse'
|
12
|
+
|
13
|
+
# Support files
|
14
|
+
Dir["#{File.expand_path(File.dirname(__FILE__))}/support/*.rb"].each do |file|
|
15
|
+
require file
|
16
|
+
end
|
17
|
+
|
18
|
+
class Lapse::TestCase < MiniTest::Unit::TestCase
|
19
|
+
include ::ClientMacros
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lapse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sam Soffes
|
9
|
+
- Aaron Gotwalt
|
10
|
+
- Adam Ryan
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2013-06-05 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: multi_json
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.6'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '1.6'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: hashie
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.2.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.2.0
|
48
|
+
description: Ruby gem for working with the Everlapse API.
|
49
|
+
email:
|
50
|
+
- sam@soff.es
|
51
|
+
- gotwalt@gmail.com
|
52
|
+
- adam.g.ryan@gmail.com
|
53
|
+
executables: []
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- .gitignore
|
58
|
+
- .travis.yml
|
59
|
+
- Contributing.markdown
|
60
|
+
- Gemfile
|
61
|
+
- LICENSE
|
62
|
+
- Rakefile
|
63
|
+
- Readme.markdown
|
64
|
+
- lapse.gemspec
|
65
|
+
- lib/lapse.rb
|
66
|
+
- lib/lapse/client.rb
|
67
|
+
- lib/lapse/client/configuration.rb
|
68
|
+
- lib/lapse/error.rb
|
69
|
+
- lib/lapse/response.rb
|
70
|
+
- lib/lapse/transport.rb
|
71
|
+
- lib/lapse/transport/http.rb
|
72
|
+
- lib/lapse/version.rb
|
73
|
+
- test/lapse/client_test.rb
|
74
|
+
- test/lapse/transport/http_test.rb
|
75
|
+
- test/lapse_test.rb
|
76
|
+
- test/support/client_macros.rb
|
77
|
+
- test/test_helper.rb
|
78
|
+
homepage: https://github.com/seesawco/lapse-rb
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.8.7
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
hash: -3688395446889741402
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.8.23
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Ruby gem for working with the Everlapse API.
|
106
|
+
test_files:
|
107
|
+
- test/lapse/client_test.rb
|
108
|
+
- test/lapse/transport/http_test.rb
|
109
|
+
- test/lapse_test.rb
|
110
|
+
- test/support/client_macros.rb
|
111
|
+
- test/test_helper.rb
|
112
|
+
has_rdoc:
|