Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jolle-c
Created March 27, 2015 22:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jolle-c/58b030dd546f26fac4a2 to your computer and use it in GitHub Desktop.
Save jolle-c/58b030dd546f26fac4a2 to your computer and use it in GitHub Desktop.
Thread object to serve a fairly accurate exchange rate for a given currency
[
/**!
kin_exchangerates
Thread object to serve a fairly accurate exchange rate for a given currency
To install, go to https://www.openexchangerates.org and sign up for an account.
Insert the app_id below and store the thread file where it will be loaded at startup.
Attempts to update the rates are limited to no more than once an hour.
Call to update rates will be triggered by the first call for a rate. Not when the thread is initialized.
NB. This has been written with the aim to give correct rates for a Swedish usage. For usage within the US it should probably be written in another fashion.
If you want to implement this in another country, change the caller data to an appropriate value
Example usage
kin_exchangerates -> get('AUD')
kin_exchangerates -> get('DKK')
kin_exchangerates -> get('EUR')
kin_exchangerates -> lasttry // will return a date for the latest attempt to update the rates
kin_exchangerates -> timestamp // will return a date for when the rates were calculated on openexchangerates.org
*/
define kin_exchangerates => thread {
data
public app_id::string = 'SupplyOwnIDHere',
public caller::string = 'SEK',
public lasttry::date,
public base::string,
public rates::map = map,
public timestamp::date,
public calling::decimal = 0.0,
public baserate::decimal = 0.0
public updaterates => {
if(not .lasttry or duration(.lasttry, date) -> minute > 60) => {
.lasttry = date
local(
exchangeresponse = jc_include_url(
'http://openexchangerates.org/api/latest.json',
-getParams = (:
'app_id'= .app_id
),
-reqMethod = `GET`,
-timeout = 300
),
exchangeobject
)
protect => {
#exchangeobject = json_deserialize(#exchangeresponse)
}
if(#exchangeobject -> isa(::map)) => {
.base = #exchangeobject -> find('base')
.rates = #exchangeobject -> find('rates') or map
.timestamp = date(#exchangeobject -> find('timestamp') or 0)
.calling = decimal(.rates -> find(.caller))
.baserate = decimal(.rates -> find(.base))
}
}
}
public get(currency::string) => {
protect => {
handle_error => {
log_critical('Error in kin_exchangerates -> get(' + #currency + ') ' + error_msg)
error_reset
return
}
if(not .lasttry or not .timestamp or duration(.timestamp, date) -> minute > 60) => {
.updaterates
}
fail_if(not .baserate or .baserate == 0.00, -1, 'Seems to be a problem with the exchange baserate')
fail_if(not .calling or .calling == 0.00, -1, 'Seems to be a problem with the exchange calling rate')
local(currencyrate = .rates -> find(#currency))
fail_if(not #currencyrate, -1, 'Seems to be a problem with the finding the currency: ' + #currency)
return ((.baserate/#currencyrate)/(.baserate/.calling))
}
}
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment