Expensive bee

This commit is contained in:
2026-02-03 16:49:05 +02:00
parent d3f29e3927
commit cdcdf2c644
10 changed files with 376 additions and 50 deletions

52
main.go
View File

@@ -16,9 +16,19 @@ import (
const helpText = `woke - TUI alarm clock with REST API
Usage:
woke Start the TUI (API server runs on :9119)
woke Start the TUI (API server runs on :9119 in host mode)
woke --help Show this help
Modes:
Host mode (default): Uses local SQLite, exposes REST API on :9119
Client mode: Connects to remote woke server, syncs alarms, fires locally
Configure mode in Settings (press 'c'):
- Server URL: empty = host mode, or http://host:9119 for client mode
- Server pass: password to authenticate with remote server
- API password: password required for incoming API requests (host mode)
- Poll seconds: how often client polls server for alarm updates
API endpoints (http://localhost:9119):
List alarms:
@@ -48,6 +58,9 @@ API endpoints (http://localhost:9119):
Delete alarm:
curl -X DELETE http://localhost:9119/api/alarms/1
With authentication (if API password is set):
curl -H 'Authorization: Bearer yourpassword' http://localhost:9119/api/alarms
TUI keybindings:
j/k Navigate alarms
a Add alarm
@@ -64,6 +77,7 @@ func main() {
os.Exit(0)
}
// Always open local store for settings
store, err := db.Open()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to open database: %v\n", err)
@@ -71,23 +85,37 @@ func main() {
}
defer store.Close()
settings := store.LoadSettings()
clientMode := settings.ServerURL != ""
// Determine alarm store: local DB or remote API
var alarmStore db.AlarmStore
if clientMode {
alarmStore = api.NewClient(settings.ServerURL, settings.ServerPassword)
fmt.Fprintf(os.Stderr, "Client mode: connecting to %s\n", settings.ServerURL)
} else {
alarmStore = store
}
pl := player.New()
sched := scheduler.New(store)
sched := scheduler.New(alarmStore, clientMode)
sched.Start()
defer sched.Stop()
model := ui.NewModel(store, sched, pl)
model := ui.NewModel(store, alarmStore, sched, pl, clientMode)
p := tea.NewProgram(model, tea.WithAltScreen())
// Start HTTP API server — notify TUI on mutations via p.Send
srv := api.New(store, func() { p.Send(ui.AlarmsChangedMsg{}) })
go func() {
addr := ":9119"
fmt.Fprintf(os.Stderr, "API server listening on %s\n", addr)
if err := http.ListenAndServe(addr, srv.Handler()); err != nil {
fmt.Fprintf(os.Stderr, "API server error: %v\n", err)
}
}()
// Start HTTP API server only in host mode
if !clientMode {
srv := api.New(store, settings.APIPassword, func() { p.Send(ui.AlarmsChangedMsg{}) })
go func() {
addr := ":9119"
fmt.Fprintf(os.Stderr, "API server listening on %s\n", addr)
if err := http.ListenAndServe(addr, srv.Handler()); err != nil {
fmt.Fprintf(os.Stderr, "API server error: %v\n", err)
}
}()
}
if _, err := p.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)