class EuCentralBank
Constants
- CURRENCIES
- DECIMAL_PRECISION
- ECB_90_DAY_URL
- ECB_RATES_URL
- SERIALIZER_DATE_SEPARATOR
Attributes
historical_last_updated[RW]
historical_rates_updated_at[RW]
last_updated[RW]
rates_updated_at[RW]
Public Class Methods
new(st = Money::RatesStore::StoreWithHistoricalDataSupport.new, &block)
click to toggle source
Calls superclass method
# File lib/eu_central_bank.rb, line 23 def initialize(st = Money::RatesStore::StoreWithHistoricalDataSupport.new, &block) super @currency_string = nil end
Public Instance Methods
check_currency_available(currency)
click to toggle source
# File lib/eu_central_bank.rb, line 156 def check_currency_available(currency) currency_string = currency.to_s return true if currency_string == "EUR" return true if CURRENCIES.include?(currency_string) raise CurrencyUnavailable, "No rates available for #{currency_string}" end
exchange(cents, from_currency, to_currency, date=nil)
click to toggle source
# File lib/eu_central_bank.rb, line 52 def exchange(cents, from_currency, to_currency, date=nil) exchange_with(Money.new(cents, from_currency), to_currency, date) end
exchange_with(from, to_currency, date=nil)
click to toggle source
# File lib/eu_central_bank.rb, line 56 def exchange_with(from, to_currency, date=nil) from_base_rate, to_base_rate = nil, nil rate = get_rate(from.currency, to_currency, date) unless rate store.transaction true do from_base_rate = get_rate("EUR", from.currency.to_s, date) to_base_rate = get_rate("EUR", to_currency, date) end unless from_base_rate && to_base_rate message = "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'" message << " on #{date.to_s}" if date raise Money::Bank::UnknownRate, message end rate = to_base_rate / from_base_rate end calculate_exchange(from, to_currency, rate) end
export_rates(format, file = nil, opts = {})
click to toggle source
# File lib/eu_central_bank.rb, line 109 def export_rates(format, file = nil, opts = {}) raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include? format store.transaction true do s = case format when :json JSON.dump(rates) when :ruby Marshal.dump(rates) when :yaml YAML.dump(rates) end unless file.nil? File.open(file, "w") {|f| f.write(s) } end s end end
get_rate(from, to, date = nil)
click to toggle source
# File lib/eu_central_bank.rb, line 79 def get_rate(from, to, date = nil) return 1 if from == to check_currency_available(from) check_currency_available(to) if date.is_a?(Hash) # Backwards compatibility for the opts hash date = date[:date] end store.get_rate(::Money::Currency.wrap(from).iso_code, ::Money::Currency.wrap(to).iso_code, date) end
import_rates(format, s, opts = {})
click to toggle source
# File lib/eu_central_bank.rb, line 131 def import_rates(format, s, opts = {}) raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include? format store.transaction true do data = case format when :json JSON.load(s) when :ruby Marshal.load(s) when :yaml YAML.load(s) end data.each do |key, rate| from, to = key.split(SERIALIZER_SEPARATOR) to, date = to.split(SERIALIZER_DATE_SEPARATOR) store.add_rate from, to, BigDecimal(rate, DECIMAL_PRECISION), date end end self end
rates()
click to toggle source
# File lib/eu_central_bank.rb, line 101 def rates store.each_rate.each_with_object({}) do |(from,to,rate,date),hash| key = [from, to].join(SERIALIZER_SEPARATOR) key = [key, date.to_s].join(SERIALIZER_DATE_SEPARATOR) if date hash[key] = rate end end
save_rates(cache, url=ECB_RATES_URL)
click to toggle source
# File lib/eu_central_bank.rb, line 36 def save_rates(cache, url=ECB_RATES_URL) raise InvalidCache unless cache File.open(cache, "w") do |file| io = open_url(url); io.each_line { |line| file.puts line } end end
save_rates_to_s(url=ECB_RATES_URL)
click to toggle source
# File lib/eu_central_bank.rb, line 48 def save_rates_to_s(url=ECB_RATES_URL) open_url(url).read end
set_rate(from, to, rate, date = nil)
click to toggle source
# File lib/eu_central_bank.rb, line 93 def set_rate(from, to, rate, date = nil) if date.is_a?(Hash) # Backwards compatibility for the opts hash date = date[:date] end store.add_rate(::Money::Currency.wrap(from).iso_code, ::Money::Currency.wrap(to).iso_code, rate, date) end
update_historical_rates(cache=nil)
click to toggle source
# File lib/eu_central_bank.rb, line 32 def update_historical_rates(cache=nil) update_parsed_historical_rates(doc(cache, ECB_90_DAY_URL)) end
update_rates(cache=nil, url=ECB_RATES_URL)
click to toggle source
# File lib/eu_central_bank.rb, line 28 def update_rates(cache=nil, url=ECB_RATES_URL) update_parsed_rates(doc(cache, url)) end
update_rates_from_s(content)
click to toggle source
# File lib/eu_central_bank.rb, line 44 def update_rates_from_s(content) update_parsed_rates(doc_from_s(content)) end
Protected Instance Methods
doc(cache, url=ECB_RATES_URL)
click to toggle source
# File lib/eu_central_bank.rb, line 165 def doc(cache, url=ECB_RATES_URL) rates_source = !!cache ? cache : url Nokogiri::XML(open_url(rates_source)).tap { |doc| doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube') } rescue Nokogiri::XML::XPath::SyntaxError Nokogiri::XML(open_url(url)) end
doc_from_s(content)
click to toggle source
# File lib/eu_central_bank.rb, line 172 def doc_from_s(content) Nokogiri::XML(content) end
update_parsed_historical_rates(doc)
click to toggle source
# File lib/eu_central_bank.rb, line 194 def update_parsed_historical_rates(doc) rates = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube') store.transaction true do rates.each do |exchange_rate| rate = BigDecimal(exchange_rate.attribute("rate").value, DECIMAL_PRECISION) currency = exchange_rate.attribute("currency").value date = exchange_rate.parent.attribute("time").value set_rate("EUR", currency, rate, date) end end rates_updated_at = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube/@time').first.value @historical_rates_updated_at = Time.parse(rates_updated_at) @historical_last_updated = Time.now end
update_parsed_rates(doc)
click to toggle source
# File lib/eu_central_bank.rb, line 176 def update_parsed_rates(doc) rates = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube') store.transaction true do rates.each do |exchange_rate| rate = BigDecimal(exchange_rate.attribute("rate").value, DECIMAL_PRECISION) currency = exchange_rate.attribute("currency").value set_rate("EUR", currency, rate) end set_rate("EUR", "EUR", 1) end rates_updated_at = doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube/@time').first.value @rates_updated_at = Time.parse(rates_updated_at) @last_updated = Time.now end
Private Instance Methods
calculate_exchange(from, to_currency, rate)
click to toggle source
# File lib/eu_central_bank.rb, line 214 def calculate_exchange(from, to_currency, rate) to_currency_money = Money::Currency.wrap(to_currency).subunit_to_unit from_currency_money = from.currency.subunit_to_unit decimal_money = BigDecimal(to_currency_money, DECIMAL_PRECISION) / BigDecimal(from_currency_money, DECIMAL_PRECISION) money = (decimal_money * from.cents * rate).round Money.new(money, to_currency) end
open_url(url)
click to toggle source
# File lib/eu_central_bank.rb, line 222 def open_url(url) if RUBY_VERSION >= '2.5.0' URI.open(url) else open(url) end end