eu_central_bank 0.3.8 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/eu_central_bank.rb +88 -22
  3. metadata +20 -63
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ecdbda3cf40f2ffa1e54020dd8c93e045ee428b
4
+ data.tar.gz: a6a95b47411c3ec8e0ad5da4a04c12e35cd6ce1b
5
+ SHA512:
6
+ metadata.gz: 73d3a0b6ef922aa0c75cfe45e1371440a35598e93b39d180a06f382a5c1b95f1eca88d20a0788151b6737b893d3b882f0b35cfe5c74cbe8eabd37e17b3724826
7
+ data.tar.gz: 9c7f41bc3ba48142d2459e666acc85a607b5018b3adb0138bd29a2271cdaf6f7ab4335c7f56ce28e2d51ce251ecc1bcb35d0e3dee176140bf4aee2078ce6bba2
@@ -9,19 +9,26 @@ class EuCentralBank < Money::Bank::VariableExchange
9
9
 
10
10
  attr_accessor :last_updated
11
11
  attr_accessor :rates_updated_at
12
+ attr_accessor :historical_last_updated
13
+ attr_accessor :historical_rates_updated_at
12
14
 
13
- ECB_RATES_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'
14
15
  CURRENCIES = %w(USD JPY BGN CZK DKK GBP HUF ILS LTL PLN RON SEK CHF NOK HRK RUB TRY AUD BRL CAD CNY HKD IDR INR KRW MXN MYR NZD PHP SGD THB ZAR)
16
+ ECB_RATES_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'
17
+ ECB_90_DAY_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml'
15
18
 
16
19
  def update_rates(cache=nil)
17
20
  update_parsed_rates(doc(cache))
18
21
  end
19
22
 
20
- def save_rates(cache)
21
- raise InvalidCache if !cache
23
+ def update_historical_rates(cache=nil)
24
+ update_parsed_historical_rates(doc(cache, ECB_90_DAY_URL))
25
+ end
26
+
27
+ def save_rates(cache, url=ECB_RATES_URL)
28
+ raise InvalidCache unless cache
22
29
  File.open(cache, "w") do |file|
23
- io = open(ECB_RATES_URL) ;
24
- io.each_line {|line| file.puts line}
30
+ io = open(url);
31
+ io.each_line { |line| file.puts line }
25
32
  end
26
33
  end
27
34
 
@@ -29,34 +36,57 @@ class EuCentralBank < Money::Bank::VariableExchange
29
36
  update_parsed_rates(doc_from_s(content))
30
37
  end
31
38
 
32
- def save_rates_to_s
33
- open(ECB_RATES_URL).read
39
+ def save_rates_to_s(url=ECB_RATES_URL)
40
+ open(url).read
34
41
  end
35
42
 
36
- def exchange(cents, from_currency, to_currency)
37
- exchange_with(Money.new(cents, from_currency), to_currency)
43
+ def exchange(cents, from_currency, to_currency, date=nil)
44
+ exchange_with(Money.new(cents, from_currency), to_currency, date)
38
45
  end
39
46
 
40
- def exchange_with(from, to_currency)
41
- rate = get_rate(from.currency, to_currency)
47
+ def exchange_with(from, to_currency, date=nil)
48
+ from_base_rate, to_base_rate = nil, nil
49
+ rate = get_rate(from, to_currency, {:date => date})
50
+
42
51
  unless rate
43
- from_base_rate, to_base_rate = nil, nil
44
- @mutex.synchronize {
45
- from_base_rate = get_rate("EUR", from.currency, :without_mutex => true)
46
- to_base_rate = get_rate("EUR", to_currency, :without_mutex => true)
47
- }
52
+ @mutex.synchronize do
53
+ opts = { :date => date, :without_mutex => true }
54
+ from_base_rate = get_rate("EUR", from.currency.to_s, opts)
55
+ to_base_rate = get_rate("EUR", to_currency, opts)
56
+ end
48
57
  rate = to_base_rate / from_base_rate
49
58
  end
50
- Money.new(((BigDecimal(Money::Currency.wrap(to_currency).subunit_to_unit) / BigDecimal(from.currency.subunit_to_unit)) * from.cents * rate).round, to_currency)
59
+
60
+ calculate_exchange(from, to_currency, rate)
61
+ end
62
+
63
+ def get_rate(from, to, opts = {})
64
+ fn = -> { @rates[rate_key_for(from, to, opts)] }
65
+
66
+ if opts[:without_mutex]
67
+ fn.call
68
+ else
69
+ @mutex.synchronize { fn.call }
70
+ end
71
+ end
72
+
73
+ def set_rate(from, to, rate, opts = {})
74
+ fn = -> { @rates[rate_key_for(from, to, opts)] = rate }
75
+
76
+ if opts[:without_mutex]
77
+ fn.call
78
+ else
79
+ @mutex.synchronize { fn.call }
80
+ end
51
81
  end
52
82
 
53
83
  protected
54
84
 
55
- def doc(cache)
56
- rates_source = !!cache ? cache : ECB_RATES_URL
57
- Nokogiri::XML(open(rates_source)).tap {|doc| doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube') }
85
+ def doc(cache, url=ECB_RATES_URL)
86
+ rates_source = !!cache ? cache : url
87
+ Nokogiri::XML(open(rates_source)).tap { |doc| doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube') }
58
88
  rescue Nokogiri::XML::XPath::SyntaxError
59
- Nokogiri::XML(open(ECB_RATES_URL))
89
+ Nokogiri::XML(open(url))
60
90
  end
61
91
 
62
92
  def doc_from_s(content)
@@ -66,7 +96,7 @@ class EuCentralBank < Money::Bank::VariableExchange
66
96
  def update_parsed_rates(doc)
67
97
  rates = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
68
98
 
69
- @mutex.synchronize do
99
+ @mutex.synchronize do
70
100
  rates.each do |exchange_rate|
71
101
  rate = BigDecimal(exchange_rate.attribute("rate").value)
72
102
  currency = exchange_rate.attribute("currency").value
@@ -80,4 +110,40 @@ class EuCentralBank < Money::Bank::VariableExchange
80
110
 
81
111
  @last_updated = Time.now
82
112
  end
113
+
114
+ def update_parsed_historical_rates(doc)
115
+ rates = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
116
+
117
+ @mutex.synchronize do
118
+ rates.each do |exchange_rate|
119
+ rate = BigDecimal(exchange_rate.attribute("rate").value)
120
+ currency = exchange_rate.attribute("currency").value
121
+ opts = { :without_mutex => true }
122
+ opts[:date] = exchange_rate.parent.attribute("time").value
123
+ set_rate("EUR", currency, rate, opts)
124
+ set_rate("EUR", "EUR", 1, opts)
125
+ end
126
+ end
127
+
128
+ rates_updated_at = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube/@time').first.value
129
+ @historical_rates_updated_at = Time.parse(rates_updated_at)
130
+
131
+ @historical_last_updated = Time.now
132
+ end
133
+
134
+ private
135
+
136
+ def calculate_exchange(from, to_currency, rate)
137
+ to_currency_money = Money::Currency.wrap(to_currency).subunit_to_unit
138
+ from_currency_money = from.currency.subunit_to_unit
139
+ decimal_money = BigDecimal(to_currency_money) / BigDecimal(from_currency_money)
140
+ money = (decimal_money * from.cents * rate).round
141
+ Money.new(money, to_currency)
142
+ end
143
+
144
+ def rate_key_for(from, to, opts)
145
+ key = "#{from}_TO_#{to}"
146
+ key << "_#{opts[:date].to_s}" if opts[:date]
147
+ key.upcase
148
+ end
83
149
  end
metadata CHANGED
@@ -1,134 +1,91 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eu_central_bank
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
5
- prerelease:
4
+ version: 0.4.0
6
5
  platform: ruby
7
6
  authors:
8
- - Wong Liang Zan
9
7
  - Shane Emmons
10
- - Thorsten Böttger
11
- - Jonathan Eisenstein
12
8
  autorequire:
13
9
  bindir: bin
14
10
  cert_chain: []
15
- date: 2014-02-11 00:00:00.000000000 Z
11
+ date: 2014-10-06 00:00:00.000000000 Z
16
12
  dependencies:
17
13
  - !ruby/object:Gem::Dependency
18
14
  name: nokogiri
19
15
  requirement: !ruby/object:Gem::Requirement
20
- none: false
21
16
  requirements:
22
- - - ! '>='
17
+ - - ">="
23
18
  - !ruby/object:Gem::Version
24
19
  version: '0'
25
20
  type: :runtime
26
21
  prerelease: false
27
22
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
23
  requirements:
30
- - - ! '>='
24
+ - - ">="
31
25
  - !ruby/object:Gem::Version
32
26
  version: '0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: money
35
29
  requirement: !ruby/object:Gem::Requirement
36
- none: false
37
30
  requirements:
38
- - - ! '>='
31
+ - - "~>"
39
32
  - !ruby/object:Gem::Version
40
- version: 6.0.1
33
+ version: 6.3.0
41
34
  type: :runtime
42
35
  prerelease: false
43
36
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
37
  requirements:
46
- - - ! '>='
38
+ - - "~>"
47
39
  - !ruby/object:Gem::Version
48
- version: 6.0.1
40
+ version: 6.3.0
49
41
  - !ruby/object:Gem::Dependency
50
42
  name: rspec
51
43
  requirement: !ruby/object:Gem::Requirement
52
- none: false
53
44
  requirements:
54
- - - ! '>='
45
+ - - "~>"
55
46
  - !ruby/object:Gem::Version
56
- version: 2.0.0
47
+ version: 3.0.0
57
48
  type: :development
58
49
  prerelease: false
59
50
  version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
51
  requirements:
62
- - - ! '>='
52
+ - - "~>"
63
53
  - !ruby/object:Gem::Version
64
- version: 2.0.0
65
- - !ruby/object:Gem::Dependency
66
- name: rr
67
- requirement: !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
- - - ! '>='
71
- - !ruby/object:Gem::Version
72
- version: '0'
73
- type: :development
74
- prerelease: false
75
- version_requirements: !ruby/object:Gem::Requirement
76
- none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- - !ruby/object:Gem::Dependency
82
- name: shoulda
83
- requirement: !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ! '>='
87
- - !ruby/object:Gem::Version
88
- version: '0'
89
- type: :development
90
- prerelease: false
91
- version_requirements: !ruby/object:Gem::Requirement
92
- none: false
93
- requirements:
94
- - - ! '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
54
+ version: 3.0.0
97
55
  description: This gem reads exchange rates from the european central bank website.
98
56
  It uses it to calculates exchange rates. It is compatible with the money gem
99
57
  email:
100
- - zan@liangzan.net
58
+ - shane@emmons.io
101
59
  executables: []
102
60
  extensions: []
103
61
  extra_rdoc_files: []
104
62
  files:
105
- - lib/eu_central_bank.rb
106
63
  - CHANGELOG.md
107
64
  - LICENSE
108
65
  - README.md
66
+ - lib/eu_central_bank.rb
109
67
  homepage: http://github.com/RubyMoney/eu_central_bank
110
68
  licenses: []
69
+ metadata: {}
111
70
  post_install_message:
112
71
  rdoc_options: []
113
72
  require_paths:
114
73
  - lib
115
74
  required_ruby_version: !ruby/object:Gem::Requirement
116
- none: false
117
75
  requirements:
118
- - - ! '>='
76
+ - - ">="
119
77
  - !ruby/object:Gem::Version
120
78
  version: '0'
121
79
  required_rubygems_version: !ruby/object:Gem::Requirement
122
- none: false
123
80
  requirements:
124
- - - ! '>='
81
+ - - ">="
125
82
  - !ruby/object:Gem::Version
126
- version: 1.3.6
83
+ version: '0'
127
84
  requirements: []
128
85
  rubyforge_project:
129
- rubygems_version: 1.8.25
86
+ rubygems_version: 2.2.2
130
87
  signing_key:
131
- specification_version: 3
88
+ specification_version: 4
132
89
  summary: Calculates exchange rates based on rates from european central bank. Money
133
90
  gem compatible.
134
91
  test_files: []