eu_central_bank 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/eu_central_bank/rates_document.rb +45 -0
- data/lib/eu_central_bank.rb +49 -34
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b589452c483bac16b40ab1372829694c9f261b9c802381110ed00fcebb73eaa6
|
4
|
+
data.tar.gz: 551614b051eb56ef4c10be19a5e796ebe0194287e1c278d374ae12f9aa5a2b9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0774ff56419fa0b24d71d8747259b1464468e3cbdb4b6db52808bf3ab9e6023cdb4a00f92e387df9e27fb9d84a16a933a588f49e7d7355db86704fa0a67ab8d7
|
7
|
+
data.tar.gz: 1f2a24bfd29add88ea0c537b2b7be8a245bcd8fdbe8a7bda04474757e3df9b8ebb62271b34e8dadfc029c2918b4d5c80f4a6783f043eb22d9447f29911db2534
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
class EuCentralBank < Money::Bank::VariableExchange
|
2
|
+
class RatesDocument < Nokogiri::XML::SAX::Document
|
3
|
+
attr_reader :rates
|
4
|
+
attr_reader :errors
|
5
|
+
attr_reader :updated_at
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@rates = {}
|
9
|
+
@errors = []
|
10
|
+
@updated_at = nil
|
11
|
+
@current_date = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def error(msg)
|
15
|
+
# TODO: remove this workaround after
|
16
|
+
# https://github.com/sparklemotion/nokogiri/pull/1872
|
17
|
+
# is released
|
18
|
+
@errors << msg
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def start_element(name, attributes=[])
|
23
|
+
return if name != 'Cube' || attributes.empty?
|
24
|
+
begin
|
25
|
+
first_name, first_value = attributes[0]
|
26
|
+
case first_name
|
27
|
+
when 'time'
|
28
|
+
@current_date = Time.parse(first_value).to_date
|
29
|
+
@updated_at ||= @current_date
|
30
|
+
@rates[@current_date] = []
|
31
|
+
when 'currency'
|
32
|
+
currency = first_value
|
33
|
+
_, rate = attributes[1]
|
34
|
+
@rates[@current_date] << [currency, rate]
|
35
|
+
end
|
36
|
+
rescue StandardError => e
|
37
|
+
raise Nokogiri::XML::XPath::SyntaxError, e.message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def end_document
|
42
|
+
raise Nokogiri::XML::XPath::SyntaxError if @rates.empty? || @updated_at.nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/eu_central_bank.rb
CHANGED
@@ -2,6 +2,7 @@ require 'open-uri'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'money'
|
4
4
|
require 'money/rates_store/store_with_historical_data_support'
|
5
|
+
require 'eu_central_bank/rates_document'
|
5
6
|
|
6
7
|
class InvalidCache < StandardError ; end
|
7
8
|
|
@@ -19,6 +20,9 @@ class EuCentralBank < Money::Bank::VariableExchange
|
|
19
20
|
CURRENCIES = %w(USD JPY BGN CZK DKK GBP HUF ILS ISK PLN RON SEK CHF NOK HRK RUB TRY AUD BRL CAD CNY HKD IDR INR KRW MXN MYR NZD PHP SGD THB ZAR).map(&:freeze).freeze
|
20
21
|
ECB_RATES_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'.freeze
|
21
22
|
ECB_90_DAY_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml'.freeze
|
23
|
+
ECB_ALL_HIST_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml'.freeze
|
24
|
+
|
25
|
+
LEGACY_CURRENCIES = %w(CYP SIT ROL TRL)
|
22
26
|
|
23
27
|
def initialize(st = Money::RatesStore::StoreWithHistoricalDataSupport.new, &block)
|
24
28
|
super
|
@@ -29,20 +33,26 @@ class EuCentralBank < Money::Bank::VariableExchange
|
|
29
33
|
update_parsed_rates(doc(cache, url))
|
30
34
|
end
|
31
35
|
|
32
|
-
def update_historical_rates(cache=nil)
|
33
|
-
|
36
|
+
def update_historical_rates(cache=nil, all=false)
|
37
|
+
url = all ? ECB_ALL_HIST_URL : ECB_90_DAY_URL
|
38
|
+
update_parsed_historical_rates(doc(cache, url))
|
34
39
|
end
|
35
40
|
|
36
41
|
def save_rates(cache, url=ECB_RATES_URL)
|
37
42
|
raise InvalidCache unless cache
|
38
43
|
File.open(cache, "w") do |file|
|
39
|
-
io = open_url(url)
|
44
|
+
io = open_url(url)
|
40
45
|
io.each_line { |line| file.puts line }
|
41
46
|
end
|
42
47
|
end
|
43
48
|
|
49
|
+
def save_historical_rates(cache, all=false)
|
50
|
+
url = all ? ECB_ALL_HIST_URL : ECB_90_DAY_URL
|
51
|
+
save_rates(cache, url)
|
52
|
+
end
|
53
|
+
|
44
54
|
def update_rates_from_s(content)
|
45
|
-
update_parsed_rates(
|
55
|
+
update_parsed_rates(parse_rates(content))
|
46
56
|
end
|
47
57
|
|
48
58
|
def save_rates_to_s(url=ECB_RATES_URL)
|
@@ -164,48 +174,53 @@ class EuCentralBank < Money::Bank::VariableExchange
|
|
164
174
|
|
165
175
|
def doc(cache, url=ECB_RATES_URL)
|
166
176
|
rates_source = !!cache ? cache : url
|
167
|
-
|
168
|
-
|
169
|
-
Nokogiri::XML
|
177
|
+
begin
|
178
|
+
parse_rates(open_url(rates_source))
|
179
|
+
rescue Nokogiri::XML::XPath::SyntaxError
|
180
|
+
parse_rates(open_url(url))
|
181
|
+
end
|
170
182
|
end
|
171
183
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
184
|
+
def parse_rates(io)
|
185
|
+
doc = ::EuCentralBank::RatesDocument.new
|
186
|
+
parser = Nokogiri::XML::SAX::Parser.new(doc)
|
187
|
+
parser.parse(io)
|
175
188
|
|
176
|
-
|
177
|
-
|
189
|
+
unless doc.errors.empty?
|
190
|
+
# Temporary workaround for jruby until
|
191
|
+
# https://github.com/sparklemotion/nokogiri/pull/1872 gets
|
192
|
+
# released and we bump nokogiri version to include it.
|
193
|
+
# TLDR: jruby version of SAX parser will mask all the exceptions
|
194
|
+
# raised in document so we will raise it here if there were errors.
|
195
|
+
raise Nokogiri::XML::XPath::SyntaxError, doc.errors.join("\n")
|
196
|
+
end
|
178
197
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
198
|
+
doc
|
199
|
+
end
|
200
|
+
|
201
|
+
def copy_rates(rates_document, with_date = false)
|
202
|
+
rates_document.rates.each do |date, rates|
|
203
|
+
rates.each do |currency, rate|
|
204
|
+
next if LEGACY_CURRENCIES.include?(currency)
|
205
|
+
set_rate('EUR', currency, BigDecimal(rate, DECIMAL_PRECISION), with_date ? date : nil)
|
184
206
|
end
|
185
|
-
set_rate(
|
207
|
+
set_rate('EUR', 'EUR', 1, with_date ? date : nil)
|
186
208
|
end
|
209
|
+
end
|
187
210
|
|
188
|
-
|
189
|
-
|
190
|
-
|
211
|
+
def update_parsed_rates(rates_document)
|
212
|
+
store.transaction true do
|
213
|
+
copy_rates(rates_document)
|
214
|
+
end
|
215
|
+
@rates_updated_at = rates_document.updated_at
|
191
216
|
@last_updated = Time.now
|
192
217
|
end
|
193
218
|
|
194
|
-
def update_parsed_historical_rates(
|
195
|
-
rates = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
|
196
|
-
|
219
|
+
def update_parsed_historical_rates(rates_document)
|
197
220
|
store.transaction true do
|
198
|
-
|
199
|
-
rate = BigDecimal(exchange_rate.attribute("rate").value, DECIMAL_PRECISION)
|
200
|
-
currency = exchange_rate.attribute("currency").value
|
201
|
-
date = exchange_rate.parent.attribute("time").value
|
202
|
-
set_rate("EUR", currency, rate, date)
|
203
|
-
end
|
221
|
+
copy_rates(rates_document, true)
|
204
222
|
end
|
205
|
-
|
206
|
-
rates_updated_at = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube/@time').first.value
|
207
|
-
@historical_rates_updated_at = Time.parse(rates_updated_at)
|
208
|
-
|
223
|
+
@historical_rates_updated_at = rates_document.updated_at
|
209
224
|
@historical_last_updated = Time.now
|
210
225
|
end
|
211
226
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eu_central_bank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shane Emmons
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- LICENSE
|
71
71
|
- README.md
|
72
72
|
- lib/eu_central_bank.rb
|
73
|
+
- lib/eu_central_bank/rates_document.rb
|
73
74
|
- lib/money/rates_store/store_with_historical_data_support.rb
|
74
75
|
homepage: https://github.com/RubyMoney/eu_central_bank
|
75
76
|
licenses:
|
@@ -90,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
91
|
- !ruby/object:Gem::Version
|
91
92
|
version: '0'
|
92
93
|
requirements: []
|
93
|
-
rubygems_version: 3.2.
|
94
|
+
rubygems_version: 3.2.22
|
94
95
|
signing_key:
|
95
96
|
specification_version: 4
|
96
97
|
summary: Calculates exchange rates based on rates from european central bank. Money
|