Use fixer.io currency rates API instead of Yahoo due to Yahoo service issues

This commit is contained in:
Adrian Gallagher
2017-08-28 09:06:53 +10:00
parent 40a4ff4fdb
commit d1bdc6af5d
2 changed files with 111 additions and 15 deletions

View File

@@ -39,10 +39,19 @@ type YahooJSONResponse struct {
}
}
// FixerResponse contains the data fields for the Fixer API response
type FixerResponse struct {
Base string `json:"base"`
Date string `json:"date"`
Rates map[string]float64 `json:"rates"`
}
const (
maxCurrencyPairsPerRequest = 350
yahooYQLURL = "https://query.yahooapis.com/v1/public/yql?"
yahooDatabase = "store://datatables.org/alltableswithkeys"
yahooEnabled = false
fixerAPI = "http://api.fixer.io/latest"
// DefaultCurrencies has the default minimum of FIAT values
DefaultCurrencies = "USD,AUD,EUR,CNY"
// DefaultCryptoCurrencies has the default minimum of crytpocurrency values
@@ -53,6 +62,7 @@ const (
// queries
var (
CurrencyStore map[string]Rate
CurrencyStoreFixer map[string]float64
BaseCurrencies string
CryptoCurrencies string
ErrCurrencyDataNotFetched = errors.New("yahoo currency data has not been fetched yet")
@@ -170,11 +180,11 @@ func SeedCurrencyData(fiatCurrencies string) error {
fiatCurrencies = DefaultCurrencies
}
err := QueryYahooCurrencyValues(fiatCurrencies)
if err != nil {
return ErrQueryingYahoo
if yahooEnabled {
return QueryYahooCurrencyValues(fiatCurrencies)
}
return nil
return FetchFixerCurrencyData()
}
// MakecurrencyPairs takes all supported currency and turns them into pairs.
@@ -196,21 +206,90 @@ func MakecurrencyPairs(supportedCurrencies string) string {
// ConvertCurrency for example converts $1 USD to the equivalent Japanese Yen
// or vice versa.
func ConvertCurrency(amount float64, from, to string) (float64, error) {
currency := common.StringToUpper(from + to)
from = common.StringToUpper(from)
to = common.StringToUpper(to)
_, ok := CurrencyStore[currency]
if from == to {
return amount, nil
}
if yahooEnabled {
currency := from + to
_, ok := CurrencyStore[currency]
if !ok {
err := SeedCurrencyData(currency[:len(from)] + "," + currency[len(to):])
if err != nil {
return 0, err
}
}
result, ok := CurrencyStore[currency]
if !ok {
return 0, ErrCurrencyNotFound
}
return amount * result.Rate, nil
}
_, ok := CurrencyStoreFixer[from]
if !ok {
err := SeedCurrencyData(currency[:len(from)] + "," + currency[len(to):])
err := FetchFixerCurrencyData()
if err != nil {
return 0, err
}
}
result, ok := CurrencyStore[currency]
var resultFrom float64
var resultTo float64
// First check if we're converting to USD, USD doesn't exist in the rates map
if to == "USD" {
resultFrom, ok = CurrencyStoreFixer[from]
if !ok {
return 0, ErrCurrencyNotFound
}
return amount / resultFrom, nil
}
// Check to see if we're converting from USD
if from == "USD" {
resultTo, ok = CurrencyStoreFixer[to]
if !ok {
return 0, ErrCurrencyNotFound
}
return resultTo * amount, nil
}
// Otherwise convert to USD, then to the target currency
resultFrom, ok = CurrencyStoreFixer[from]
if !ok {
return 0, ErrCurrencyNotFound
}
return amount * result.Rate, nil
converted := amount / resultFrom
resultTo, ok = CurrencyStoreFixer[to]
if !ok {
return 0, ErrCurrencyNotFound
}
return converted * resultTo, nil
}
// FetchFixerCurrencyData seeds the variable C
func FetchFixerCurrencyData() error {
var result FixerResponse
values := url.Values{}
values.Set("base", "USD")
url := common.EncodeURLValues(fixerAPI, values)
CurrencyStoreFixer = make(map[string]float64)
err := common.SendHTTPGetRequest(url, true, &result)
if err != nil {
return err
}
CurrencyStoreFixer = result.Rates
return nil
}
// FetchYahooCurrencyData seeds the variable CurrencyStore; this is a

View File

@@ -274,12 +274,14 @@ func TestSeedCurrencyData(t *testing.T) {
err2, currencyRequestUSDAUD,
)
}
err3 := SeedCurrencyData(currencyRequestObtuse)
if err3 == nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err3, currencyRequestObtuse,
)
if yahooEnabled {
err3 := SeedCurrencyData(currencyRequestObtuse)
if err3 == nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err3, currencyRequestObtuse,
)
}
}
}
@@ -323,7 +325,18 @@ func TestConvertCurrency(t *testing.T) {
}
}
func TestFetchFixerCurrencyData(t *testing.T) {
err := FetchFixerCurrencyData()
if err != nil {
t.Errorf("Test failed. FetchFixerCurrencyData returned %s", err)
}
}
func TestFetchYahooCurrencyData(t *testing.T) {
if !yahooEnabled {
return
}
t.Parallel()
var fetchData []string
fiatCurrencies := DefaultCurrencies
@@ -344,6 +357,10 @@ func TestFetchYahooCurrencyData(t *testing.T) {
}
func TestQueryYahooCurrencyValues(t *testing.T) {
if !yahooEnabled {
return
}
err := QueryYahooCurrencyValues(DefaultCurrencies)
if err != nil {
t.Errorf("Test Failed. QueryYahooCurrencyValues: Error, %s", err)