frankfurter/lib/provider/adapters/lb.rb
BadMark d0a43e357a
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / publish (push) Has been cancelled
CI/CD Pipeline / release (push) Has been cancelled
up
2026-05-21 01:38:14 -06:00

82 lines
2.3 KiB
Ruby

# frozen_string_literal: true
require "net/http"
require "ox"
require "provider/adapters/adapter"
class Provider
module Adapters
# Bank of Lithuania (Lietuvos Bankas). Publishes daily exchange rates for
# ~88 currencies. Pre-2015 rates are quoted against LTL (Lithuanian litas);
# post-2015 rates are EUR-based (ECB rates republished after euro adoption).
class LB < Adapter
BASE_URL = "https://www.lb.lt/webservices/FxRates/FxRates.asmx/getFxRates"
EUR_ADOPTION = Date.new(2015, 1, 1)
class << self
def backfill_range = 30
end
def fetch(after: nil, upto: nil)
end_date = upto || Date.today
dataset = []
first = true
(after..end_date).each do |date|
next if date.saturday? || date.sunday?
sleep(0.2) unless first
first = false
dataset.concat(fetch_date(date))
end
dataset
end
def parse(xml)
doc = Ox.load(xml)
doc.locate("*/FxRate").filter_map do |fx_rate|
amounts = fx_rate.locate("CcyAmt")
next unless amounts.size == 2
first_ccy = amounts[0].locate("Ccy/^String").first
first_amt = amounts[0].locate("Amt/^String").first
second_ccy = amounts[1].locate("Ccy/^String").first
second_amt = amounts[1].locate("Amt/^String").first
date_str = fx_rate.locate("Dt/^String").first
next unless first_ccy && first_amt && second_ccy && second_amt && date_str
date = Date.parse(date_str)
tp = fx_rate.locate("Tp/^String").first
if tp == "LT"
quote_amt = Float(first_amt)
base_quantity = Float(second_amt)
next if quote_amt.zero? || base_quantity.zero?
{ date:, base: second_ccy, quote: "LTL", rate: quote_amt / base_quantity }
else
rate = Float(second_amt)
next if rate.zero?
{ date:, base: "EUR", quote: second_ccy, rate: }
end
end
end
private
def fetch_date(date)
tp = date < EUR_ADOPTION ? "LT" : "EU"
url = URI(BASE_URL)
url.query = URI.encode_www_form(tp:, dt: date.strftime("%Y-%m-%d"))
response = Net::HTTP.get(url)
parse(response)
end
end
end
end