From d80f4872dc9cf060298f17bd8f5e76a12aa8f42d Mon Sep 17 00:00:00 2001 From: amueller Date: Wed, 16 Oct 2024 18:41:06 +0200 Subject: [PATCH 1/2] #236 support currencies for markets widget --- internal/feed/primitives.go | 1 + internal/feed/yahoo.go | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/internal/feed/primitives.go b/internal/feed/primitives.go index 755b0026..3da888aa 100644 --- a/internal/feed/primitives.go +++ b/internal/feed/primitives.go @@ -113,6 +113,7 @@ type DNSStatsBlockedDomain struct { type MarketRequest struct { Name string `yaml:"name"` Symbol string `yaml:"symbol"` + Currency string `yaml:"currency"` ChartLink string `yaml:"chart-link"` SymbolLink string `yaml:"symbol-link"` } diff --git a/internal/feed/yahoo.go b/internal/feed/yahoo.go index f9626952..2535864e 100644 --- a/internal/feed/yahoo.go +++ b/internal/feed/yahoo.go @@ -1,6 +1,7 @@ package feed import ( + "encoding/json" "fmt" "log/slog" "net/http" @@ -27,6 +28,30 @@ type marketResponseJson struct { // TODO: allow changing chart time frame const marketChartDays = 21 +func FetchUSDExchangeRate(currency string) (float64, error) { + url := fmt.Sprintf("https://query1.finance.yahoo.com/v8/finance/chart/USD%s=X?range=1d&interval=1d", currency) + resp, err := http.Get(url) + if err != nil { + return 0, fmt.Errorf("failed to fetch exchange rate: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return 0, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + var response marketResponseJson + if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { + return 0, fmt.Errorf("failed to decode response: %w", err) + } + + if len(response.Chart.Result) == 0 { + return 0, fmt.Errorf("no result in response") + } + + return response.Chart.Result[0].Meta.RegularMarketPrice, nil +} + func FetchMarketsDataFromYahoo(marketRequests []MarketRequest) (Markets, error) { requests := make([]*http.Request, 0, len(marketRequests)) @@ -80,6 +105,19 @@ func FetchMarketsDataFromYahoo(marketRequests []MarketRequest) (Markets, error) currency = response.Chart.Result[0].Meta.Currency } + if marketRequests[i].Currency != "" { + exchangeRate, err := FetchUSDExchangeRate(marketRequests[i].Currency) + if err != nil { + slog.Error("Failed to fetch USD/EUR exchange rate", "error", err) + continue + } + + if response.Chart.Result[0].Meta.Currency == "USD" { + response.Chart.Result[0].Meta.RegularMarketPrice *= exchangeRate + currency = currencyToSymbol[marketRequests[i].Currency] + } + } + markets = append(markets, Market{ MarketRequest: marketRequests[i], Price: response.Chart.Result[0].Meta.RegularMarketPrice, From 5f27218dcbf13872c8726c04e5a2ea79966b31fb Mon Sep 17 00:00:00 2001 From: amueller Date: Thu, 17 Oct 2024 17:22:46 +0200 Subject: [PATCH 2/2] #236 fixed change rate calc bug --- internal/feed/yahoo.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/feed/yahoo.go b/internal/feed/yahoo.go index 2535864e..f3979af8 100644 --- a/internal/feed/yahoo.go +++ b/internal/feed/yahoo.go @@ -108,12 +108,13 @@ func FetchMarketsDataFromYahoo(marketRequests []MarketRequest) (Markets, error) if marketRequests[i].Currency != "" { exchangeRate, err := FetchUSDExchangeRate(marketRequests[i].Currency) if err != nil { - slog.Error("Failed to fetch USD/EUR exchange rate", "error", err) + slog.Error("Failed to fetch USD exchange rate", "error", err) continue } if response.Chart.Result[0].Meta.Currency == "USD" { response.Chart.Result[0].Meta.RegularMarketPrice *= exchangeRate + previous *= exchangeRate currency = currencyToSymbol[marketRequests[i].Currency] } }