currency-rate 0.1.1
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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +91 -0
- data/LICENSE.txt +20 -0
- data/README.md +52 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/currency-rate.gemspec +95 -0
- data/lib/adapter.rb +42 -0
- data/lib/btc_adapter.rb +17 -0
- data/lib/btc_adapters/average_rate_adapter.rb +50 -0
- data/lib/btc_adapters/bitpay_adapter.rb +18 -0
- data/lib/btc_adapters/bitstamp_adapter.rb +14 -0
- data/lib/btc_adapters/btce_adapter.rb +14 -0
- data/lib/btc_adapters/coinbase_adapter.rb +13 -0
- data/lib/btc_adapters/kraken_adapter.rb +14 -0
- data/lib/btc_adapters/localbitcoins_adapter.rb +13 -0
- data/lib/btc_adapters/okcoin_adapter.rb +14 -0
- data/lib/core_ext/classify.rb +7 -0
- data/lib/core_ext/deep_get.rb +11 -0
- data/lib/currency_rate.rb +49 -0
- data/lib/fiat_adapter.rb +30 -0
- data/lib/fiat_adapters/fixer_adapter.rb +11 -0
- data/lib/fiat_adapters/yahoo_adapter.rb +22 -0
- data/lib/storage.rb +17 -0
- data/spec/currency_rate_spec.rb +28 -0
- data/spec/lib/btc_adapter_spec.rb +55 -0
- data/spec/lib/btc_adapters/average_rate_adapter_spec.rb +51 -0
- data/spec/lib/btc_adapters/bitpay_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/bitstamp_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/btce_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/coinbase_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/kraken_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/localbitcoins_adapter_spec.rb +35 -0
- data/spec/lib/btc_adapters/okcoin_adapter_spec.rb +35 -0
- data/spec/lib/fiat_adapters/fixer_adapter_spec.rb +22 -0
- data/spec/lib/fiat_adapters/yahoo_adapter_spec.rb +22 -0
- data/spec/lib/storage_spec.rb +25 -0
- data/spec/spec_helper.rb +13 -0
- metadata +169 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f65d7412d5bdf082fb39bc670010cf88aaf83ace
|
4
|
+
data.tar.gz: 7fc7e9af03abb1747d6f1fc01c6f880d64433a31
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1844ba52a93f9cdf1d5c3d6b2ecc7b8516ef8678f32771499fdb3c3c52785b3c5ed2dd3d9b1215e38256308ad19a58bc4e85d05cd87eab7cb9e92ed9c4586ac9
|
7
|
+
data.tar.gz: bc1a32af222d5555c8b7d1fe6cac660df64a512dee62c6ce7fd6d8995b7abd29bea28169edfbbe5dc8a6c17b5b81399143e57100eb73f6d85ac699aaf31ec632
|
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git@github.com:technicalpickles/jeweler.git
|
3
|
+
revision: ec91e05d06f2835ee30568fa42b5fa7d451444b6
|
4
|
+
specs:
|
5
|
+
jeweler (2.1.1)
|
6
|
+
builder
|
7
|
+
bundler (>= 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
github_api
|
10
|
+
highline (>= 1.6.15)
|
11
|
+
nokogiri (>= 1.5.10)
|
12
|
+
rake
|
13
|
+
rdoc
|
14
|
+
semver
|
15
|
+
|
16
|
+
GEM
|
17
|
+
remote: https://rubygems.org/
|
18
|
+
specs:
|
19
|
+
addressable (2.4.0)
|
20
|
+
builder (3.2.2)
|
21
|
+
crack (0.4.3)
|
22
|
+
safe_yaml (~> 1.0.0)
|
23
|
+
descendants_tracker (0.0.4)
|
24
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
25
|
+
diff-lcs (1.2.5)
|
26
|
+
faraday (0.9.2)
|
27
|
+
multipart-post (>= 1.2, < 3)
|
28
|
+
git (1.3.0)
|
29
|
+
github_api (0.14.0)
|
30
|
+
addressable (~> 2.4.0)
|
31
|
+
descendants_tracker (~> 0.0.4)
|
32
|
+
faraday (~> 0.8, < 0.10)
|
33
|
+
hashie (>= 3.4)
|
34
|
+
oauth2
|
35
|
+
hashdiff (0.3.0)
|
36
|
+
hashie (3.4.4)
|
37
|
+
highline (1.7.8)
|
38
|
+
json (1.8.3)
|
39
|
+
jwt (1.5.1)
|
40
|
+
mini_portile2 (2.0.0)
|
41
|
+
multi_json (1.12.1)
|
42
|
+
multi_xml (0.5.5)
|
43
|
+
multipart-post (2.0.0)
|
44
|
+
nokogiri (1.6.7.2)
|
45
|
+
mini_portile2 (~> 2.0.0.rc2)
|
46
|
+
oauth2 (1.1.0)
|
47
|
+
faraday (>= 0.8, < 0.10)
|
48
|
+
jwt (~> 1.0, < 1.5.2)
|
49
|
+
multi_json (~> 1.3)
|
50
|
+
multi_xml (~> 0.5)
|
51
|
+
rack (>= 1.2, < 3)
|
52
|
+
rack (1.6.4)
|
53
|
+
rake (11.1.2)
|
54
|
+
rdoc (4.2.2)
|
55
|
+
json (~> 1.4)
|
56
|
+
rspec (3.4.0)
|
57
|
+
rspec-core (~> 3.4.0)
|
58
|
+
rspec-expectations (~> 3.4.0)
|
59
|
+
rspec-mocks (~> 3.4.0)
|
60
|
+
rspec-core (3.4.4)
|
61
|
+
rspec-support (~> 3.4.0)
|
62
|
+
rspec-expectations (3.4.0)
|
63
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
+
rspec-support (~> 3.4.0)
|
65
|
+
rspec-mocks (3.4.1)
|
66
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
+
rspec-support (~> 3.4.0)
|
68
|
+
rspec-support (3.4.1)
|
69
|
+
safe_yaml (1.0.4)
|
70
|
+
satoshi-unit (0.1.8)
|
71
|
+
semver (1.0.1)
|
72
|
+
thread_safe (0.3.5)
|
73
|
+
vcr (3.0.3)
|
74
|
+
webmock (2.0.3)
|
75
|
+
addressable (>= 2.3.6)
|
76
|
+
crack (>= 0.3.2)
|
77
|
+
hashdiff
|
78
|
+
|
79
|
+
PLATFORMS
|
80
|
+
ruby
|
81
|
+
|
82
|
+
DEPENDENCIES
|
83
|
+
bundler (~> 1.0)
|
84
|
+
jeweler (~> 2.1.1)!
|
85
|
+
rspec
|
86
|
+
satoshi-unit
|
87
|
+
vcr
|
88
|
+
webmock
|
89
|
+
|
90
|
+
BUNDLED WITH
|
91
|
+
1.12.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 Roman Snitko
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
currency-rate
|
2
|
+
=============
|
3
|
+
|
4
|
+
Converter for fiat and crypto currencies
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
gem install currency-rate
|
10
|
+
|
11
|
+
or in Gemfile
|
12
|
+
|
13
|
+
gem "currency-rate"
|
14
|
+
|
15
|
+
Usage
|
16
|
+
-----
|
17
|
+
Basically, all you'll need is to use the top level class to fetch any rates you want.
|
18
|
+
For example:
|
19
|
+
|
20
|
+
CurrencyRate.convert('Bitstamp', amount: 5, from: 'BTC', to: 'USD')
|
21
|
+
CurrencyRate.convert('Bitstamp', amount: 2750, from: 'USD', to: 'BTC')
|
22
|
+
CurrencyRate.convert('Bitstamp', amount: 1000, from: 'USD', to: 'EUR')
|
23
|
+
|
24
|
+
In the third case, because Bitstamp doesn't really support direct conversion from
|
25
|
+
USD to EUR, the 1000 will first be converted to BTC, then the BTC amount will be converted to EUR.
|
26
|
+
|
27
|
+
This introduced the concept of anchor currency. For all Btc adapters in this lib, it's set to BTC
|
28
|
+
by default. For all Fiat adapters it's set to USD by default. To specify anchor currency manually,
|
29
|
+
simply pass it as another argument, for example:
|
30
|
+
|
31
|
+
CurrencyRate.convert('Bitstamp', amount: 1000, from: 'USD', to: 'EUR', anchor_currency: 'BTC')
|
32
|
+
|
33
|
+
For a list of available adapters, please see
|
34
|
+
[lib/btc_adapters](https://github.com/snitko/currency-rate/tree/master/lib/btc_adapters)
|
35
|
+
and [lib/fiat_adapters](https://github.com/snitko/currency-rate/tree/master/lib/fiat_adapters).
|
36
|
+
To specify an adapter for `#convert` or `#get`, remove the last `Adapter` part from its name.
|
37
|
+
|
38
|
+
Caching and Storage
|
39
|
+
-------------------
|
40
|
+
|
41
|
+
By default, a simple in-memory caching mechanism with a timeout of 1800 seconds is set.
|
42
|
+
To change the default timeout and also implement your very own caching mechanism you can
|
43
|
+
try reloading `CurrencyRate::Storage` methods and writing your own functionality,
|
44
|
+
storing data in Redis, for example.
|
45
|
+
|
46
|
+
While I agree it'd be nicer to have the timeout set somewhere in `CurrencyRate` class,
|
47
|
+
for simplicity reasons I've avoided that. It also makes sense that the `Storage` class is responsible
|
48
|
+
for how and when to store/fetch data, not other classes.
|
49
|
+
|
50
|
+
Credits
|
51
|
+
-------
|
52
|
+
This gem was extracted from [straight gem](https://github.com/MyceliumGear/straight), thanks to all the people who added various exchange rate adapters and contributed code.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
+
gem.name = "currency-rate"
|
18
|
+
gem.homepage = "http://github.com/snitko/currency-rate"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Converter for fiat and crypto currencies}
|
21
|
+
gem.description = %Q{Fetches exchange rates from various sources and does the conversion}
|
22
|
+
gem.email = "roman.snitko@gmail.com"
|
23
|
+
gem.authors = ["Roman Snitko"]
|
24
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: currency-rate 0.1.1 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "currency-rate"
|
9
|
+
s.version = "0.1.1"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Roman Snitko"]
|
14
|
+
s.date = "2016-06-18"
|
15
|
+
s.description = "Fetches exchange rates from various sources and does the conversion"
|
16
|
+
s.email = "roman.snitko@gmail.com"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"Gemfile.lock",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.md",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"currency-rate.gemspec",
|
31
|
+
"lib/adapter.rb",
|
32
|
+
"lib/btc_adapter.rb",
|
33
|
+
"lib/btc_adapters/average_rate_adapter.rb",
|
34
|
+
"lib/btc_adapters/bitpay_adapter.rb",
|
35
|
+
"lib/btc_adapters/bitstamp_adapter.rb",
|
36
|
+
"lib/btc_adapters/btce_adapter.rb",
|
37
|
+
"lib/btc_adapters/coinbase_adapter.rb",
|
38
|
+
"lib/btc_adapters/kraken_adapter.rb",
|
39
|
+
"lib/btc_adapters/localbitcoins_adapter.rb",
|
40
|
+
"lib/btc_adapters/okcoin_adapter.rb",
|
41
|
+
"lib/core_ext/classify.rb",
|
42
|
+
"lib/core_ext/deep_get.rb",
|
43
|
+
"lib/currency_rate.rb",
|
44
|
+
"lib/fiat_adapter.rb",
|
45
|
+
"lib/fiat_adapters/fixer_adapter.rb",
|
46
|
+
"lib/fiat_adapters/yahoo_adapter.rb",
|
47
|
+
"lib/storage.rb",
|
48
|
+
"spec/currency_rate_spec.rb",
|
49
|
+
"spec/lib/btc_adapter_spec.rb",
|
50
|
+
"spec/lib/btc_adapters/average_rate_adapter_spec.rb",
|
51
|
+
"spec/lib/btc_adapters/bitpay_adapter_spec.rb",
|
52
|
+
"spec/lib/btc_adapters/bitstamp_adapter_spec.rb",
|
53
|
+
"spec/lib/btc_adapters/btce_adapter_spec.rb",
|
54
|
+
"spec/lib/btc_adapters/coinbase_adapter_spec.rb",
|
55
|
+
"spec/lib/btc_adapters/kraken_adapter_spec.rb",
|
56
|
+
"spec/lib/btc_adapters/localbitcoins_adapter_spec.rb",
|
57
|
+
"spec/lib/btc_adapters/okcoin_adapter_spec.rb",
|
58
|
+
"spec/lib/fiat_adapters/fixer_adapter_spec.rb",
|
59
|
+
"spec/lib/fiat_adapters/yahoo_adapter_spec.rb",
|
60
|
+
"spec/lib/storage_spec.rb",
|
61
|
+
"spec/spec_helper.rb"
|
62
|
+
]
|
63
|
+
s.homepage = "http://github.com/snitko/currency-rate"
|
64
|
+
s.licenses = ["MIT"]
|
65
|
+
s.rubygems_version = "2.5.1"
|
66
|
+
s.summary = "Converter for fiat and crypto currencies"
|
67
|
+
|
68
|
+
if s.respond_to? :specification_version then
|
69
|
+
s.specification_version = 4
|
70
|
+
|
71
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
72
|
+
s.add_runtime_dependency(%q<satoshi-unit>, [">= 0"])
|
73
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
74
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.1.1"])
|
75
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<webmock>, [">= 0"])
|
77
|
+
s.add_development_dependency(%q<vcr>, [">= 0"])
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<satoshi-unit>, [">= 0"])
|
80
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
81
|
+
s.add_dependency(%q<jeweler>, ["~> 2.1.1"])
|
82
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
83
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
84
|
+
s.add_dependency(%q<vcr>, [">= 0"])
|
85
|
+
end
|
86
|
+
else
|
87
|
+
s.add_dependency(%q<satoshi-unit>, [">= 0"])
|
88
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
89
|
+
s.add_dependency(%q<jeweler>, ["~> 2.1.1"])
|
90
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
91
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
92
|
+
s.add_dependency(%q<vcr>, [">= 0"])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
data/lib/adapter.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module CurrencyRate
|
2
|
+
class Adapter
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
class FetchingFailed < Exception; end
|
6
|
+
class CurrencyNotSupported < Exception; end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@storage = Storage.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_rates!
|
13
|
+
raise "FETCH_URL is not defined!" unless self.class::FETCH_URL
|
14
|
+
uri = URI.parse(self.class::FETCH_URL)
|
15
|
+
begin
|
16
|
+
@rates = JSON.parse(uri.read(read_timeout: 4))
|
17
|
+
@rates_updated_at = Time.now
|
18
|
+
rescue OpenURI::HTTPError => e
|
19
|
+
raise FetchingFailed
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def rate_for(currency_code)
|
24
|
+
@storage.fetch(self.class.to_s) do
|
25
|
+
self.fetch_rates!
|
26
|
+
end
|
27
|
+
nil # this should be changed in descendant classes
|
28
|
+
end
|
29
|
+
|
30
|
+
# This method will get value we are interested in from hash and
|
31
|
+
# prevent failing with 'undefined method [] for Nil' if at some point hash doesn't have such key value pair
|
32
|
+
def get_rate_value_from_hash(rates_hash, *keys)
|
33
|
+
rates_hash.deep_get(*keys) || raise(CurrencyNotSupported)
|
34
|
+
end
|
35
|
+
|
36
|
+
# We dont want to have false positive rate, because nil.to_f is 0.0
|
37
|
+
# This method checks that rate value is not nil
|
38
|
+
def rate_to_f(rate)
|
39
|
+
rate ? rate.to_f : raise(CurrencyNotSupported)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/btc_adapter.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module CurrencyRate
|
2
|
+
|
3
|
+
class BtcAdapter < Adapter
|
4
|
+
|
5
|
+
def convert_from_currency(amount_in_currency, btc_denomination: :satoshi, currency: 'USD')
|
6
|
+
btc_amount = amount_in_currency.to_f/rate_for(currency)
|
7
|
+
Satoshi.new(btc_amount, from_unit: :btc, to_unit: btc_denomination).to_unit
|
8
|
+
end
|
9
|
+
|
10
|
+
def convert_to_currency(amount, btc_denomination: :satoshi, currency: 'USD')
|
11
|
+
amount_in_btc = Satoshi.new(amount.to_f, from_unit: btc_denomination).to_btc
|
12
|
+
amount_in_btc*rate_for(currency)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module CurrencyRate
|
2
|
+
class AverageRateAdapter < BtcAdapter
|
3
|
+
|
4
|
+
# Takes exchange rate adapters instances or classes as arguments
|
5
|
+
def self.instance(*adapters)
|
6
|
+
instance = super()
|
7
|
+
instance.instance_variable_set(:@adapters, adapters.map { |adapter| adapter.respond_to?(:instance) ? adapter.instance : adapter })
|
8
|
+
instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_rates!
|
12
|
+
failed_fetches = 0
|
13
|
+
@adapters.each do |adapter|
|
14
|
+
begin
|
15
|
+
adapter.fetch_rates!
|
16
|
+
rescue FetchingFailed => e
|
17
|
+
failed_fetches += 1
|
18
|
+
raise e if failed_fetches == @adapters.size
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def rate_for(currency_code)
|
24
|
+
rates = []
|
25
|
+
@adapters.each do |adapter|
|
26
|
+
begin
|
27
|
+
rates << adapter.rate_for(currency_code)
|
28
|
+
rescue CurrencyNotSupported
|
29
|
+
rates << nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
unless rates.select(&:nil?).size == @adapters.size
|
34
|
+
rates.compact!
|
35
|
+
rates.inject {|sum, rate| sum + rate} / rates.size
|
36
|
+
else
|
37
|
+
raise CurrencyNotSupported
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_rate_value_from_hash(rates_hash, *keys)
|
42
|
+
raise "This method is not supposed to be used in #{self.class}."
|
43
|
+
end
|
44
|
+
|
45
|
+
def rate_to_f(rate)
|
46
|
+
raise "This method is not supposed to be used in #{self.class}."
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CurrencyRate
|
2
|
+
class BitpayAdapter < BtcAdapter
|
3
|
+
|
4
|
+
FETCH_URL = 'https://bitpay.com/api/rates'
|
5
|
+
|
6
|
+
def rate_for(currency_code)
|
7
|
+
super
|
8
|
+
@rates.each do |rt|
|
9
|
+
if rt['code'] == currency_code
|
10
|
+
rate = get_rate_value_from_hash(rt, 'rate')
|
11
|
+
return rate_to_f(rate)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
raise CurrencyNotSupported
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|