63 lines
1.8 KiB
Ruby
63 lines
1.8 KiB
Ruby
|
|
# frozen_string_literal: true
|
||
|
|
|
||
|
|
require "net/http"
|
||
|
|
require "ox"
|
||
|
|
|
||
|
|
require "provider/adapters/adapter"
|
||
|
|
|
||
|
|
class Provider
|
||
|
|
module Adapters
|
||
|
|
# National Bank of Romania. Publishes daily reference rates for ~35
|
||
|
|
# currencies against the Romanian leu (RON). Yearly XML archives back to
|
||
|
|
# 2005 are kept current within the year. The 10-day feed is a redundant
|
||
|
|
# window over the same data, so we always use the yearly archive.
|
||
|
|
class BNR < Adapter
|
||
|
|
BASE_URL = "https://www.bnr.ro"
|
||
|
|
|
||
|
|
class << self
|
||
|
|
def backfill_range = 365
|
||
|
|
end
|
||
|
|
|
||
|
|
def fetch(after: nil, upto: nil)
|
||
|
|
end_date = upto || Date.today
|
||
|
|
|
||
|
|
records = if after.nil? || after.year == end_date.year
|
||
|
|
fetch_year(after&.year || end_date.year)
|
||
|
|
else
|
||
|
|
(after.year..end_date.year).flat_map { |year| fetch_year(year) }
|
||
|
|
end
|
||
|
|
|
||
|
|
records.select { |r| (after.nil? || r[:date] > after) && r[:date] <= end_date }
|
||
|
|
end
|
||
|
|
|
||
|
|
def parse(xml)
|
||
|
|
doc = Ox.load(xml)
|
||
|
|
|
||
|
|
doc.locate("DataSet/Body/Cube").flat_map do |cube|
|
||
|
|
date = Date.parse(cube[:date])
|
||
|
|
cube.locate("Rate").filter_map do |rate_node|
|
||
|
|
currency = rate_node[:currency]
|
||
|
|
next unless currency&.match?(/\A[A-Z]{3}\z/)
|
||
|
|
|
||
|
|
multiplier = rate_node[:multiplier]&.to_i || 1
|
||
|
|
rate_value = Float(rate_node.text, exception: false)
|
||
|
|
next unless rate_value
|
||
|
|
|
||
|
|
rate_value /= multiplier if multiplier > 1
|
||
|
|
rate_value *= GRAMS_PER_TROY_OUNCE if currency == "XAU"
|
||
|
|
next if rate_value.zero?
|
||
|
|
|
||
|
|
{ date:, base: currency, quote: "RON", rate: rate_value }
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
private
|
||
|
|
|
||
|
|
def fetch_year(year)
|
||
|
|
parse(Net::HTTP.get(URI("#{BASE_URL}/files/xml/years/nbrfxrates#{year}.xml")))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|