money-open-exchange-rates 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.markdown +25 -0
- data/lib/money/bank/open_exchange_rates_bank.rb +54 -0
- data/test/latest.json +129 -0
- data/test/open_exchange_rates_bank_test.rb +76 -0
- data/test/test_helper.rb +4 -0
- metadata +99 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Laurent Arnoud <laurent@spkdev.net>
|
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 NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Money Open Exchange Rates
|
2
|
+
|
3
|
+
A gem that calculates the exchange rate using published rates from [open-exchange-rates](http://josscrowcroft.github.com/open-exchange-rates/)
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'money/bank/open_exchange_rates_bank'
|
9
|
+
moe = Money::Bank::OpenExchangeRatesBank.new
|
10
|
+
moe.cache = 'path/to/file/cache'
|
11
|
+
|
12
|
+
Money.default_bank = moe
|
13
|
+
```
|
14
|
+
|
15
|
+
## Refs
|
16
|
+
|
17
|
+
* https://github.com/currencybot/open-exchange-rates
|
18
|
+
* https://github.com/RubyMoney/money
|
19
|
+
* https://github.com/RubyMoney/eu_central_bank
|
20
|
+
* https://github.com/RubyMoney/google_currency
|
21
|
+
|
22
|
+
## License
|
23
|
+
The MIT License
|
24
|
+
|
25
|
+
Copyright © 2011 Laurent Arnoud <laurent@spkdev.net>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'open-uri'
|
3
|
+
require 'yajl'
|
4
|
+
require 'money'
|
5
|
+
|
6
|
+
class Money
|
7
|
+
module Bank
|
8
|
+
class InvalidCache < StandardError ; end
|
9
|
+
|
10
|
+
class OpenExchangeRatesBank < Money::Bank::VariableExchange
|
11
|
+
|
12
|
+
OER_URL = 'http://openexchangerates.org/latest.php'
|
13
|
+
|
14
|
+
attr_accessor :cache
|
15
|
+
attr_reader :doc, :oer_rates, :rates_source
|
16
|
+
|
17
|
+
def update_rates
|
18
|
+
exchange_rates.each do |exchange_rate|
|
19
|
+
rate = exchange_rate.last
|
20
|
+
currency = exchange_rate.first
|
21
|
+
set_rate('USD', currency, rate)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_rates
|
26
|
+
raise InvalidCache unless cache
|
27
|
+
open(cache, 'w').write(open(OER_URL).read)
|
28
|
+
end
|
29
|
+
|
30
|
+
def exchange(cents, from_currency, to_currency)
|
31
|
+
exchange_with(Money.new(cents, from_currency), to_currency)
|
32
|
+
end
|
33
|
+
|
34
|
+
def exchange_with(from, to_currency)
|
35
|
+
rate = get_rate(from.currency, to_currency)
|
36
|
+
unless rate
|
37
|
+
from_base_rate = get_rate("USD", from.currency)
|
38
|
+
to_base_rate = get_rate("USD", to_currency)
|
39
|
+
rate = to_base_rate / from_base_rate
|
40
|
+
end
|
41
|
+
Money.new(((Money::Currency.wrap(to_currency).subunit_to_unit.to_f / from.currency.subunit_to_unit.to_f) * from.cents * rate).round, to_currency)
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def exchange_rates
|
47
|
+
@rates_source = !!cache ? cache : OER_URL
|
48
|
+
@doc = Yajl::Parser.parse(open(rates_source).read)
|
49
|
+
@oer_rates = @doc['rates']
|
50
|
+
@doc['rates']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/latest.json
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
{
|
2
|
+
"disclaimer": "This data is collected from various providers and provided free of charge for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability or fitness for any purpose; use at your own risk. Other than that - have fun, and please share/watch/fork if you think data like this should be free!",
|
3
|
+
"license": "all code open-source under GPL v3 [http://www.opensource.org/licenses/GPL-3.0]. all data made available by various providers; copyright may apply; not for resale; no warranties given.",
|
4
|
+
"timestamp": 1318931535,
|
5
|
+
"base": "USD",
|
6
|
+
"rates": {
|
7
|
+
"AED": 3.67000274,
|
8
|
+
"ALL": 103.01253573,
|
9
|
+
"ANG": 1.79614315,
|
10
|
+
"ARS": 4.22279733,
|
11
|
+
"AUD": 0.985166,
|
12
|
+
"AWG": 1.788773,
|
13
|
+
"BBD": 1.99964999,
|
14
|
+
"BDT": 76.15338649,
|
15
|
+
"BGN": 1.41994959,
|
16
|
+
"BHD": 0.37704772,
|
17
|
+
"BIF": 1218.55496226,
|
18
|
+
"BMD": 0.99949722,
|
19
|
+
"BND": 1.27225861,
|
20
|
+
"BOB": 6.91736836,
|
21
|
+
"BRL": 1.77381475,
|
22
|
+
"BSD": 0.99954175,
|
23
|
+
"BTN": 49.05028406,
|
24
|
+
"BYR": 7308.49243258,
|
25
|
+
"BZD": 1.98384726,
|
26
|
+
"CAD": 1.02336071,
|
27
|
+
"CHF": 0.90167657,
|
28
|
+
"CLP": 487.11197257,
|
29
|
+
"CNY": 6.38085304,
|
30
|
+
"COP": 1826.6698892,
|
31
|
+
"CRC": 521.8990447,
|
32
|
+
"CZK": 18.0694024,
|
33
|
+
"DKK": 5.44049406,
|
34
|
+
"DOP": 38.25438217,
|
35
|
+
"DZD": 73.81094439,
|
36
|
+
"EEK": 12.07815511,
|
37
|
+
"EGP": 5.97000248,
|
38
|
+
"ETB": 17.19251636,
|
39
|
+
"EUR": 0.73062465,
|
40
|
+
"FJD": 1.83036833,
|
41
|
+
"GBP": 0.63603926,
|
42
|
+
"GMD": 28.76426182,
|
43
|
+
"GNF": 7306.12192981,
|
44
|
+
"GTQ": 7.83918646,
|
45
|
+
"HKD": 7.77640265,
|
46
|
+
"HNL": 18.87502384,
|
47
|
+
"HRK": 5.45529344,
|
48
|
+
"HTG": 40.35709926,
|
49
|
+
"HUF": 214.84221403,
|
50
|
+
"IDR": 7306.81897687,
|
51
|
+
"ILS": 3.64949785,
|
52
|
+
"INR": 49.37039746,
|
53
|
+
"IQD": 1217.80316493,
|
54
|
+
"IRR": 7307.93452885,
|
55
|
+
"ISK": 115.9989631,
|
56
|
+
"JMD": 85.97569959,
|
57
|
+
"JOD": 0.70868135,
|
58
|
+
"JPY": 76.72400038,
|
59
|
+
"KES": 98.76466584,
|
60
|
+
"KMF": 365.42927124,
|
61
|
+
"KRW": 1218.09757292,
|
62
|
+
"KWD": 0.27560788,
|
63
|
+
"KYD": 0.81903871,
|
64
|
+
"KZT": 149.11496117,
|
65
|
+
"LBP": 1461.32661693,
|
66
|
+
"LKR": 110.70093173,
|
67
|
+
"LSL": 8.0465418,
|
68
|
+
"LTL": 2.52287977,
|
69
|
+
"LVL": 0.51543231,
|
70
|
+
"MAD": 8.21085207,
|
71
|
+
"MDL": 11.61789383,
|
72
|
+
"MKD": 44.55887535,
|
73
|
+
"MNT": 1217.94260361,
|
74
|
+
"MOP": 8.00333931,
|
75
|
+
"MRO": 292.28205422,
|
76
|
+
"MUR": 28.88162297,
|
77
|
+
"MVR": 15.31876757,
|
78
|
+
"MWK": 166.11689667,
|
79
|
+
"MXN": 13.51340243,
|
80
|
+
"MYR": 3.13293632,
|
81
|
+
"NAD": 8.04971592,
|
82
|
+
"NGN": 162.42231002,
|
83
|
+
"NIO": 22.76948135,
|
84
|
+
"NOK": 5.65814755,
|
85
|
+
"NPR": 78.5914389,
|
86
|
+
"NZD": 1.26937516,
|
87
|
+
"OMR": 0.38491346,
|
88
|
+
"PAB": 0.99933189,
|
89
|
+
"PEN": 2.72220031,
|
90
|
+
"PGK": 2.17003989,
|
91
|
+
"PHP": 43.24670259,
|
92
|
+
"PKR": 87.00825226,
|
93
|
+
"PLN": 3.17724869,
|
94
|
+
"PYG": 3655.78872997,
|
95
|
+
"QAR": 3.64122541,
|
96
|
+
"RON": 3.18309814,
|
97
|
+
"RUB": 31.24605524,
|
98
|
+
"RWF": 609.18567356,
|
99
|
+
"SAR": 3.7488354,
|
100
|
+
"SBD": 7.38406858,
|
101
|
+
"SCR": 12.62561094,
|
102
|
+
"SEK": 6.69630223,
|
103
|
+
"SGD": 1.27495292,
|
104
|
+
"SKK": 22.07966229,
|
105
|
+
"SLL": 3654.18384486,
|
106
|
+
"SVC": 8.74162128,
|
107
|
+
"SZL": 8.05732772,
|
108
|
+
"THB": 30.70586701,
|
109
|
+
"TND": 1.42622659,
|
110
|
+
"TOP": 1.70695633,
|
111
|
+
"TRY": 1.86605172,
|
112
|
+
"TTD": 6.40445307,
|
113
|
+
"TWD": 30.07194885,
|
114
|
+
"TZS": 1826.90594941,
|
115
|
+
"UAH": 8.00396967,
|
116
|
+
"UGX": 2435.87459922,
|
117
|
+
"USD": 1,
|
118
|
+
"UYU": 19.97292206,
|
119
|
+
"VUV": 92.53276399,
|
120
|
+
"WST": 2.28297876,
|
121
|
+
"XAF": 487.33923469,
|
122
|
+
"XCD": 2.69810192,
|
123
|
+
"XOF": 487.27721607,
|
124
|
+
"XPF": 85.9900992,
|
125
|
+
"YER": 214.97524163,
|
126
|
+
"ZAR": 8.05499975,
|
127
|
+
"ZMK": 3636.84384705
|
128
|
+
}
|
129
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
4
|
+
|
5
|
+
describe Money::Bank::OpenExchangeRatesBank do
|
6
|
+
|
7
|
+
describe 'update_rates' do
|
8
|
+
before do
|
9
|
+
@cache_path = File.expand_path(File.join(File.dirname(__FILE__), 'latest.json'))
|
10
|
+
@bank = Money::Bank::OpenExchangeRatesBank.new
|
11
|
+
@bank.cache = @cache_path
|
12
|
+
@bank.update_rates
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should update itself with exchange rates from OpenExchangeRates" do
|
16
|
+
@bank.oer_rates.keys.each do |currency|
|
17
|
+
@bank.get_rate("USD", currency).must_be :>, 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return the correct oer rates using oer" do
|
22
|
+
@bank.update_rates
|
23
|
+
@bank.oer_rates.keys.each do |currency|
|
24
|
+
subunit = Money::Currency.wrap(currency).subunit_to_unit
|
25
|
+
@bank.exchange(100, "USD", currency).cents.must_equal (@bank.oer_rates[currency].to_f * subunit).round
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the correct oer rates using exchange_with" do
|
30
|
+
@bank.update_rates
|
31
|
+
@bank.oer_rates.keys.each do |currency|
|
32
|
+
subunit = Money::Currency.wrap(currency).subunit_to_unit
|
33
|
+
@bank.exchange_with(Money.new(100, "USD"), currency).cents.must_equal (@bank.oer_rates[currency].to_f * subunit).round
|
34
|
+
@bank.exchange_with(1.to_money("USD"), currency).cents.must_equal (@bank.oer_rates[currency].to_f * subunit).round
|
35
|
+
end
|
36
|
+
@bank.exchange_with(5000.to_money('JPY'), 'USD').cents.must_equal 6517
|
37
|
+
end
|
38
|
+
|
39
|
+
# in response to #4
|
40
|
+
it "should exchange btc" do
|
41
|
+
Money::Currency::TABLE[:btc] = {
|
42
|
+
:priority => 1,
|
43
|
+
:iso_code => "BTC",
|
44
|
+
:name => "Bitcoin",
|
45
|
+
:symbol => "BTC",
|
46
|
+
:subunit => "Cent",
|
47
|
+
:subunit_to_unit => 1000,
|
48
|
+
:separator => ".",
|
49
|
+
:delimiter => ","
|
50
|
+
}
|
51
|
+
@bank.add_rate("USD", "BTC", 1 / 13.7603)
|
52
|
+
@bank.add_rate("BTC", "USD", 13.7603)
|
53
|
+
@bank.exchange(100, "BTC", "USD").cents.must_equal 138
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'no cache' do
|
58
|
+
include RR::Adapters::TestUnit
|
59
|
+
|
60
|
+
before do
|
61
|
+
@bank = Money::Bank::OpenExchangeRatesBank.new
|
62
|
+
@bank.cache = nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should get from url' do
|
66
|
+
stub(OpenURI::OpenRead).open(Money::Bank::OpenExchangeRatesBank::OER_URL) { File.read @cache_path }
|
67
|
+
@bank.update_rates
|
68
|
+
@bank.rates_source.must_equal Money::Bank::OpenExchangeRatesBank::OER_URL
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should raise an error if invalid path is given to save_rates' do
|
72
|
+
proc { @bank.save_rates }.must_raise Money::Bank::InvalidCache
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: money-open-exchange-rates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Laurent Arnoud
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-18 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: yajl-ruby
|
16
|
+
requirement: &19606860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.8.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *19606860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: money
|
27
|
+
requirement: &19605560 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.7.1
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *19605560
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: minitest
|
38
|
+
requirement: &19604500 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *19604500
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rr
|
49
|
+
requirement: &19603220 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *19603220
|
58
|
+
description: A gem that calculates the exchange rate using published rates from open-exchange-rates.
|
59
|
+
Compatible with the money gem.
|
60
|
+
email: laurent@spkdev.net
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files:
|
64
|
+
- README.markdown
|
65
|
+
files:
|
66
|
+
- LICENSE
|
67
|
+
- README.markdown
|
68
|
+
- Gemfile
|
69
|
+
- lib/money/bank/open_exchange_rates_bank.rb
|
70
|
+
- test/latest.json
|
71
|
+
- test/test_helper.rb
|
72
|
+
- test/open_exchange_rates_bank_test.rb
|
73
|
+
homepage: http://github.com/spk/money-open-exchange-rates
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.7.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: A gem that calculates the exchange rate using published rates from open-exchange-rates.
|
97
|
+
test_files:
|
98
|
+
- test/open_exchange_rates_bank_test.rb
|
99
|
+
has_rdoc:
|