invisiblehand 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.
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +124 -0
- data/Rakefile +10 -0
- data/invisiblehand.gemspec +24 -0
- data/invisiblehand.sample.yml +11 -0
- data/lib/invisiblehand.rb +23 -0
- data/lib/invisiblehand/api.rb +110 -0
- data/lib/invisiblehand/errors.rb +6 -0
- data/lib/invisiblehand/logger.rb +32 -0
- data/lib/invisiblehand/version.rb +5 -0
- data/spec/api_spec.rb +62 -0
- data/spec/spec_helper.rb +1 -0
- metadata +131 -0
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.rvmrc
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.yardoc
|
7
|
+
Gemfile.lock
|
8
|
+
InstalledFiles
|
9
|
+
_yardoc
|
10
|
+
coverage
|
11
|
+
doc/
|
12
|
+
lib/bundler/man
|
13
|
+
pkg
|
14
|
+
rdoc
|
15
|
+
spec/reports
|
16
|
+
test/tmp
|
17
|
+
test/version_tmp
|
18
|
+
tmp
|
19
|
+
invisiblehand.yml
|
20
|
+
spec/invisiblehand.yml
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Sam Rose
|
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,124 @@
|
|
1
|
+
# InvisibleHand API Client Ruby
|
2
|
+
|
3
|
+
A Ruby client library to the InvisibleHand API. Allows for very easy
|
4
|
+
programmatic access to the Invisible Hand API from Ruby.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'invisiblehand'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Alternately you can just install directly through the `gem` command:
|
17
|
+
|
18
|
+
$ gem install invisiblehand
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
The first thing you must do in order to use this gem is create a configuration
|
23
|
+
that contains your app ID and app key. You can obtain these from the Invisible
|
24
|
+
Hand API website:
|
25
|
+
[https://developer.getinvisiblehand.com/](https://developer.getinvisiblehand.com/).
|
26
|
+
|
27
|
+
The sample configuration in this repository gives you a taste of what the config
|
28
|
+
should look like. The gem will look for the config in the following locations in
|
29
|
+
the following order:
|
30
|
+
|
31
|
+
- The path or Hash sent to the constructor
|
32
|
+
- An ENV variable called INVISIBLEHAND_CONFIG
|
33
|
+
- The current working directory at: ./invisiblehand.yml
|
34
|
+
|
35
|
+
Some example usage:
|
36
|
+
|
37
|
+
``` ruby
|
38
|
+
require 'invisiblehand'
|
39
|
+
|
40
|
+
# Instantiate the API object using the default config location
|
41
|
+
# ./invisiblehand.yml
|
42
|
+
api = InvisibleHand::API.new
|
43
|
+
|
44
|
+
# Instantiate the API object with a hard coded, not-in-file config.
|
45
|
+
api = InvisibleHand::API.new :app_id => "id", :app_key => "key"
|
46
|
+
|
47
|
+
# Instantiate the API object from a path to a file.
|
48
|
+
api = InvisibleHand::API.new "path/to/invisiblehand.yml"
|
49
|
+
|
50
|
+
# Search for products that match the query "ipad"
|
51
|
+
api.products({
|
52
|
+
:query => "ipad"
|
53
|
+
})
|
54
|
+
#=> A massive hash that you can find details of at:
|
55
|
+
# https://developer.getinvisiblehand.com/documentation
|
56
|
+
|
57
|
+
# Search for products in a different region with a load of other relevant
|
58
|
+
# options
|
59
|
+
api.products({
|
60
|
+
:query => "galaxy", # Search term
|
61
|
+
:region => "ca", # Which region to query
|
62
|
+
:sort => "popularity", # What to order results by
|
63
|
+
:order => "desc", # Direction to order results by
|
64
|
+
:size => "100" # Number of results to return
|
65
|
+
})
|
66
|
+
#=> A massive hash that you can find details of at:
|
67
|
+
# https://developer.getinvisiblehand.com/documentation
|
68
|
+
|
69
|
+
# Do a live price search on a product (price comes back as the currency in the
|
70
|
+
# URL you specify. On amazon.com you get dollars, amazon.co.uk you get pounds.)
|
71
|
+
api.live_price "http://www.amazon.com/gp/product/B005SUHRZS"
|
72
|
+
#=> 11.25
|
73
|
+
|
74
|
+
# You can also specify an Invisible Hand API link to the live_price method and
|
75
|
+
# it will work fine.
|
76
|
+
api.live_price "http://api.invisiblehand.co.uk/v1/pages/live_price?url=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fproduct%2FB007PRHNHO"
|
77
|
+
|
78
|
+
# Search for a specific product by its Invisible Hand ID
|
79
|
+
api.product "f619c3e117d50d1a2b10930e5b202336"
|
80
|
+
#=> A hash containing details of this item. More info at:
|
81
|
+
# https://developer.getinvisiblehand.com/documentation
|
82
|
+
|
83
|
+
```
|
84
|
+
|
85
|
+
### Errors
|
86
|
+
|
87
|
+
If the API returns any error information, an `InvisibleHand::Error::APIError` is
|
88
|
+
thrown and the `#message` method of the error object will contain the error
|
89
|
+
output from the API.
|
90
|
+
|
91
|
+
### Logging
|
92
|
+
|
93
|
+
The InvisibleHand gem does have debug logging that goes to an internal `Logger`
|
94
|
+
object. It should not output anything higher than the debug level, which it does
|
95
|
+
when the `DEBUG` environment variable is set.
|
96
|
+
|
97
|
+
If you wish to override the default logging object it builds internally, which
|
98
|
+
outputs to STDOUT, you can do so with the following code:
|
99
|
+
|
100
|
+
``` ruby
|
101
|
+
require 'invisiblehand'
|
102
|
+
|
103
|
+
# Ignore all InvisibleHand logging.
|
104
|
+
InvisibleHand.logger = Logger.new('/dev/null')
|
105
|
+
```
|
106
|
+
|
107
|
+
## Debugging
|
108
|
+
|
109
|
+
The gem looks for a DEBUG environment variable. If DEBUG is set, debugging
|
110
|
+
information will be printed out to the screen. This includes URL information
|
111
|
+
every time an API call is made.
|
112
|
+
|
113
|
+
## Development
|
114
|
+
|
115
|
+
To run tests, first you will need a valid `invisiblehand.yml` config file inside
|
116
|
+
the `spec/` directory. The config you specify must be able to make API calls.
|
117
|
+
|
118
|
+
Once you have confirmed this, you can run tests with the following command:
|
119
|
+
|
120
|
+
$ rake
|
121
|
+
|
122
|
+
And if you wish to see debugging information:
|
123
|
+
|
124
|
+
$ DEBUG=true rake
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/invisiblehand/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Sam Rose"]
|
6
|
+
gem.email = ["developers@getinvisiblehand.com"]
|
7
|
+
gem.description = %q{Ruby API client library to the InvisibleHand API.}
|
8
|
+
gem.summary = %q{Allows for easy programmatic access to the InvisibleHand API.}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "invisiblehand"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = InvisibleHand::VERSION
|
17
|
+
|
18
|
+
# Dependencies
|
19
|
+
gem.add_dependency('rest-client')
|
20
|
+
gem.add_dependency('json')
|
21
|
+
|
22
|
+
gem.add_development_dependency('rake')
|
23
|
+
gem.add_development_dependency('rspec')
|
24
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
:app_id: "your app id here"
|
2
|
+
:app_key: "your app key here"
|
3
|
+
|
4
|
+
# The endpoint is the region of the API you would like to hit. The regions are
|
5
|
+
# detailed in the developer documentation:
|
6
|
+
#
|
7
|
+
# https://developer.getinvisiblehand.com/documentation#intro
|
8
|
+
#
|
9
|
+
# The option will default to the US if you do not explicitly specify it.
|
10
|
+
#
|
11
|
+
# :endpoint: us.api.invisiblehand.co.uk
|
@@ -0,0 +1,23 @@
|
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH << libdir unless $LOAD_PATH.include? libdir
|
3
|
+
|
4
|
+
require 'cgi'
|
5
|
+
require 'yaml'
|
6
|
+
require 'logger'
|
7
|
+
require 'rest_client'
|
8
|
+
require 'json'
|
9
|
+
require 'benchmark'
|
10
|
+
|
11
|
+
# Requires all .rb file in a given directory.
|
12
|
+
def require_all path
|
13
|
+
Dir[File.join(File.dirname(__FILE__), path, '*.rb')].each { |f| require f }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Logger is required early because it's a dependency of other classes.
|
17
|
+
require 'invisiblehand/logger'
|
18
|
+
|
19
|
+
require_all 'invisiblehand'
|
20
|
+
|
21
|
+
module InvisibleHand
|
22
|
+
DEBUG = !!ENV['DEBUG']
|
23
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module InvisibleHand
|
2
|
+
class API
|
3
|
+
include InvisibleHand::Logger
|
4
|
+
attr_accessor :config
|
5
|
+
|
6
|
+
# When initializing a new instance of `InvisibleHand::API`, you can specify
|
7
|
+
# configuration in one of three ways:
|
8
|
+
#
|
9
|
+
# require 'invisiblehand'
|
10
|
+
#
|
11
|
+
# # This looks first for an environment variable called
|
12
|
+
# # "INVISIBLEHAND_CONFIG", which should contain a file path to a config
|
13
|
+
# # YAML file. Failing that, "./invisiblehand.yml" is used, looking for
|
14
|
+
# # the config YAML file in the current directory.
|
15
|
+
# api = InvisibleHand::API.new
|
16
|
+
#
|
17
|
+
# # This one takes a string argument which should be a valid file path to
|
18
|
+
# # the YAML config file.
|
19
|
+
# api = InvisibleHand::API.new "path/to/invisiblehand.yml"
|
20
|
+
#
|
21
|
+
# # Or you can do a literal hash config. This requires no YAML config
|
22
|
+
# # file.
|
23
|
+
# api = InvisibleHand::API.new :api_key => "...", :app_id => "..."
|
24
|
+
#
|
25
|
+
# Examples of the configuration variables you can pass in can be found in
|
26
|
+
# the "invisiblehand.sample.yml" file in this gem's GitHub repository.
|
27
|
+
def initialize conf = nil
|
28
|
+
if conf.is_a? Hash
|
29
|
+
@config = conf
|
30
|
+
elsif conf.is_a? String
|
31
|
+
@config = YAML.load_file(conf)
|
32
|
+
else
|
33
|
+
conf ||= ENV['INVISIBLEHAND_CONFIG'] || './invisiblehand.yml'
|
34
|
+
@config = YAML.load_file(conf)
|
35
|
+
end
|
36
|
+
|
37
|
+
# The @config[:development] flag exists to bypass the app_id and app_key
|
38
|
+
# check in this gem (not on the server) for internal testing reasons.
|
39
|
+
if valid_config?
|
40
|
+
raise Error::InvalidConfig.new
|
41
|
+
"Your config does not contain an app_id and app_key. " +
|
42
|
+
"Both are required to make API calls."
|
43
|
+
end
|
44
|
+
|
45
|
+
@config[:protocol] = @config[:use_ssl] == false ? "http://" : "https://"
|
46
|
+
@config[:endpoint] ||= "us.api.invisiblehand.co.uk"
|
47
|
+
end
|
48
|
+
|
49
|
+
def products opts = {}
|
50
|
+
api_call :get, "/v1/products", opts
|
51
|
+
end
|
52
|
+
|
53
|
+
def product id, opts = {}
|
54
|
+
api_call :get, "/v1/products/#{CGI.escape(id)}", opts
|
55
|
+
end
|
56
|
+
|
57
|
+
def live_price url, opts = {}
|
58
|
+
if url =~ /http:\/\/api\.invisiblehand/
|
59
|
+
url += url_params_from opts
|
60
|
+
json = api_raw_request :get, url
|
61
|
+
json["price"]
|
62
|
+
else
|
63
|
+
opts[:url] = url
|
64
|
+
json = api_call :get, "/v1/pages/live_price", opts
|
65
|
+
json["price"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def api_call method, path, opts = {}
|
70
|
+
query = url_params_from opts
|
71
|
+
url = "#{@config[:protocol]}#{@config[:endpoint]}#{path}?#{query}"
|
72
|
+
|
73
|
+
api_raw_request method, url
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def api_raw_request method, url
|
79
|
+
logger.debug "API call URL: #{url}"
|
80
|
+
|
81
|
+
# Declare these early to avoid scoping programs in the timing block.
|
82
|
+
response = nil
|
83
|
+
json = nil
|
84
|
+
|
85
|
+
elapsed = Benchmark.realtime do
|
86
|
+
response = RestClient.send(method, url) { |resp, req, res| resp }
|
87
|
+
json = JSON.parse(response.body)
|
88
|
+
end
|
89
|
+
|
90
|
+
logger.debug "API call took #{elapsed.round(3)} seconds."
|
91
|
+
logger.debug "API json response: #{json.inspect}"
|
92
|
+
|
93
|
+
raise Error::APIError.new(json["error"]) if json["error"]
|
94
|
+
|
95
|
+
json
|
96
|
+
end
|
97
|
+
|
98
|
+
def url_params_from hash
|
99
|
+
hash.map do |key, value|
|
100
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
|
101
|
+
end.join("&")
|
102
|
+
end
|
103
|
+
|
104
|
+
def valid_config?
|
105
|
+
@config[:app_id].nil? and
|
106
|
+
@config[:app_key].nil? and
|
107
|
+
!@config[:development]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module InvisibleHand
|
2
|
+
def self.logger
|
3
|
+
unless @logger
|
4
|
+
@logger = ::Logger.new(STDOUT)
|
5
|
+
|
6
|
+
if DEBUG
|
7
|
+
@logger.level = ::Logger::DEBUG
|
8
|
+
else
|
9
|
+
@logger.level = ::Logger::FATAL
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
@logger
|
14
|
+
end
|
15
|
+
|
16
|
+
# Override the InvisibleHand logger if you wish to have finer grained control
|
17
|
+
# over where your application's output is going.
|
18
|
+
#
|
19
|
+
# InvisibleHand.logger = Logger.new('my/app/logs.log')
|
20
|
+
def self.logger= new_logger
|
21
|
+
@logger = new_logger
|
22
|
+
end
|
23
|
+
|
24
|
+
# Helper module for classes to include if they want to use the main
|
25
|
+
# InvisibleHand logger. Should be used for all in-gem logging as it is
|
26
|
+
# configurable by the end-user of the gem.
|
27
|
+
module Logger
|
28
|
+
def logger
|
29
|
+
InvisibleHand.logger
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe InvisibleHand::API do
|
4
|
+
# This file is not committed to this repository. You will have to create it
|
5
|
+
# yourself if you wish to run tests.
|
6
|
+
let(:api_config) { File.join(File.dirname(__FILE__), 'invisiblehand.yml') }
|
7
|
+
|
8
|
+
let(:api) { InvisibleHand::API.new(api_config) }
|
9
|
+
let(:product) { api.products["results"].first }
|
10
|
+
let(:product_id) { product["id"] }
|
11
|
+
let(:page) { product["best_page"] }
|
12
|
+
|
13
|
+
describe "#products" do
|
14
|
+
subject { api.products }
|
15
|
+
it { should be_a Hash }
|
16
|
+
its(:keys) { should include "results" }
|
17
|
+
its(:keys) { should include "info" }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#product" do
|
21
|
+
subject { product }
|
22
|
+
it { should_not be_nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#live_price" do
|
26
|
+
describe "with live price url" do
|
27
|
+
subject { api.live_price(page["live_price_url"]) }
|
28
|
+
it { should be_a Float }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "with vanilla page url" do
|
32
|
+
subject { api.live_price(page["original_url"]) }
|
33
|
+
it { should be_a Float }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "invalid config" do
|
38
|
+
specify "no app_id or api_key should throw error" do
|
39
|
+
expect do
|
40
|
+
InvisibleHand::API.new
|
41
|
+
end.to raise_error InvisibleHand::Error::InvalidConfig
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "invalid api calls" do
|
46
|
+
describe "#product" do
|
47
|
+
specify "should throw InvisibleHand::Error::APIError on invalid ID" do
|
48
|
+
expect do
|
49
|
+
api.product "not a real id at all, lol"
|
50
|
+
end.to raise_error InvisibleHand::Error::APIError
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#live_price" do
|
55
|
+
specify "should throw InvisibleHand::Error::APIError on invalid URL" do
|
56
|
+
expect do
|
57
|
+
api.live_price "not a real url, rofl"
|
58
|
+
end.to raise_error InvisibleHand::Error::APIError
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'invisiblehand')
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: invisiblehand
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sam Rose
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Ruby API client library to the InvisibleHand API.
|
79
|
+
email:
|
80
|
+
- developers@getinvisiblehand.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- invisiblehand.gemspec
|
91
|
+
- invisiblehand.sample.yml
|
92
|
+
- lib/invisiblehand.rb
|
93
|
+
- lib/invisiblehand/api.rb
|
94
|
+
- lib/invisiblehand/errors.rb
|
95
|
+
- lib/invisiblehand/logger.rb
|
96
|
+
- lib/invisiblehand/version.rb
|
97
|
+
- spec/api_spec.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
homepage: ''
|
100
|
+
licenses: []
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
hash: 3768390383107493245
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
hash: 3768390383107493245
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 1.8.24
|
126
|
+
signing_key:
|
127
|
+
specification_version: 3
|
128
|
+
summary: Allows for easy programmatic access to the InvisibleHand API.
|
129
|
+
test_files:
|
130
|
+
- spec/api_spec.rb
|
131
|
+
- spec/spec_helper.rb
|