Files
portfolio-tracker/internal/handler/api.go
T
2025-07-05 05:10:42 +02:00

180 lines
4.6 KiB
Go

package handler
import (
"encoding/json"
"fmt"
"net/http"
"portfolio-tracker/internal/model"
"portfolio-tracker/internal/util"
"time"
)
func JsonEndpoint(w http.ResponseWriter, r *http.Request) {
stock := r.URL.Query().Get("stock")
// Standardwerte setzen, falls Parameter fehlen
if stock == "" {
stock = "IDIA.SW"
}
data, err := util.FetchYahooFinanceData(stock)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(data))
}
func YahooMaxDividendsHandler(w http.ResponseWriter, r *http.Request) {
stock := r.URL.Query().Get("stock")
if stock == "" {
http.Error(w, "Fehlender stock-Parameter", http.StatusBadRequest)
return
}
data, err := util.FetchYahooFinanceDataMax(stock)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var resp model.YahooDividendChartResponse
err = json.Unmarshal([]byte(data), &resp)
if err != nil {
http.Error(w, "Fehler beim Parsen der Yahoo-Dividenden-Daten: "+err.Error(), http.StatusInternalServerError)
return
}
var result [][]interface{}
if len(resp.Chart.Result) > 0 {
for _, div := range resp.Chart.Result[0].Events.Dividends {
result = append(result, []interface{}{div.Date * 1000, div.Amount})
}
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
func StockSearchEndpoint(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
if query == "" {
http.Error(w, "Fehlender q-Parameter", http.StatusBadRequest)
return
}
data, err := util.StockSearch(query)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(data))
}
// Helper function to get stock currency from Yahoo Finance
func getStockCurrency(stock string) (string, error) {
// Fetch basic stock data from Yahoo Finance
data, err := util.FetchYahooFinanceData(stock)
if err != nil {
return "", err
}
// Parse the JSON response
var resp util.YahooChartResponse
err = json.Unmarshal([]byte(data), &resp)
if err != nil {
return "", err
}
// Extract currency from the response
if len(resp.Chart.Result) > 0 {
currency := resp.Chart.Result[0].Meta.Currency
if currency != "" {
return currency, nil
}
}
return "", fmt.Errorf("currency not found in response")
}
// ClearCurrencyCacheHandler clears the currency conversion cache
func ClearCurrencyCacheHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Nur POST erlaubt", http.StatusMethodNotAllowed)
return
}
util.ClearCache()
response := map[string]string{
"status": "success",
"message": "Currency cache (including historical rates) cleared successfully",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
// CleanExpiredCacheHandler removes expired cache entries
func CleanExpiredCacheHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Nur POST erlaubt", http.StatusMethodNotAllowed)
return
}
removedCount := util.CleanExpiredCache()
response := map[string]interface{}{
"status": "success",
"message": "Expired cache entries cleaned",
"removed_count": removedCount,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
// CurrencyCacheInfoHandler returns information about the currency cache
func CurrencyCacheInfoHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Nur GET erlaubt", http.StatusMethodNotAllowed)
return
}
detailedCacheInfo := util.GetDetailedCacheInfo()
// Separate historical and current rates
historicalRates := make(map[string]interface{})
currentRates := make(map[string]interface{})
for key, cached := range detailedCacheInfo {
rateInfo := map[string]interface{}{
"rate": cached.Rate,
"timestamp": cached.Timestamp,
"date": cached.Date,
"age_hours": time.Since(cached.Timestamp).Hours(),
}
if cached.Date == cached.Timestamp.Format("2006-01-02") {
currentRates[key] = rateInfo
} else {
historicalRates[key] = rateInfo
}
}
response := map[string]interface{}{
"status": "success",
"total_entries": len(detailedCacheInfo),
"historical_rates": historicalRates,
"current_rates": currentRates,
"historical_count": len(historicalRates),
"current_count": len(currentRates),
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}