class Money::Bank::JsonRates
Money::Bank
implementation that gives access to the current exchange rates using jsonrates.com api.
Constants
- SERVICE_HOST
Host of service jsonrates
- SERVICE_PATH
Relative path of jsonrates api
Attributes
@return [Boolean] Returns is Rates Careful mode set.
@return [Time] Returns the time when the rates expire.
@return [Integer] Returns the Time To Live (TTL) in seconds.
accessor of api_key
of jsonrates.com service
@return [Hash] Stores the currently known rates.
Public Class Methods
Set Rates Careful mode
@param [Boolean] value - mode Careful, if set - don’t reload cache if get some exception
# File lib/money/bank/json_rates.rb, line 52 def rates_careful= value @rates_careful = !!value end
Set the rates expiration TTL seconds from the current time.
@return [Time] The next expiration.
# File lib/money/bank/json_rates.rb, line 69 def refresh_rates_expiration! @rates_expiration = Time.now + ttl_in_seconds end
Set the Time To Live (TTL) in seconds.
@param [Integer] value - the seconds between an expiration and another.
# File lib/money/bank/json_rates.rb, line 60 def ttl_in_seconds= value @ttl_in_seconds = value refresh_rates_expiration! if ttl_in_seconds end
Public Instance Methods
Registers a conversion rate and returns it (uses #set_rate
).
@param [Currency, String, Symbol] from Currency to exchange from. @param [Currency, String, Symbol] to Currency to exchange to. @param [Numeric] rate Rate to use when exchanging currencies.
@return [Numeric]
@example
bank = Money::Bank::JsonRates.new #=> <Money::Bank::JsonRates...> bank.add_rate("USD", "CAD", 1.24515) #=> 1.24515 bank.add_rate("CAD", "USD", 0.803115) #=> 0.803115
# File lib/money/bank/json_rates.rb, line 143 def add_rate from, to, rate set_rate from, to, rate end
Flushes all the rates if they are expired.
@return [Boolean]
# File lib/money/bank/json_rates.rb, line 194 def expire_rates if expired? flush_rates self.class.refresh_rates_expiration! true else false end end
Clears the specified rate stored in @rates.
@param [String, Symbol, Currency] from Currency to convert from (used
for key into @rates).
@param [String, Symbol, Currency] to Currency to convert to (used for
key into @rates).
@return [Float] The flushed rate.
@example
bank = Money::Bank::JsonRates.new #=> <Money::Bank::JsonRates...> bank.get_rate(:USD, :EUR) #=> 0.776337241 bank.flush_rate(:USD, :EUR) #=> 0.776337241
# File lib/money/bank/json_rates.rb, line 103 def flush_rate(from, to) key = rate_key_for(from, to) @mutex.synchronize{ @rates.delete(key) } end
Clears all rates stored in @rates
@return [Hash] The empty @rates Hash.
@example
bank = Money::Bank::JsonRates.new #=> <Money::Bank::JsonRates...> bank.get_rate(:USD, :EUR) #=> 0.776337241 bank.flush_rates #=> {}
# File lib/money/bank/json_rates.rb, line 83 def flush_rates @mutex.synchronize{ @rates = {} } end
Returns the requested rate.
It uses #get_rate_careful
or #get_rate_straight
respect of @rates_careful value
@param [String, Symbol, Currency] from Currency to convert from @param [String, Symbol, Currency] to Currency to convert to
@return [Float] The requested rate.
@example
bank = Money::Bank::JsonRates.new #=> <Money::Bank::JsonRates...> bank.get_rate(:USD, :EUR) #=> 0.776337241
# File lib/money/bank/json_rates.rb, line 123 def get_rate(from, to) if self.class.rates_careful get_rate_careful(from, to) else get_rate_straight(from, to) end end
Return the rate hashkey for the given currencies.
@param [Currency, String, Symbol] from The currency to exchange from. @param [Currency, String, Symbol] to The currency to exchange to.
@return [String]
@example
rate_key_for("USD", "CAD") #=> "USD_TO_CAD" Money::Bank::JsonRates.rates_careful = true rate_key_for("USD", "CAD") #=> "USD_TO_CAD_C"
# File lib/money/bank/json_rates.rb, line 182 def rate_key_for(from, to) if self.class.rates_careful "#{Currency.wrap(from).iso_code}_TO_#{Currency.wrap(to).iso_code}_C".upcase else super end end
Set the rate for the given currencies. Uses Mutex
to synchronize data access.
@param [Currency, String, Symbol] from Currency to exchange from. @param [Currency, String, Symbol] to Currency to exchange to. @param [Numeric] rate Rate to use when exchanging currencies. @param [Hash] opts Options hash to set special parameters @option opts [Boolean] :without_mutex disables the usage of a mutex
@return [Numeric]
@example
@bank = Money::Bank::JsonRates.new #=> <Money::Bank::JsonRates...> bank.set_rate("USD", "CAD", 1.24515) #=> 1.24515 bank.set_rate("CAD", "USD", 0.803115) #=> 0.803115
# File lib/money/bank/json_rates.rb, line 162 def set_rate from, to, rate if self.class.rates_careful set_rate_with_time(from, to, rate) else super end end
Private Instance Methods
Registers a conversion rate with created_at and returns it (uses #set_rate_with_time
).
@param [Currency, String, Symbol] from Currency to exchange from. @param [Currency, String, Symbol] to Currency to exchange to. @param [Numeric] rate Rate to use when exchanging currencies.
@return [Numeric]
# File lib/money/bank/json_rates.rb, line 269 def add_rate_with_time(from, to, rate) set_rate_with_time(from, to, rate) end
Build a URI for the given arguments.
@param [Currency] from The currency to convert from. @param [Currency] to The currency to convert to.
@return [URI::HTTP]
# File lib/money/bank/json_rates.rb, line 333 def build_uri(from, to) from, to = Currency.wrap(from), Currency.wrap(to) raise NoApiKey if api_key.nil? || api_key.empty? uri = URI::HTTP.build( :host => SERVICE_HOST, :path => SERVICE_PATH, :query => "from=#{from.iso_code}&to=#{to.iso_code}&apiKey=#{api_key}" ) end
Returns whether the time expired.
@return [Boolean]
# File lib/money/bank/json_rates.rb, line 210 def expired? self.class.ttl_in_seconds && self.class.rates_expiration <= Time.now end
Check if time is expired
@param [Time] time Time to check
@return [Boolean] Is the time expired.
# File lib/money/bank/json_rates.rb, line 297 def expired_time? time time + self.class.ttl_in_seconds.to_i < Time.now end
Takes the response from jsonrates.com and extract the rate.
@param [String] data HTTP-Response of api.
@return [BigDecimal]
# File lib/money/bank/json_rates.rb, line 349 def extract_rate(data) request_hash = JSON.parse(data) error = request_hash['error'] raise JsonRatesRequestError, request_hash['error'] unless (error.nil? || error.empty?) BigDecimal.new(request_hash['rate']) end
Queries for the requested rate and returns it.
@param [String, Symbol, Currency] from Currency to convert from @param [String, Symbol, Currency] to Currency to convert to
@return [BigDecimal] The requested rate.
# File lib/money/bank/json_rates.rb, line 308 def fetch_rate(from, to) uri = build_uri(from, to) data = perform_request(uri) extract_rate(data) end
Returns the requested rate.
It not flushes all the rates and create rates with created_at time. Check expired for each rate respectively. If it can’t get new rate by some reason it returns cached value.
@param [String, Symbol, Currency] from Currency to convert from @param [String, Symbol, Currency] to Currency to convert to
@return [Float] The requested rate.
# File lib/money/bank/json_rates.rb, line 225 def get_rate_careful(from, to) rate_key = rate_key_for(from, to) rate_cached = @rates[rate_key] if rate_cached.nil? || expired_time?(rate_cached[:created_at]) set_rate_with_time(from, to, fetch_rate(from, to)) @rates[rate_key][:rate] else rate_cached[:rate] end rescue JsonRatesRequestError => e if rate_cached.nil? raise e else rate_cached[:rate] end end
Returns the requested rate.
It also flushes all the rates when and if they are expired.
@param [String, Symbol, Currency] from Currency to convert from @param [String, Symbol, Currency] to Currency to convert to
@return [Float] The requested rate.
# File lib/money/bank/json_rates.rb, line 253 def get_rate_straight(from, to) expire_rates @mutex.synchronize{ @rates[rate_key_for(from, to)] ||= fetch_rate(from, to) } end
Performs request on uri or raise exception message with JsonRatesRequestError
@param [String] uri Requested uri
@return [String]
# File lib/money/bank/json_rates.rb, line 320 def perform_request(uri) uri.read rescue Exception => e raise JsonRatesRequestError, e.message end
Set the rate and created_at time for the given currencies. Uses Mutex
to synchronize data access.
@param [Currency, String, Symbol] from Currency to exchange from. @param [Currency, String, Symbol] to Currency to exchange to. @param [Numeric] rate Rate to use when exchanging currencies. @param [Hash] opts Options hash to set special parameters @option opts [Boolean] :without_mutex disables the usage of a mutex
@return [Numeric]
# File lib/money/bank/json_rates.rb, line 283 def set_rate_with_time(from, to, rate) rate_d = BigDecimal.new(rate.to_s) @mutex.synchronize { @rates[rate_key_for(from, to)] = {rate: rate_d, created_at: Time.now} } rate_d end