class Money::Bank::OpenExchangeRatesBank
OpenExchangeRatesBank
base class
Constants
- BASE_URL
- OER_HISTORICAL_URL
- OER_URL
OpenExchangeRates urls
- OE_SOURCE
Default base currency “base”: “USD”
- RATES_KEY
- TIMESTAMP_KEY
- VERSION
Attributes
As of the end of August 2012 all requests to the Open Exchange Rates API must have a valid app_id
see docs.openexchangerates.org/docs/authentication
@example
oxr.app_id = 'YOUR_APP_APP_ID'
@param [String] token to access OXR API @return [String] token to access OXR API
Cache accessor
@example
oxr.cache = 'path/to/file/cache.json'
@param [String,Proc] for a String a filepath @return [String,Proc] for a String a filepath
Date for historical api see docs.openexchangerates.org/docs/historical-json
@example
oxr.date = '2015-01-01'
@param [String] The requested date in YYYY-MM-DD format @return [String] The requested date in YYYY-MM-DD format
Force refresh rates cache and store on the fly when ttl is expired This will slow down request on get_rate
, so use at your on risk, if you don’t want to setup crontab/worker/scheduler for your application
@param [Boolean]
Unparsed OpenExchangeRates response as String
@return [String] OpenExchangeRates json response
Parsed OpenExchangeRates result as Hash
@return [Hash] All rates as Hash
Minified Response (‘prettyprint’) see docs.openexchangerates.org/docs/prettyprint @example
oxr.prettyprint = false
@param [Boolean] Set to false to receive minified (default: true) @return [Boolean]
Rates expiration Time
@return [Time] expiration time
Set support for the black market and alternative digital currencies see docs.openexchangerates.org/docs/alternative-currencies @example
oxr.show_alternative = true
@param [Boolean] if true show alternative @return [Boolean] Setted show alternative
Filter response to a list of symbols see docs.openexchangerates.org/docs/get-specific-currencies @example
oxr.symbols = [:usd, :cad]
@param [Array] list of symbols @return [Array] Setted list of symbols
Seconds after than the current rates are automatically expired
@return [Integer] Setted time to live in seconds
Public Instance Methods
Expire rates when expired
@return [NilClass, Time] nil if not expired or new expiration time
# File lib/money/bank/open_exchange_rates_bank.rb, line 231 def expire_rates return unless ttl_in_seconds return if rates_expiration > Time.now refresh_rates if force_refresh_rate_on_expire update_rates refresh_rates_expiration end
Override Money
‘get_rate` method for caching
@param [String] from_currency Currency ISO code. ex. ‘USD’ @param [String] to_currency Currency ISO code. ex. ‘CAD’
@return [Numeric] rate.
# File lib/money/bank/open_exchange_rates_bank.rb, line 211 def get_rate(from_currency, to_currency, opts = {}) super if opts[:call_super] expire_rates rate = get_rate_or_calc_inverse(from_currency, to_currency, opts) rate || calc_pair_rate_using_base(from_currency, to_currency, opts) end
Get prettyprint option
@return [Boolean]
# File lib/money/bank/open_exchange_rates_bank.rb, line 250 def prettyprint return true unless defined? @prettyprint return true if @prettyprint.nil? @prettyprint end
Current rates timestamp
@return [Time]
# File lib/money/bank/open_exchange_rates_bank.rb, line 140 def rates_timestamp @rates_timestamp || Time.now end
Set current rates timestamp
@return [Time]
# File lib/money/bank/open_exchange_rates_bank.rb, line 133 def rates_timestamp=(at) @rates_timestamp = Time.at(at) end
Fetch from url and save cache
@return [Array] Array of exchange rates
# File lib/money/bank/open_exchange_rates_bank.rb, line 221 def refresh_rates read_from_url end
Get show alternative
@return [Boolean] if true show alternative
# File lib/money/bank/open_exchange_rates_bank.rb, line 243 def show_alternative @show_alternative ||= false end
Get the base currency for all rates. By default, USD is used.
@return [String] base currency
# File lib/money/bank/open_exchange_rates_bank.rb, line 181 def source @source ||= OE_SOURCE end
Set the base currency for all rates. By default, USD is used. OpenExchangeRates only allows USD as base currency for the free plan users.
@example
oxr.source = 'USD'
@param value [String] Currency code, ISO 3166-1 alpha-3
@return [String] chosen base currency
# File lib/money/bank/open_exchange_rates_bank.rb, line 169 def source=(value) scurrency = Money::Currency.find(value.to_s) @source = if scurrency scurrency.iso_code else OE_SOURCE end end
Source url of openexchangerates defined with app_id
@return [String] URL
# File lib/money/bank/open_exchange_rates_bank.rb, line 268 def source_url str = "#{oer_url}?app_id=#{app_id}" str = "#{str}&base=#{source}" unless source == OE_SOURCE str = "#{str}&show_alternative=#{show_alternative}" str = "#{str}&prettyprint=#{prettyprint}" str = "#{str}&symbols=#{symbols.join(',')}" if symbols&.is_a?(Array) str end
Get symbols
@return [Array] list of symbols to filter by
# File lib/money/bank/open_exchange_rates_bank.rb, line 260 def symbols @symbols ||= nil end
Set the seconds after than the current rates are automatically expired by default, they never expire.
@example
ttl_in_seconds = 86400 # will expire the rates in one day
@param value [Integer] Time to live in seconds
@return [Integer] Setted time to live in seconds
# File lib/money/bank/open_exchange_rates_bank.rb, line 153 def ttl_in_seconds=(value) @ttl_in_seconds = value refresh_rates_expiration if ttl_in_seconds ttl_in_seconds end
Update all rates from openexchangerates JSON
@return [Array] Array of exchange rates
# File lib/money/bank/open_exchange_rates_bank.rb, line 188 def update_rates store.transaction do clear_rates! exchange_rates.each do |exchange_rate| rate = exchange_rate.last currency = exchange_rate.first next unless Money::Currency.find(currency) set_rate(source, currency, rate) set_rate(currency, source, 1.0 / rate) end end end
Protected Instance Methods
Read API
@return [String]
# File lib/money/bank/open_exchange_rates_bank.rb, line 350 def api_response Net::HTTP.get(URI(source_url)) end
Tries to calculate a pair rate using base currency rate
@param [String] from_currency Currency ISO code. ex. ‘USD’ @param [String] to_currency Currency ISO code. ex. ‘CAD’
@return [Numeric] rate or nil if cannot calculate rate.
# File lib/money/bank/open_exchange_rates_bank.rb, line 426 def calc_pair_rate_using_base(from_currency, to_currency, opts) from_base_rate = get_rate_or_calc_inverse(source, from_currency, opts) to_base_rate = get_rate_or_calc_inverse(source, to_currency, opts) return unless to_base_rate return unless from_base_rate rate = BigDecimal(to_base_rate.to_s) / from_base_rate add_rate(from_currency, to_currency, rate) rate end
Clears cached rates in store
@return [Hash] All rates from store as Hash
# File lib/money/bank/open_exchange_rates_bank.rb, line 440 def clear_rates! store.each_rate do |iso_from, iso_to| add_rate(iso_from, iso_to, nil) end end
Get expire rates, first from cache and then from url
@return [Hash] key is country code (ISO 3166-1 alpha-3) value Float
# File lib/money/bank/open_exchange_rates_bank.rb, line 384 def exchange_rates doc = JSON.parse(read_from_cache || read_from_url) if doc['error'] && ERROR_MAP.key?(doc['message'].to_sym) raise ERROR_MAP[doc['message'].to_sym] end self.rates_timestamp = doc[TIMESTAMP_KEY] @oer_rates = doc[RATES_KEY] end
Get rate or calculate it as inverse rate
@param [String] from_currency Currency ISO code. ex. ‘USD’ @param [String] to_currency Currency ISO code. ex. ‘CAD’
@return [Numeric] rate or rate calculated as inverse rate.
# File lib/money/bank/open_exchange_rates_bank.rb, line 407 def get_rate_or_calc_inverse(from_currency, to_currency, opts = {}) rate = super_get_rate(from_currency, to_currency, opts) unless rate # Tries to calculate an inverse rate inverse_rate = super_get_rate(to_currency, from_currency, opts) if inverse_rate rate = 1.0 / inverse_rate add_rate(from_currency, to_currency, rate) end end rate end
Historical url generated from ‘date` attr_accessor
@return [String] URL
# File lib/money/bank/open_exchange_rates_bank.rb, line 303 def historical_url URI.join(OER_HISTORICAL_URL, "#{date}.json") end
Latest url
@return [String] URL
# File lib/money/bank/open_exchange_rates_bank.rb, line 310 def latest_url OER_URL end
Latest url if no date given
@return [String] URL
# File lib/money/bank/open_exchange_rates_bank.rb, line 292 def oer_url if date historical_url else latest_url end end
Read from cache when exist
@return [String] Raw string from file or cache proc
# File lib/money/bank/open_exchange_rates_bank.rb, line 338 def read_from_cache result = if cache.is_a?(Proc) cache.call(nil) elsif File.exist?(cache.to_s) File.read(cache) end result if valid_rates?(result) end
Read from url
@return [String] JSON content
# File lib/money/bank/open_exchange_rates_bank.rb, line 357 def read_from_url raise NoAppId if app_id.nil? || app_id.empty? @json_response = api_response save_cache if cache @json_response end
Refresh expiration from now
@return [Time] new expiration time
# File lib/money/bank/open_exchange_rates_bank.rb, line 397 def refresh_rates_expiration @rates_expiration = rates_timestamp + ttl_in_seconds end
Save rates on cache Can raise InvalidCache
@return [Proc,File]
# File lib/money/bank/open_exchange_rates_bank.rb, line 283 def save_cache store_in_cache(@json_response) if valid_rates?(@json_response) rescue Errno::ENOENT raise InvalidCache end
Store the provided text data by calling the proc method provided for the cache, or write to the cache file. Can raise InvalidCache
@example
oxr.store_in_cache("{\"rates\": {\"AED\": 3.67304}}")
@param text [String] String to cache @return [String,Integer]
# File lib/money/bank/open_exchange_rates_bank.rb, line 323 def store_in_cache(text) if cache.is_a?(Proc) cache.call(text) elsif cache.is_a?(String) || cache.is_a?(Pathname) File.open(cache.to_s, 'w') do |f| f.write(text) end else raise InvalidCache end end
Check validity of rates response only for store in cache
@example
oxr.valid_rates?("{\"rates\": {\"AED\": 3.67304}}")
@param [String] text is JSON content @return [Boolean] valid or not
# File lib/money/bank/open_exchange_rates_bank.rb, line 372 def valid_rates?(text) return false unless text parsed = JSON.parse(text) parsed&.key?(RATES_KEY) && parsed&.key?(TIMESTAMP_KEY) rescue JSON::ParserError false end