Home

mint @5732331b253e024e4f0da97d353b0eb29dd87723 - refs - log -
-
https://git.jolheiser.com/mint.git
Budget
mint / main.go
- raw -
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package main

import (
	_ "embed"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"time"
)

var (
	//go:embed index.html
	_indexTmpl string
	indexTmpl  = template.Must(template.New("").Parse(_indexTmpl))
	//go:embed budget.json
	_json []byte
)

type Event struct {
	ID            string         `json:"id"`
	AllDay        bool           `json:"allDay"`
	Start         time.Time      `json:"start"`
	Title         string         `json:"title"`
	ExtendedProps map[string]any `json:"extendedProps"`
}

func maine() error {
	fs := flag.NewFlagSet("mint", flag.ExitOnError)
	portFlag := fs.Int("port", 8080, "Port to run on")
	fs.IntVar(portFlag, "p", *portFlag, "--port")

	if err := fs.Parse(os.Args[1:]); err != nil {
		return fmt.Errorf("could not parse CLI arguments: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		indexTmpl.Execute(w, nil)
	})
	mux.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
		var budget []struct {
			Title  string
			Amount float64
			Date   time.Time
		}
		if err := json.Unmarshal(_json, &budget); err != nil {
			slog.Error("could not unmarshal budget", slog.Any("err", err))
		}
		var events []Event
		var id int
		for _, b := range budget {
			events = append(events, Event{
				ID:     strconv.Itoa(id),
				AllDay: true,
				Start:  b.Date,
				Title:  fmt.Sprintf("%s ($%.2f)", b.Title, b.Amount),
				ExtendedProps: map[string]any{
					"title":     b.Title,
					"amount":    int(b.Amount * 100),
					"recurring": true,
				},
			})
			id++
		}
		w.Header().Set("Content-Type", "application/json")
		if err := json.NewEncoder(w).Encode(events); err != nil {
			slog.Error("could not marshal budget data", slog.Any("err", err))
		}
	})

	go func() {
		addr := fmt.Sprintf(":%d", *portFlag)
		slog.Debug(fmt.Sprintf("Listening at http://localhost%s", addr))
		if err := http.ListenAndServe(addr, mux); err != nil {
			panic(err)
		}
	}()

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, os.Kill, os.Interrupt)
	<-ch

	return nil
}

func main() {
	if err := maine(); err != nil {
		slog.Error("error during runtime", slog.Any("err", err))
	}
}