bullion_vault 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bullion_vault (0.1.0)
5
+ faraday_middleware (~> 0.3.2)
6
+ hashie (~> 1.0.0)
7
+ multi_xml (~> 0.2.1)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ addressable (2.2.4)
13
+ crack (0.1.8)
14
+ diff-lcs (1.1.2)
15
+ faraday (0.5.7)
16
+ addressable (~> 2.2.4)
17
+ multipart-post (~> 1.1.0)
18
+ rack (< 2, >= 1.1.0)
19
+ faraday_middleware (0.3.2)
20
+ faraday (~> 0.5.4)
21
+ hashie (1.0.0)
22
+ multi_xml (0.2.1)
23
+ multipart-post (1.1.0)
24
+ rack (1.2.2)
25
+ rake (0.8.7)
26
+ rspec (2.5.0)
27
+ rspec-core (~> 2.5.0)
28
+ rspec-expectations (~> 2.5.0)
29
+ rspec-mocks (~> 2.5.0)
30
+ rspec-core (2.5.1)
31
+ rspec-expectations (2.5.0)
32
+ diff-lcs (~> 1.1.2)
33
+ rspec-mocks (2.5.0)
34
+ webmock (1.6.2)
35
+ addressable (>= 2.2.2)
36
+ crack (>= 0.1.7)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ bullion_vault!
43
+ rake (~> 0.8.7)
44
+ rspec (~> 2.5.0)
45
+ webmock (~> 1.6.2)
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010-2011 William T Nelson, John Nunemaker, Wynn
2
+ Netherland, Erik Michaels-Ober, Steve Richert
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ BullionVault Ruby Gem
2
+ ====================
3
+ A Ruby wrapper for the BullionVault XML API
4
+
5
+ Installation
6
+ ------------
7
+ gem install bullion_vault
8
+
9
+ Usage Examples
10
+ --------------
11
+ require 'rubygems'
12
+ require 'bullion_vault'
13
+ require 'pp'
14
+
15
+ # Get current market data
16
+ pp BullionVault.view_market
17
+
18
+ # Certain methods require authentication. To get BullionVault credentials,
19
+ # sign up at https://live.bullionvault.com/secure/registration.do
20
+
21
+ BullionVault \
22
+ .configure {|c| c.user_login, c.user_password = USERNAME, PASSWORD } \
23
+ .authenticate
24
+ => true
25
+
26
+ # Check your account
27
+ pp BullionVault.view_balance
28
+
29
+ # You only need a valid session id to be authenticated
30
+ BullionVault.cookie
31
+ => "JSESSIONID=1D034E46B78C47C17005478B6537CABD; Path=/secure; Secure,
32
+ logintest=\"Thu Mar 31 09:17:26 UTC 2011\"; Version=1; Max-Age=60000;
33
+ Expires=Fri, 01-Apr-2011 01:57:26 GMT"
34
+ cookie = 'JSESSIONID=1D034E46B78C47C17005478B6537CABD'
35
+ BullionVault.cookie = cookie
36
+ BullionVault.view_balance
37
+
38
+ # Use two accounts at once
39
+ BullionVault.reset
40
+ c0 = BullionVault::Client.new(:user_login => 'sara_birton')
41
+ c1 = BullionVault::Client.new(:user_login => 'bonepoppy')
42
+
43
+ Documentation
44
+ -------------
45
+ * [BullionVault XML API](http://www.bullionvault.com/help/?xml_api.html)
46
+ * [BullionVault Robots FAQs](http://www.bullionvault.com/help/index.do?content=FAQs/FAQs_bots.html)
47
+
48
+ Copyright
49
+ ---------
50
+ Copyright (c) 2010-2011 William T Nelson, John Nunemaker, Wynn Netherland,
51
+ Erik Michaels-Ober, Steve Richert. See [MIT-LICENSE](https://github.com/wtn/bullion_vault/blob/master/MIT-LICENSE) for details.
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :test => :spec
8
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/bullion_vault/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.add_development_dependency('rspec', '~> 2.5.0')
6
+ s.add_development_dependency('webmock', '~> 1.6.2')
7
+ s.add_development_dependency('rake', '~> 0.8.7')
8
+ s.add_runtime_dependency('faraday_middleware', '~> 0.3.2')
9
+ s.add_runtime_dependency('multi_xml', '~> 0.2.1')
10
+ s.add_runtime_dependency('hashie', '~> 1.0.0')
11
+
12
+ s.name = 'bullion_vault'
13
+ s.version = BullionVault::VERSION.dup
14
+ s.summary = %q{A Ruby wrapper for the BullionVault XML API}
15
+ s.description = %q{A Ruby wrapper for the BullionVault XML API}
16
+ s.homepage = 'https://github.com/wtn/bullion_vault'
17
+ s.authors = ['William T Nelson']
18
+ s.email = ['wtn@notational.net']
19
+ s.post_install_message = nil
20
+ s.rubyforge_project = nil
21
+ s.platform = Gem::Platform::RUBY
22
+ s.files = `git ls-files`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ['lib']
25
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to?(:required_rubygems_version=)
26
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
27
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../bullion_vault/error', __FILE__)
2
+ require File.expand_path('../bullion_vault/configuration', __FILE__)
3
+ require File.expand_path('../bullion_vault/api', __FILE__)
4
+ require File.expand_path('../bullion_vault/client', __FILE__)
5
+ require File.expand_path('../bullion_vault/connection', __FILE__)
6
+ require File.expand_path('../bullion_vault/request', __FILE__)
7
+
8
+ module BullionVault
9
+ extend Configuration
10
+
11
+ def self.client(options={})
12
+ BullionVault::Client.new(options)
13
+ end
14
+
15
+ def self.method_missing(method, *args, &block)
16
+ return super if ! client.respond_to?(method)
17
+ client.public_send(method, *args, &block)
18
+ end
19
+
20
+ def self.respond_to?(method)
21
+ return client.respond_to?(method) || super
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../connection', __FILE__)
2
+ require File.expand_path('../request', __FILE__)
3
+ require File.expand_path('../authentication', __FILE__)
4
+
5
+ module BullionVault
6
+ class API
7
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
8
+
9
+ # Creates a new API
10
+ def initialize(options={})
11
+ options = BullionVault.options.merge(options)
12
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
13
+ public_send("#{key}=", options[key])
14
+ end
15
+ end
16
+
17
+ include Connection
18
+ include Request
19
+ include Authentication
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module BullionVault
2
+ module Authentication
3
+ private
4
+
5
+ def login_credentials
6
+ { :j_username => user_login, :j_password => user_password }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module BullionVault
2
+ class Client < API
3
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each {|f| require f }
4
+
5
+ alias :api_endpoint :endpoint
6
+
7
+ include BullionVault::Client::Login
8
+ include BullionVault::Client::ViewMarket
9
+ include BullionVault::Client::ViewBalance
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module BullionVault
2
+ class Client
3
+ module Login
4
+ HTML_LOGIN_PATH = 'secure/login.do'.freeze
5
+ XML_LOGIN_PATH = 'secure/j_security_check'.freeze
6
+
7
+ def authenticate(raw=false)
8
+ reset_cookie
9
+ login(raw)
10
+ end
11
+
12
+ private
13
+
14
+ def login(raw=false)
15
+ resp = post(XML_LOGIN_PATH, login_credentials, true)
16
+ raw and return resp
17
+ resp.status == 302 and resp.headers['location'] == 'https://live.bullionvault.com/secure/main_frame.do'
18
+ end
19
+
20
+ def reset_cookie
21
+ self.cookie = nil
22
+ self.cookie = get(HTML_LOGIN_PATH, {}, true).headers['set-cookie']
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module BullionVault
2
+ class Client
3
+ module ViewBalance
4
+ BALANCE_PATH = 'secure/view_balance_xml.do'.freeze
5
+
6
+ def view_balance(options={}, raw=false)
7
+ get BALANCE_PATH, options, raw
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module BullionVault
2
+ class Client
3
+ module ViewMarket
4
+ MARKET_PATH = 'view_market_xml.do'.freeze
5
+
6
+ def view_market(options={}, raw=false)
7
+ get MARKET_PATH, options, raw
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,66 @@
1
+ require 'faraday'
2
+ require File.expand_path('../version', __FILE__)
3
+
4
+ module BullionVault
5
+ module Configuration
6
+ VALID_OPTIONS_KEYS = [
7
+ :adapter,
8
+ :user_login,
9
+ :user_password,
10
+ :endpoint,
11
+ :format,
12
+ :proxy,
13
+ :cookie,
14
+ :user_agent
15
+ ].freeze
16
+
17
+ VALID_FORMATS = [:xml].freeze
18
+
19
+ # The default faraday adapter is Net::HTTP.
20
+ DEFAULT_ADAPTER = Faraday.default_adapter
21
+
22
+ DEFAULT_USER_LOGIN = nil
23
+ DEFAULT_USER_PASSWORD = nil
24
+ DEFAULT_ENDPOINT = 'https://live.bullionvault.com/'.freeze
25
+ DEFAULT_FORMAT = 'xml'.freeze
26
+ DEFAULT_PROXY = nil
27
+ DEFAULT_COOKIE = nil
28
+ DEFAULT_USER_AGENT = "BullionVault Ruby Gem #{BullionVault::VERSION}".freeze
29
+
30
+ attr_accessor *VALID_OPTIONS_KEYS
31
+
32
+ # When this module is extended, set all configuration options to their default values
33
+ def self.extended(base)
34
+ base.reset
35
+ end
36
+
37
+ # Convenience method to allow configuration options to be set in a block
38
+ def configure
39
+ yield self
40
+ self
41
+ end
42
+
43
+ # Create a hash of options and their values
44
+ def options
45
+ Hash[VALID_OPTIONS_KEYS.map {|key| [key, public_send(key)] }]
46
+ end
47
+
48
+ # Reset all configuration options to defaults
49
+ def reset
50
+ self.adapter = DEFAULT_ADAPTER
51
+ self.user_login = DEFAULT_USER_LOGIN
52
+ self.user_password = DEFAULT_USER_PASSWORD
53
+ self.endpoint = DEFAULT_ENDPOINT
54
+ self.format = DEFAULT_FORMAT
55
+ self.proxy = DEFAULT_PROXY
56
+ self.cookie = DEFAULT_COOKIE
57
+ self.user_agent = DEFAULT_USER_AGENT
58
+ self
59
+ end
60
+
61
+ def authenticate
62
+ client = Client.new
63
+ client.authenticate ? (BullionVault.cookie = client.cookie and true) : false
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday_middleware'
2
+ Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each {|f| require f}
3
+
4
+ module BullionVault
5
+ module Connection
6
+ private
7
+
8
+ def connection(raw=false)
9
+ options = {
10
+ :headers => {'User-Agent' => user_agent},
11
+ :proxy => proxy,
12
+ :ssl => {:verify => false},
13
+ :url => api_endpoint,
14
+ }
15
+
16
+ Faraday::Connection.new(options) do |connection|
17
+ cookie and connection.use Faraday::Request::CookieAuth, cookie
18
+ connection.adapter(adapter)
19
+ connection.use Faraday::Response::RaiseHttp5xx
20
+ parse_xml?(raw).tap do |parse_xml|
21
+ connection.use Faraday::Response::ParseXml if parse_xml
22
+ connection.use Faraday::Response::RaiseHttp4xx
23
+ cookie and connection.use Faraday::Response::RaiseInvalidCookie
24
+ connection.use Faraday::Response::Mashify if parse_xml
25
+ end
26
+ end
27
+ end
28
+
29
+ def parse_xml?(raw)
30
+ ! raw and format.to_s.downcase == 'xml'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ module BullionVault
2
+ class Error < StandardError; end
3
+
4
+ class BullionVault::InvalidCookie < Error; end
5
+
6
+ # 400
7
+ class BadRequest < Error; end
8
+
9
+ # 401
10
+ class Unauthorized < Error; end
11
+
12
+ # 403
13
+ class Forbidden < Error; end
14
+
15
+ # 404
16
+ class NotFound < Error; end
17
+
18
+ # 406
19
+ class NotAcceptable < Error; end
20
+
21
+ # 500
22
+ class InternalServerError < Error; end
23
+
24
+ # 502
25
+ class BadGateway < Error; end
26
+
27
+ # 503
28
+ class ServiceUnavailable < Error; end
29
+ end
@@ -0,0 +1,34 @@
1
+ module BullionVault
2
+ module Request
3
+ def get(path, options={}, raw=false)
4
+ request(:get, path, options, raw)
5
+ end
6
+
7
+ def post(path, options={}, raw=false)
8
+ request(:post, path, options, raw)
9
+ end
10
+
11
+ def put(path, options={}, raw=false)
12
+ request(:put, path, options, raw)
13
+ end
14
+
15
+ def delete(path, options={}, raw=false)
16
+ request(:delete, path, options, raw)
17
+ end
18
+
19
+ private
20
+
21
+ def request(method, path, options, raw=false)
22
+ response = connection(raw).public_send(method) do |request|
23
+ case method
24
+ when :get, :delete
25
+ request.url(path, options)
26
+ when :post, :put
27
+ request.path = path
28
+ request.body = options unless options.empty?
29
+ end
30
+ end
31
+ raw ? response : response.body
32
+ end
33
+ end
34
+ end