Created
March 27, 2015 22:57
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
/**! | |
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