gte/cmd/android-app/runner/runner.go

206 lines
4.4 KiB
Go
Raw Normal View History

2022-10-18 16:58:12 +02:00
package runner
import (
2022-10-23 12:45:21 +02:00
"encoding/json"
2022-10-18 16:58:12 +02:00
"fmt"
2022-10-23 12:45:21 +02:00
"io"
"sync"
2022-10-20 13:58:48 +02:00
"time"
2022-10-18 16:58:12 +02:00
"ewintr.nl/gte/cmd/android-app/component"
"ewintr.nl/gte/cmd/android-app/screen"
2022-10-23 12:45:21 +02:00
"ewintr.nl/gte/internal/task"
2022-10-18 16:58:12 +02:00
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
2022-10-23 12:45:21 +02:00
"fyne.io/fyne/v2/storage"
2022-10-18 16:58:12 +02:00
)
var runnerLock = sync.Mutex{}
2022-10-18 16:58:12 +02:00
type Runner struct {
fyneApp fyne.App
fyneWindow fyne.Window
conf *component.Configuration
logger *component.Logger
tasks *component.Tasks
screens []screen.Screen
2022-10-20 08:50:52 +02:00
status string
2022-10-18 16:58:12 +02:00
requests chan interface{}
2022-10-20 08:50:52 +02:00
refresh chan bool
2022-10-23 14:08:19 +02:00
fileURI fyne.URI
2022-10-18 16:58:12 +02:00
}
2022-10-23 14:08:19 +02:00
func NewRunner(conf *component.Configuration, fileURI fyne.URI, logger *component.Logger) *Runner {
2022-10-18 16:58:12 +02:00
return &Runner{
status: "init",
conf: conf,
logger: logger,
requests: make(chan interface{}),
2022-10-20 08:50:52 +02:00
refresh: make(chan bool),
2022-10-23 14:08:19 +02:00
fileURI: fileURI,
2022-10-18 16:58:12 +02:00
}
}
func (r *Runner) Init() fyne.CanvasObject {
2022-10-18 16:58:12 +02:00
logScreen := screen.NewLog()
logTab := container.NewTabItem("log", logScreen.Content())
r.screens = append(r.screens, logScreen)
configScreen := screen.NewConfig(r.requests)
configTab := container.NewTabItem("config", configScreen.Content())
r.screens = append(r.screens, configScreen)
2022-10-23 14:08:19 +02:00
stored, err := load(r.fileURI)
2022-10-18 16:58:12 +02:00
if err != nil {
r.logger.Log(err.Error())
}
2022-10-23 12:45:21 +02:00
r.logger.Log(fmt.Sprintf("loaded %d tasks from file", len(stored)))
r.tasks = component.NewTasks(r.conf, stored)
2022-10-18 16:58:12 +02:00
taskScreen := screen.NewTasks(r.requests)
taskTab := container.NewTabItem("tasks", taskScreen.Content())
r.screens = append(r.screens, taskScreen)
tabs := container.NewAppTabs(taskTab, configTab, logTab)
return tabs
2022-10-18 16:58:12 +02:00
}
func (r *Runner) Run() {
2022-10-20 08:50:52 +02:00
go r.refresher()
2022-10-18 16:58:12 +02:00
go r.processRequest()
r.backgroundSync()
2022-10-18 16:58:12 +02:00
}
func (r *Runner) processRequest() {
for req := range r.requests {
r.logger.Log(fmt.Sprintf("processing request %T", req))
2022-10-18 16:58:12 +02:00
switch v := req.(type) {
case screen.SaveConfigRequest:
2022-10-20 10:40:46 +02:00
r.status = "saving..."
r.refresh <- true
2022-10-18 16:58:12 +02:00
for k, val := range v.Fields {
r.conf.Set(k, val)
}
2022-10-20 10:40:46 +02:00
r.logger.Log("new config saved")
r.status = "ready"
2022-10-18 16:58:12 +02:00
case screen.SyncTasksRequest:
r.logger.Log("starting sync request")
2022-10-20 08:50:52 +02:00
r.status = "syncing..."
r.refresh <- true
countDisp, countFetch, err := r.tasks.Sync(r.logger)
2022-10-18 16:58:12 +02:00
if err != nil {
r.logger.Log(err.Error())
}
//if countDisp > 0 || countFetch > 0 {
r.logger.Log(fmt.Sprintf("task sync: dispatched: %d, fetched: %d", countDisp, countFetch))
//}
2022-10-20 10:40:46 +02:00
r.status = "ready"
2022-10-23 12:45:21 +02:00
r.logger.Log("fetching all")
all, err := r.tasks.All()
if err != nil {
r.logger.Log(err.Error())
break
}
r.logger.Log("saving all")
2022-10-23 14:08:19 +02:00
if err := save(r.fileURI, all); err != nil {
2022-10-23 12:45:21 +02:00
r.logger.Log(err.Error())
break
}
r.logger.Log("sync request done")
2022-10-20 10:40:46 +02:00
case screen.MarkTaskDoneRequest:
if err := r.tasks.MarkDone(v.ID); err != nil {
r.logger.Log(err.Error())
}
2022-10-20 14:49:33 +02:00
r.logger.Log(fmt.Sprintf("marked task %q done", v.ID))
2022-10-18 16:58:12 +02:00
default:
r.logger.Log("request unknown")
}
r.refresh <- true
r.logger.Log("processing request done")
2022-10-18 16:58:12 +02:00
}
2022-10-18 16:58:12 +02:00
}
2022-10-20 08:50:52 +02:00
func (r *Runner) refresher() {
for <-r.refresh {
r.logger.Log("start refresh")
2022-10-20 08:50:52 +02:00
tasks, err := r.tasks.Today()
if err != nil {
r.logger.Log(err.Error())
}
2022-10-23 12:45:21 +02:00
r.logger.Log(fmt.Sprintf("found %d tasks", len(tasks)))
2022-10-20 10:40:46 +02:00
sTasks := []screen.Task{}
for id, action := range tasks {
sTasks = append(sTasks, screen.Task{
ID: id,
Action: action,
})
}
2022-10-20 08:50:52 +02:00
state := screen.State{
Status: r.status,
2022-10-20 10:40:46 +02:00
Tasks: sTasks,
2022-10-20 08:50:52 +02:00
Config: r.conf.Fields(),
Logs: r.logger.Lines(),
}
2022-10-20 08:50:52 +02:00
for _, s := range r.screens {
s.Refresh(state)
}
2022-10-18 16:58:12 +02:00
}
}
2022-10-20 13:58:48 +02:00
func (r *Runner) backgroundSync() {
ticker := time.NewTicker(15 * time.Second)
2022-10-20 13:58:48 +02:00
for {
r.requests <- screen.SyncTasksRequest{}
<-ticker.C
2022-10-20 13:58:48 +02:00
}
}
2022-10-23 12:45:21 +02:00
2022-10-23 14:08:19 +02:00
func load(fu fyne.URI) ([]*task.Task, error) {
fr, err := storage.Reader(fu)
2022-10-23 12:45:21 +02:00
if err != nil {
return []*task.Task{}, err
}
defer fr.Close()
2022-10-23 14:08:19 +02:00
exists, err := storage.Exists(fu)
2022-10-23 12:45:21 +02:00
if !exists {
return []*task.Task{}, fmt.Errorf("uri does not exist")
}
if err != nil {
return []*task.Task{}, err
}
data, err := io.ReadAll(fr)
if err != nil {
return []*task.Task{}, err
}
storedTasks := []*task.Task{}
if err := json.Unmarshal(data, &storedTasks); err != nil {
return []*task.Task{}, err
}
return storedTasks, nil
}
2022-10-23 14:08:19 +02:00
func save(fu fyne.URI, tasks []*task.Task) error {
fw, err := storage.Writer(fu)
2022-10-23 12:45:21 +02:00
if err != nil {
return err
}
data, err := json.Marshal(tasks)
if err != nil {
return err
}
if _, err := fw.Write(data); err != nil {
return err
}
defer fw.Close()
return nil
}