tijl.dev-core/internal/apps/inflation/main.go
tijl 9ada121417
All checks were successful
release-tag / release-image (push) Successful in 15m32s
build / build (push) Successful in 42s
inflation implementation
2024-09-08 01:31:07 +02:00

174 lines
3.9 KiB
Go

package inflation
import (
"embed"
"fmt"
"html/template"
"io"
"net/http"
"os"
"time"
"git.tijl.dev/tijl/tijl.dev-core/internal/config"
"git.tijl.dev/tijl/tijl.dev-core/modules/i18n"
log "git.tijl.dev/tijl/tijl.dev-core/modules/logger"
"git.tijl.dev/tijl/tijl.dev-core/modules/web"
"github.com/go-echarts/go-echarts/v2/charts"
"github.com/go-echarts/go-echarts/v2/opts"
"github.com/gofiber/fiber/v2"
)
type Datas struct {
Name string
ProcessFunction func(map[time.Time]float32) map[time.Time]float32
}
var rawData = make(map[string]map[time.Time]float32)
var datas = map[string]Datas{
"CPIAUCSL": {
Name: "CPI USA BASE",
ProcessFunction: toPercent,
},
"PCEPI": {
Name: "PCECPI USA",
ProcessFunction: toPercent,
},
"M2SL": {
Name: "M2 USA",
ProcessFunction: toPercent,
},
"CP0000EZ19M086NEST": {
Name: "HICP ECB",
ProcessFunction: toPercent,
},
"MABMM301EZM189S": {
Name: "M3 ECB",
ProcessFunction: toPercent,
},
}
//go:embed locales/*
var Embed embed.FS
func Setup() {
err := LoadData()
if err != nil {
log.Error().Err(err).Msg("inflation.Setup: Error loading data")
}
i18n.RegisterTranslations(Embed, "locales")
web.RegisterAppSetupFunc(func(a *fiber.App) {
a.Get("/app/inflation", func(c *fiber.Ctx) error {
processedData := make(map[string]map[time.Time]float32)
for id, data := range datas {
processedData[id] = data.ProcessFunction(rawData[id])
}
line := charts.NewLine()
startYear, endYear := getYearRange(processedData)
yearList := createYearList(startYear, endYear)
for seriesID, timeData := range processedData {
aggregatedData := aggregateDataByYear(timeData)
yAxisT := []opts.LineData{}
for _, year := range yearList {
if value, exists := aggregatedData[year]; exists {
yAxisT = append(yAxisT, opts.LineData{Value: value})
} else {
yAxisT = append(yAxisT, opts.LineData{Value: nil})
}
}
line.AddSeries(datas[seriesID].Name, yAxisT)
}
line.SetXAxis(yearList)
line.SetGlobalOptions(
charts.WithTitleOpts(opts.Title{
Title: "Inflation",
Subtitle: "Copyright Tijl 2024",
}),
charts.WithDataZoomOpts(opts.DataZoom{
Orient: "horizontal",
Type: "slider",
}),
)
rendered := line.RenderSnippet()
data := *web.Common(c)
data["Title"] = "tmp"
data["RenderedScript"] = template.JS(handleScriptElement(rendered.Script))
data["RenderedElement"] = template.HTML(rendered.Element)
return c.Render("apps/inflation/index", data, "layouts/base")
})
}, 1000)
}
func LoadData() error {
var baseDataPath = config.Config.DataLocation + "/apps/inflation/data/"
if _, err := os.Stat(baseDataPath); os.IsNotExist(err) {
err := os.MkdirAll(baseDataPath, os.ModePerm)
if err != nil {
return err
}
}
// Load fred data
const fredBaseUrl = "https://fred.stlouisfed.org/graph/fredgraph.csv?id="
for id := range datas {
info, err := os.Stat(baseDataPath + id + ".csv")
if !os.IsNotExist(err) {
modTime := info.ModTime()
currentTime := time.Now()
if modTime.Year() == currentTime.Year() && modTime.Month() == currentTime.Month() {
csvdata, err := readCSV(baseDataPath + id + ".csv")
if err != nil {
return err
}
rawData[id] = csvdata
continue
}
}
resp, err := http.Get(fredBaseUrl + id)
log.Debug().Str("id", id).Msg("inflation.LoadData: getting")
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to fetch data: %v", resp.Status)
}
file, err := os.Create(baseDataPath + id + ".csv")
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
if err != nil {
return err
}
csvdata, err := readCSV(baseDataPath + id + ".csv")
if err != nil {
return err
}
rawData[id] = csvdata
}
return nil
}