This commit is contained in:
parent
270534c0d5
commit
97f4793ec3
36
moonmath.go
36
moonmath.go
@ -2,7 +2,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.humancabbage.net/sam/moonmath/coindesk"
|
"code.humancabbage.net/sam/moonmath/coindesk"
|
||||||
@ -19,6 +22,10 @@ var CLI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
logFile := setupLogging()
|
||||||
|
defer func() {
|
||||||
|
_ = logFile.Close()
|
||||||
|
}()
|
||||||
ctx := kong.Parse(&CLI)
|
ctx := kong.Parse(&CLI)
|
||||||
if ctx.Error != nil {
|
if ctx.Error != nil {
|
||||||
fail(ctx.Error)
|
fail(ctx.Error)
|
||||||
@ -42,6 +49,35 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupLogging() io.Closer {
|
||||||
|
homePath, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
programConfigPath := filepath.Join(homePath, ".moonmath")
|
||||||
|
err = os.MkdirAll(programConfigPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
errLogPath := filepath.Join(programConfigPath, "errors.log")
|
||||||
|
errLogFile, err := os.OpenFile(
|
||||||
|
errLogPath,
|
||||||
|
os.O_CREATE|os.O_APPEND|os.O_WRONLY,
|
||||||
|
0600,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.SetDefault(slog.New(
|
||||||
|
slog.NewTextHandler(errLogFile, &slog.HandlerOptions{
|
||||||
|
Level: slog.LevelError,
|
||||||
|
})))
|
||||||
|
return errLogFile
|
||||||
|
}
|
||||||
|
|
||||||
func fail(err error) {
|
func fail(err error) {
|
||||||
fmt.Printf("program error: %v\n", err)
|
fmt.Printf("program error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -3,6 +3,7 @@ package asset
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.humancabbage.net/sam/moonmath/coindesk"
|
"code.humancabbage.net/sam/moonmath/coindesk"
|
||||||
@ -109,31 +110,16 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|||||||
case refresh:
|
case refresh:
|
||||||
m.refreshing = true
|
m.refreshing = true
|
||||||
return m, tea.Batch(
|
return m, tea.Batch(
|
||||||
func() tea.Msg {
|
m.resumeIndicator,
|
||||||
return m.indicator.Tick()
|
m.refresh,
|
||||||
},
|
|
||||||
func() tea.Msg {
|
|
||||||
// TODO: log errors
|
|
||||||
_ = m.math.Refresh(context.TODO())
|
|
||||||
return Msg{m.math.Asset, m.math}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
case moon.Math:
|
case moon.Math:
|
||||||
m.math = msg
|
m.math = msg
|
||||||
refillProperties(&m)
|
refillProperties(&m)
|
||||||
refillProjections(&m)
|
refillProjections(&m)
|
||||||
return m, tea.Batch(
|
return m, tea.Batch(
|
||||||
// schedule the next refresh
|
m.stopIndicator(),
|
||||||
tea.Tick(time.Second*30,
|
m.scheduleRefresh(),
|
||||||
func(t time.Time) tea.Msg {
|
|
||||||
return Msg{m.math.Asset, refresh{}}
|
|
||||||
}),
|
|
||||||
// wait a bit to stop the indicator, so that it's more obvious
|
|
||||||
// even when the refresh completes quickly.
|
|
||||||
tea.Tick(time.Millisecond*500,
|
|
||||||
func(t time.Time) tea.Msg {
|
|
||||||
return Msg{m.math.Asset, stopIndicator{}}
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
case stopIndicator:
|
case stopIndicator:
|
||||||
m.refreshing = false
|
m.refreshing = false
|
||||||
@ -153,6 +139,37 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|||||||
type refresh struct{}
|
type refresh struct{}
|
||||||
type stopIndicator struct{}
|
type stopIndicator struct{}
|
||||||
|
|
||||||
|
func (m Model) refresh() tea.Msg {
|
||||||
|
err := m.math.Refresh(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("refresh",
|
||||||
|
"asset", m.math.Asset,
|
||||||
|
"err", err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return Msg{m.math.Asset, m.math}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) resumeIndicator() tea.Msg {
|
||||||
|
return m.indicator.Tick()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) scheduleRefresh() tea.Cmd {
|
||||||
|
return tea.Tick(time.Second*30,
|
||||||
|
func(t time.Time) tea.Msg {
|
||||||
|
return Msg{m.math.Asset, refresh{}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) stopIndicator() tea.Cmd {
|
||||||
|
// wait a bit to stop the indicator, so that it's more obvious
|
||||||
|
// even when the refresh completes quickly.
|
||||||
|
return tea.Tick(time.Millisecond*500,
|
||||||
|
func(t time.Time) tea.Msg {
|
||||||
|
return Msg{m.math.Asset, stopIndicator{}}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func refillProperties(m *Model) {
|
func refillProperties(m *Model) {
|
||||||
rows := []table.Row{
|
rows := []table.Row{
|
||||||
{"Asset", string(m.math.Asset)},
|
{"Asset", string(m.math.Asset)},
|
||||||
|
Loading…
Reference in New Issue
Block a user