currency 0.3.3 → 0.4.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/COPYING.txt +339 -0
- data/LICENSE.txt +62 -0
- data/Manifest.txt +37 -14
- data/README.txt +8 -0
- data/Rakefile +42 -8
- data/Releases.txt +26 -0
- data/TODO.txt +1 -0
- data/examples/ex1.rb +3 -3
- data/examples/xe1.rb +3 -2
- data/lib/currency.rb +71 -9
- data/lib/currency/active_record.rb +138 -21
- data/lib/currency/core_extensions.rb +7 -5
- data/lib/currency/currency.rb +94 -177
- data/lib/currency/{currency_factory.rb → currency/factory.rb} +46 -25
- data/lib/currency/currency_version.rb +3 -3
- data/lib/currency/exception.rb +14 -14
- data/lib/currency/exchange.rb +14 -12
- data/lib/currency/exchange/rate.rb +159 -28
- data/lib/currency/exchange/rate/deriver.rb +146 -0
- data/lib/currency/exchange/rate/source.rb +84 -0
- data/lib/currency/exchange/rate/source/base.rb +156 -0
- data/lib/currency/exchange/rate/source/failover.rb +57 -0
- data/lib/currency/exchange/rate/source/historical.rb +79 -0
- data/lib/currency/exchange/rate/source/historical/rate.rb +181 -0
- data/lib/currency/exchange/rate/source/historical/writer.rb +203 -0
- data/lib/currency/exchange/rate/source/new_york_fed.rb +91 -0
- data/lib/currency/exchange/rate/source/provider.rb +105 -0
- data/lib/currency/exchange/rate/source/test.rb +50 -0
- data/lib/currency/exchange/rate/source/the_financials.rb +190 -0
- data/lib/currency/exchange/rate/source/timed_cache.rb +144 -0
- data/lib/currency/exchange/rate/source/xe.rb +166 -0
- data/lib/currency/exchange/time_quantitizer.rb +111 -0
- data/lib/currency/formatter.rb +159 -0
- data/lib/currency/macro.rb +321 -0
- data/lib/currency/money.rb +90 -64
- data/lib/currency/money_helper.rb +6 -5
- data/lib/currency/parser.rb +153 -0
- data/test/ar_column_test.rb +6 -3
- data/test/ar_simple_test.rb +5 -2
- data/test/ar_test_base.rb +39 -33
- data/test/ar_test_core.rb +64 -0
- data/test/formatter_test.rb +81 -0
- data/test/historical_writer_test.rb +184 -0
- data/test/macro_test.rb +109 -0
- data/test/money_test.rb +72 -4
- data/test/new_york_fed_test.rb +57 -0
- data/test/parser_test.rb +60 -0
- data/test/test_base.rb +13 -3
- data/test/time_quantitizer_test.rb +136 -0
- data/test/xe_test.rb +29 -5
- metadata +41 -18
- data/lib/currency/exchange/base.rb +0 -84
- data/lib/currency/exchange/test.rb +0 -39
- data/lib/currency/exchange/xe.rb +0 -250
data/test/xe_test.rb
CHANGED
@@ -1,29 +1,53 @@
|
|
1
|
+
# Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
|
2
|
+
# See LICENSE.txt for details.
|
3
|
+
|
1
4
|
require 'test/test_base'
|
5
|
+
|
2
6
|
require 'currency' # For :type => :money
|
3
|
-
require 'currency/exchange/xe'
|
7
|
+
require 'currency/exchange/rate/source/xe'
|
4
8
|
|
5
9
|
module Currency
|
6
10
|
|
7
11
|
class XeTest < TestBase
|
8
12
|
def setup
|
9
13
|
super
|
10
|
-
# Force XE Exchange.
|
11
|
-
Exchange.default = Exchange::Xe.instance
|
12
14
|
end
|
13
15
|
|
16
|
+
|
17
|
+
def get_rate_source
|
18
|
+
source = Exchange::Rate::Source::Xe.new
|
19
|
+
deriver = Exchange::Rate::Deriver.new(:source => source)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
14
23
|
def test_xe_usd_cad
|
15
|
-
assert_not_nil rates = Exchange.default.
|
24
|
+
assert_not_nil rates = Exchange::Rate::Source.default.source.raw_rates
|
16
25
|
assert_not_nil rates[:USD]
|
17
26
|
assert_not_nil usd_cad = rates[:USD][:CAD]
|
18
27
|
|
19
28
|
assert_not_nil usd = Money.new(123.45, :USD)
|
20
29
|
assert_not_nil cad = usd.convert(:CAD)
|
21
30
|
|
22
|
-
assert_kind_of Numeric, m = (cad.
|
31
|
+
assert_kind_of Numeric, m = (cad.to_f / usd.to_f)
|
23
32
|
# $stderr.puts "m = #{m}"
|
24
33
|
assert_equal_float usd_cad, m, 0.001
|
25
34
|
end
|
26
35
|
|
36
|
+
|
37
|
+
def test_xe_cad_eur
|
38
|
+
assert_not_nil rates = Exchange::Rate::Source.default.source.raw_rates
|
39
|
+
assert_not_nil rates[:USD]
|
40
|
+
assert_not_nil usd_cad = rates[:USD][:CAD]
|
41
|
+
assert_not_nil usd_eur = rates[:USD][:EUR]
|
42
|
+
|
43
|
+
assert_not_nil cad = Money.new(123.45, :CAD)
|
44
|
+
assert_not_nil eur = cad.convert(:EUR)
|
45
|
+
|
46
|
+
assert_kind_of Numeric, m = (eur.to_f / cad.to_f)
|
47
|
+
# $stderr.puts "m = #{m}"
|
48
|
+
assert_equal_float (1.0 / usd_cad) * usd_eur, m, 0.001
|
49
|
+
end
|
50
|
+
|
27
51
|
end
|
28
52
|
|
29
53
|
end # module
|
metadata
CHANGED
@@ -3,16 +3,16 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: currency
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date:
|
8
|
-
summary: Currency models currencies, monetary values, foreign exchanges and rates. Supports ActiveRecord.
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2007-02-21 00:00:00 -05:00
|
8
|
+
summary: "Currency models currencies, monetary values, foreign exchanges and rates. Pulls live rates from http://xe.com/. Supports ActiveRecord. For more details, see: http://currency.rubyforge.org/files/lib/currency_rb.html http://currency.rubyforge.org/files/README.txt http://currency.rubyforge.org/"
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
- test
|
12
12
|
email: ruby-currency@umleta.com
|
13
13
|
homepage: http://rubyforge.org/projects/currency
|
14
14
|
rubyforge_project: currency
|
15
|
-
description: Currency models currencies, monetary values, foreign exchanges and rates. Supports ActiveRecord.
|
15
|
+
description: "Currency models currencies, monetary values, foreign exchanges and rates. Pulls live rates from http://xe.com/. Supports ActiveRecord. For more details, see: http://currency.rubyforge.org/files/lib/currency_rb.html http://currency.rubyforge.org/files/README.txt http://currency.rubyforge.org/"
|
16
16
|
autorequire:
|
17
17
|
default_executable:
|
18
18
|
bindir: bin
|
@@ -30,34 +30,57 @@ post_install_message:
|
|
30
30
|
authors:
|
31
31
|
- Kurt Stephens
|
32
32
|
files:
|
33
|
+
- COPYING.txt
|
33
34
|
- ChangeLog
|
35
|
+
- LICENSE.txt
|
36
|
+
- Manifest.txt
|
37
|
+
- README.txt
|
38
|
+
- Rakefile
|
39
|
+
- Releases.txt
|
40
|
+
- TODO.txt
|
34
41
|
- examples/ex1.rb
|
35
42
|
- examples/xe1.rb
|
43
|
+
- lib/currency.rb
|
36
44
|
- lib/currency/active_record.rb
|
37
45
|
- lib/currency/core_extensions.rb
|
38
|
-
- lib/currency/currency_factory.rb
|
39
46
|
- lib/currency/currency.rb
|
47
|
+
- lib/currency/currency/factory.rb
|
40
48
|
- lib/currency/currency_version.rb
|
41
49
|
- lib/currency/exception.rb
|
42
|
-
- lib/currency/exchange/base.rb
|
43
|
-
- lib/currency/exchange/rate.rb
|
44
50
|
- lib/currency/exchange.rb
|
45
|
-
- lib/currency/exchange/
|
46
|
-
- lib/currency/exchange/
|
47
|
-
- lib/currency/
|
51
|
+
- lib/currency/exchange/rate.rb
|
52
|
+
- lib/currency/exchange/rate/deriver.rb
|
53
|
+
- lib/currency/exchange/rate/source.rb
|
54
|
+
- lib/currency/exchange/rate/source/base.rb
|
55
|
+
- lib/currency/exchange/rate/source/failover.rb
|
56
|
+
- lib/currency/exchange/rate/source/historical.rb
|
57
|
+
- lib/currency/exchange/rate/source/historical/rate.rb
|
58
|
+
- lib/currency/exchange/rate/source/historical/writer.rb
|
59
|
+
- lib/currency/exchange/rate/source/new_york_fed.rb
|
60
|
+
- lib/currency/exchange/rate/source/provider.rb
|
61
|
+
- lib/currency/exchange/rate/source/test.rb
|
62
|
+
- lib/currency/exchange/rate/source/the_financials.rb
|
63
|
+
- lib/currency/exchange/rate/source/timed_cache.rb
|
64
|
+
- lib/currency/exchange/rate/source/xe.rb
|
65
|
+
- lib/currency/exchange/time_quantitizer.rb
|
66
|
+
- lib/currency/formatter.rb
|
67
|
+
- lib/currency/macro.rb
|
48
68
|
- lib/currency/money.rb
|
49
|
-
- lib/currency.rb
|
50
|
-
-
|
51
|
-
- Rakefile
|
52
|
-
- README.txt
|
53
|
-
- Releases.txt
|
54
|
-
- test/ar_test_base.rb
|
55
|
-
- test/ar_simple_test.rb
|
69
|
+
- lib/currency/money_helper.rb
|
70
|
+
- lib/currency/parser.rb
|
56
71
|
- test/ar_column_test.rb
|
72
|
+
- test/ar_simple_test.rb
|
73
|
+
- test/ar_test_base.rb
|
74
|
+
- test/ar_test_core.rb
|
75
|
+
- test/formatter_test.rb
|
76
|
+
- test/historical_writer_test.rb
|
77
|
+
- test/macro_test.rb
|
57
78
|
- test/money_test.rb
|
79
|
+
- test/new_york_fed_test.rb
|
80
|
+
- test/parser_test.rb
|
58
81
|
- test/test_base.rb
|
82
|
+
- test/time_quantitizer_test.rb
|
59
83
|
- test/xe_test.rb
|
60
|
-
- TODO.txt
|
61
84
|
test_files: []
|
62
85
|
|
63
86
|
rdoc_options: []
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
#
|
3
|
-
# = Currency::Exchange::Base
|
4
|
-
#
|
5
|
-
# The Currency::Exchange::Base class is the base class for
|
6
|
-
# currency exchange rate providers.
|
7
|
-
#
|
8
|
-
# Currency::Exchange::Base subclasses are Currency::Exchange::Rate
|
9
|
-
# factories.
|
10
|
-
#
|
11
|
-
|
12
|
-
module Currency
|
13
|
-
module Exchange
|
14
|
-
|
15
|
-
# Represents a method of converting between two currencies
|
16
|
-
class Base
|
17
|
-
|
18
|
-
# The name of this Exchange.
|
19
|
-
attr_accessor :name
|
20
|
-
|
21
|
-
# If true, this Exchange will log information.
|
22
|
-
attr_accessor :verbose
|
23
|
-
|
24
|
-
def initialize(*opt)
|
25
|
-
@name = nil
|
26
|
-
@rate = { }
|
27
|
-
opt = Hash[*opt]
|
28
|
-
opt.each{|k,v| self.send(k, v)}
|
29
|
-
end
|
30
|
-
|
31
|
-
# Converts Money m in Currency c1 to a new
|
32
|
-
# Money value in Currency c2.
|
33
|
-
def convert(m, c2, c1 = nil)
|
34
|
-
c1 = m.currency if c1 == nil
|
35
|
-
if ( c1 == c2 )
|
36
|
-
m
|
37
|
-
else
|
38
|
-
Money.new(rate(c1, c2).convert(m, c1), c2)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Flush all cached Rate.
|
43
|
-
def clear_rates
|
44
|
-
@rate.clear
|
45
|
-
end
|
46
|
-
|
47
|
-
# Flush any cached Rate between Currency c1 and c2.
|
48
|
-
def clear_rate(c1, c2, recip = true)
|
49
|
-
@rate[c1.code.to_s + c2.code.to_s] = nil
|
50
|
-
@rate[c2.code.to_s + c1.code.to_s] = nil if recip
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the Rate between Currency c1 and c2.
|
54
|
-
#
|
55
|
-
# This will call #get_rate(c1, c2) if the
|
56
|
-
# Rate has not already been cached.
|
57
|
-
#
|
58
|
-
# Subclasses can override this method to implement
|
59
|
-
# rate expiration rules.
|
60
|
-
#
|
61
|
-
def rate(c1, c2)
|
62
|
-
(@rate[c1.code.to_s + c2.code.to_s] ||= get_rate(c1, c2)) ||
|
63
|
-
(@rate[c2.code.to_s + c1.code.to_s] ||= get_rate(c2, c1))
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
# Determines and creates the Rate between Currency c1 and c2.
|
68
|
-
#
|
69
|
-
# Subclasses are required to implement this method.
|
70
|
-
def get_rate(c1, c2)
|
71
|
-
raise Exception::UnknownRate.new("Subclass responsibility: get_rate")
|
72
|
-
end
|
73
|
-
|
74
|
-
# Returns a simple string rep of an Exchange object.
|
75
|
-
def to_s
|
76
|
-
"#<#{self.class.name} #{self.name && self.name.inspect}>"
|
77
|
-
end
|
78
|
-
|
79
|
-
end # class
|
80
|
-
|
81
|
-
|
82
|
-
end # module
|
83
|
-
end # module
|
84
|
-
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# This class is a test Exchange.
|
2
|
-
# It can convert only between USD and CAD.
|
3
|
-
|
4
|
-
module Currency
|
5
|
-
module Exchange
|
6
|
-
|
7
|
-
class Test < Base
|
8
|
-
@@instance = nil
|
9
|
-
|
10
|
-
# Returns a singleton instance.
|
11
|
-
def self.instance(*opts)
|
12
|
-
@@instance ||= self.new(*opts)
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(*opts)
|
16
|
-
super(*opts)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Test rate from :USD to :CAD.
|
20
|
-
def self.USD_CAD; 1.1708; end
|
21
|
-
|
22
|
-
# Returns test Rate for USD and CAD pairs.
|
23
|
-
def get_rate(c1, c2)
|
24
|
-
# $stderr.puts "load_exchange_rate(#{c1}, #{c2})"
|
25
|
-
rate = 0.0
|
26
|
-
if ( c1.code == :USD && c2.code == :CAD )
|
27
|
-
rate = self.class.USD_CAD
|
28
|
-
end
|
29
|
-
rate > 0 ? Rate.new(c1, c2, rate, self) : nil
|
30
|
-
end
|
31
|
-
|
32
|
-
end # class
|
33
|
-
|
34
|
-
end # module
|
35
|
-
end # module
|
36
|
-
|
37
|
-
# Install as default.
|
38
|
-
Currency::Exchange.default = Currency::Exchange::Test.instance
|
39
|
-
|
data/lib/currency/exchange/xe.rb
DELETED
@@ -1,250 +0,0 @@
|
|
1
|
-
# Connects to http://xe.com and parses "XE.com Quick Cross Rates"
|
2
|
-
# from home page HTML.
|
3
|
-
|
4
|
-
require 'net/http'
|
5
|
-
require 'open-uri'
|
6
|
-
|
7
|
-
module Currency
|
8
|
-
module Exchange
|
9
|
-
|
10
|
-
class Xe < Base
|
11
|
-
@@instance = nil
|
12
|
-
# Returns a singleton instance.
|
13
|
-
def self.instance(*opts)
|
14
|
-
@@instance ||= self.new(*opts)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Defaults to "http://xe.com/"
|
18
|
-
attr_accessor :uri
|
19
|
-
|
20
|
-
# Defines the number of seconds rates until rates
|
21
|
-
# become invalid, causing a request of new rates.
|
22
|
-
#
|
23
|
-
# Defaults to 600 seconds.
|
24
|
-
attr_accessor :time_to_live
|
25
|
-
|
26
|
-
# Defines the number of random seconds to add before
|
27
|
-
# rates become invalid.
|
28
|
-
#
|
29
|
-
# Defaults to 30 seconds.
|
30
|
-
attr_accessor :time_to_live_fudge
|
31
|
-
|
32
|
-
# This Exchange's name is the same as its #uri.
|
33
|
-
def name
|
34
|
-
uri
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(*opt)
|
38
|
-
self.uri = 'http://xe.com/'
|
39
|
-
self.time_to_live = 600
|
40
|
-
self.time_to_live_fudge = 30
|
41
|
-
@xe_rates = nil
|
42
|
-
super(*opt)
|
43
|
-
end
|
44
|
-
|
45
|
-
def clear_rates
|
46
|
-
@xe_rates && @xe_rates.clear
|
47
|
-
super
|
48
|
-
end
|
49
|
-
|
50
|
-
def expired?
|
51
|
-
if @time_to_live &&
|
52
|
-
@xe_rates_renew_time &&
|
53
|
-
(Time.now > @xe_rates_renew_time)
|
54
|
-
|
55
|
-
if @xe_rates
|
56
|
-
$stderr.puts "#{self}: rates expired on #{@xe_rates_renew_time}" if @verbose
|
57
|
-
|
58
|
-
@old_rates ||= @xe_rates
|
59
|
-
|
60
|
-
@xe_rates = nil
|
61
|
-
end
|
62
|
-
|
63
|
-
true
|
64
|
-
else
|
65
|
-
false
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Check expired? before returning a Rate.
|
70
|
-
def rate(c1, c2)
|
71
|
-
if expired?
|
72
|
-
clear_rates
|
73
|
-
end
|
74
|
-
super(c1, c2)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns a cached Hash of rates:
|
78
|
-
#
|
79
|
-
# xe.xe_rates[:USD][:CAD] => 1.0134
|
80
|
-
#
|
81
|
-
def xe_rates
|
82
|
-
old_rates = nil
|
83
|
-
# Check expiration.
|
84
|
-
expired?
|
85
|
-
|
86
|
-
# Return rates, if cached.
|
87
|
-
return @xe_rates if @xe_rates
|
88
|
-
|
89
|
-
# Force load of rates
|
90
|
-
@xe_rates = xe_rates_load
|
91
|
-
|
92
|
-
# Flush old rates.
|
93
|
-
@old_rates = nil
|
94
|
-
|
95
|
-
# Update expiration.
|
96
|
-
if time_to_live
|
97
|
-
@xe_rates_renew_time = @rate_timestamp + (time_to_live + (time_to_live_fudge || 0))
|
98
|
-
$stderr.puts "#{self}: rates expire on #{@xe_rates_renew_time}" if @verbose
|
99
|
-
end
|
100
|
-
|
101
|
-
@xe_rates
|
102
|
-
end
|
103
|
-
|
104
|
-
def xe_rates_load
|
105
|
-
# Do not allow re-entrancy
|
106
|
-
raise "Reentrant!" if @processing_rates
|
107
|
-
|
108
|
-
# Begin processing new rate request.
|
109
|
-
@processing_rates = true
|
110
|
-
|
111
|
-
# Clear cached Rates.
|
112
|
-
clear_rates
|
113
|
-
|
114
|
-
# Parse rates from HTML page.
|
115
|
-
rates = parse_page_rates
|
116
|
-
|
117
|
-
unless rates
|
118
|
-
# FIXME: raise Exception::???
|
119
|
-
return rates
|
120
|
-
end
|
121
|
-
|
122
|
-
# Compute new rate timeps
|
123
|
-
@rate_timestamp = Time.now # TODO: Extract this from HTML page!
|
124
|
-
|
125
|
-
# End processsing new rate request.
|
126
|
-
@processing_rates = false
|
127
|
-
|
128
|
-
rates
|
129
|
-
end
|
130
|
-
|
131
|
-
|
132
|
-
# Returns the URI content.
|
133
|
-
def get_page
|
134
|
-
data = open(uri) { |data| data.read }
|
135
|
-
|
136
|
-
data = data.split(/[\r\n]/)
|
137
|
-
|
138
|
-
data
|
139
|
-
end
|
140
|
-
|
141
|
-
# Parses http://xe.com homepage HTML for
|
142
|
-
# quick rates of 10 currencies.
|
143
|
-
def parse_page_rates(data = nil)
|
144
|
-
data = get_page unless data
|
145
|
-
|
146
|
-
# Chomp after
|
147
|
-
until data.empty?
|
148
|
-
line = data.pop
|
149
|
-
break if line =~ /Need More currencies\?/
|
150
|
-
end
|
151
|
-
|
152
|
-
# Chomp before
|
153
|
-
until data.empty?
|
154
|
-
line = data.shift
|
155
|
-
break if line =~ /XE.com Quick Cross Rates/
|
156
|
-
end
|
157
|
-
|
158
|
-
until data.empty?
|
159
|
-
line = data.shift
|
160
|
-
break if line =~ /Confused about how to use the rates/i
|
161
|
-
end
|
162
|
-
|
163
|
-
until data.empty?
|
164
|
-
line = data.shift
|
165
|
-
break if line =~ /^\s*<\/tr>/i
|
166
|
-
end
|
167
|
-
# $stderr.puts "#{data[0..4].inspect}"
|
168
|
-
|
169
|
-
# Read first table row to get position for each currency
|
170
|
-
currency = [ ]
|
171
|
-
until data.empty?
|
172
|
-
line = data.shift
|
173
|
-
break if line =~ /^\s*<\/tr>/i
|
174
|
-
if md = /<td><IMG .+ ALT="([A-Z][A-Z][A-Z])"/i.match(line) #"
|
175
|
-
cur = md[1].intern
|
176
|
-
cur_i = currency.size
|
177
|
-
currency.push(cur)
|
178
|
-
# $stderr.puts "Found currency header: #{cur.inspect} at #{cur_i}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
# $stderr.puts "#{data[0..4].inspect}"
|
183
|
-
|
184
|
-
# Skip blank <tr>
|
185
|
-
until data.empty?
|
186
|
-
line = data.shift
|
187
|
-
break if line =~ /^\s*<td>.+1.+USD.+=/
|
188
|
-
end
|
189
|
-
|
190
|
-
until data.empty?
|
191
|
-
line = data.shift
|
192
|
-
break if line =~ /^\s*<\/tr>/i
|
193
|
-
end
|
194
|
-
|
195
|
-
# $stderr.puts "#{data[0..4].inspect}"
|
196
|
-
|
197
|
-
# Read first row of 1 USD = ...
|
198
|
-
|
199
|
-
rate = { }
|
200
|
-
cur_i = -1
|
201
|
-
until data.empty?
|
202
|
-
line = data.shift
|
203
|
-
break if cur_i < 0 && line =~ /^\s*<\/tr>/i
|
204
|
-
if md = /<td>\s+(\d+\.\d+)\s+<\/td>/.match(line)
|
205
|
-
usd_to_cur = md[1].to_f
|
206
|
-
cur_i = cur_i + 1
|
207
|
-
cur = currency[cur_i]
|
208
|
-
(rate[:USD] ||= {})[cur] = usd_to_cur
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
rate
|
213
|
-
end
|
214
|
-
|
215
|
-
# Loads cached rates from xe.com and creates Rate objects
|
216
|
-
# for 10 currencies.
|
217
|
-
def get_rate(c1, c2)
|
218
|
-
rates = xe_rates # Load rates
|
219
|
-
|
220
|
-
# $stderr.puts "load_exchange_rate(#{c1}, #{c2})"
|
221
|
-
rate = 0.0
|
222
|
-
r1 = nil
|
223
|
-
r2 = nil
|
224
|
-
|
225
|
-
rates_usd = rates[:USD]
|
226
|
-
|
227
|
-
raise Exception::UnknownRate.new("#{self}: base rate :USD") unless rates_usd
|
228
|
-
|
229
|
-
if ( c1.code == :USD && (r2 = rates_usd[c2.code]) )
|
230
|
-
rate = r2
|
231
|
-
elsif ( c2.code == :USD && (r1 = rates_usd[c2.code]) )
|
232
|
-
rate = 1.0 / r1
|
233
|
-
elsif ( (r1 = rates_usd[c1.code]) && (r2 = rates_usd[c2.code]) )
|
234
|
-
rate = r2 / r1
|
235
|
-
end
|
236
|
-
|
237
|
-
# $stderr.puts "XE Rate: #{c1.code} / #{c2.code} = #{rate}"
|
238
|
-
|
239
|
-
rate > 0 ? Rate.new(c1, c2, rate, self, @rate_timestamp) : nil
|
240
|
-
end
|
241
|
-
|
242
|
-
end # class
|
243
|
-
|
244
|
-
end # module
|
245
|
-
end # module
|
246
|
-
|
247
|
-
|
248
|
-
# Install as default.
|
249
|
-
Currency::Exchange.default = Currency::Exchange::Xe.instance
|
250
|
-
|