bullion_vault 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/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