save state

This commit is contained in:
Erik Winter 2022-10-23 12:45:21 +02:00
parent 8bed9a0d9b
commit 25413a6b00
9 changed files with 133 additions and 24 deletions

2
.gitignore vendored
View File

@ -4,4 +4,4 @@
/gte-daemon
test.db
*.apk
tasks.json

View File

@ -16,7 +16,7 @@ func NewLogger() *Logger {
}
func (l *Logger) Log(line string) {
l.lines = append(l.lines, fmt.Sprintf("%s: %s", time.Now().Format(time.Stamp), line))
l.lines = append(l.lines, fmt.Sprintf("%s: %s", time.Now().Format(time.StampMicro), line))
if len(l.lines) > 50 {
l.lines = l.lines[1:]
}

View File

@ -18,8 +18,8 @@ type Tasks struct {
disp *storage.Dispatcher
}
func NewTasks(conf *Configuration) (*Tasks, error) {
local := storage.NewMemory()
func NewTasks(conf *Configuration, tasks []*task.Task) *Tasks {
local := storage.NewMemory(tasks...)
remote := storage.NewRemoteRepository(mstore.NewIMAP(conf.IMAP()))
disp := storage.NewDispatcher(msend.NewSSLSMTP(conf.SMTP()))
@ -27,7 +27,23 @@ func NewTasks(conf *Configuration) (*Tasks, error) {
local: local,
remote: remote,
disp: disp,
}, nil
}
}
func (t *Tasks) All() ([]*task.Task, error) {
lts, err := t.local.FindAll()
if err != nil {
return []*task.Task{}, err
}
for _, lt := range lts {
lt.ApplyUpdate()
}
ts := []*task.Task{}
for _, lt := range lts {
ts = append(ts, &lt.Task)
}
return ts, nil
}
func (t *Tasks) Today() (map[string]string, error) {

View File

@ -13,10 +13,10 @@ func main() {
conf.Load()
logger := component.NewLogger()
runner := runner.NewRunner(conf, logger)
tabs := runner.Init()
r := runner.NewRunner(conf, logger)
tabs := r.Init()
w.SetContent(tabs)
go runner.Run()
go r.Run()
w.ShowAndRun()
}

View File

@ -1,14 +1,18 @@
package runner
import (
"encoding/json"
"fmt"
"io"
"sync"
"time"
"ewintr.nl/gte/cmd/android-app/component"
"ewintr.nl/gte/cmd/android-app/screen"
"ewintr.nl/gte/internal/task"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/storage"
)
var runnerLock = sync.Mutex{}
@ -45,11 +49,12 @@ func (r *Runner) Init() fyne.CanvasObject {
configTab := container.NewTabItem("config", configScreen.Content())
r.screens = append(r.screens, configScreen)
tasks, err := component.NewTasks(r.conf)
stored, err := load()
if err != nil {
r.logger.Log(err.Error())
}
r.tasks = tasks
r.logger.Log(fmt.Sprintf("loaded %d tasks from file", len(stored)))
r.tasks = component.NewTasks(r.conf, stored)
taskScreen := screen.NewTasks(r.requests)
taskTab := container.NewTabItem("tasks", taskScreen.Content())
r.screens = append(r.screens, taskScreen)
@ -88,8 +93,19 @@ func (r *Runner) processRequest() {
r.logger.Log(fmt.Sprintf("task sync: dispatched: %d, fetched: %d", countDisp, countFetch))
//}
r.status = "ready"
r.logger.Log("sync request done")
r.logger.Log("fetching all")
all, err := r.tasks.All()
if err != nil {
r.logger.Log(err.Error())
break
}
r.logger.Log("saving all")
if err := save(all); err != nil {
r.logger.Log(err.Error())
break
}
r.logger.Log("sync request done")
case screen.MarkTaskDoneRequest:
if err := r.tasks.MarkDone(v.ID); err != nil {
r.logger.Log(err.Error())
@ -111,6 +127,7 @@ func (r *Runner) refresher() {
if err != nil {
r.logger.Log(err.Error())
}
r.logger.Log(fmt.Sprintf("found %d tasks", len(tasks)))
sTasks := []screen.Task{}
for id, action := range tasks {
sTasks = append(sTasks, screen.Task{
@ -139,3 +156,50 @@ func (r *Runner) backgroundSync() {
<-ticker.C
}
}
func load() ([]*task.Task, error) {
uri := storage.NewFileURI("tasks.json")
fr, err := storage.Reader(uri)
if err != nil {
return []*task.Task{}, err
}
defer fr.Close()
exists, err := storage.Exists(uri)
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
}
func save(tasks []*task.Task) error {
uri := storage.NewFileURI("tasks.json")
fw, err := storage.Writer(uri)
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
}

View File

@ -21,6 +21,7 @@ type Tasks struct {
tasks []Task
taskLabels binding.StringList
selectedTask string
list *widget.List
out chan interface{}
}
@ -44,6 +45,9 @@ func (t *Tasks) Refresh(state State) {
tls = append(tls, t.Action)
}
t.taskLabels.Set(tls)
if t.selectedTask == "" {
t.list.UnselectAll()
}
}
func (t *Tasks) Content() fyne.CanvasObject {
@ -53,7 +57,7 @@ func (t *Tasks) Content() fyne.CanvasObject {
doneButton := widget.NewButton("done", func() {
t.markDone()
})
list := widget.NewListWithData(
t.list = widget.NewListWithData(
t.taskLabels,
func() fyne.CanvasObject {
return widget.NewLabel("template")
@ -62,14 +66,14 @@ func (t *Tasks) Content() fyne.CanvasObject {
o.(*widget.Label).Bind(i.(binding.String))
},
)
list.OnSelected = t.selectItem
t.list.OnSelected = t.selectItem
return container.NewBorder(
container.NewHBox(statusLabel),
doneButton,
nil,
nil,
list,
t.list,
)
}
@ -89,4 +93,5 @@ func (t *Tasks) markDone() {
t.out <- MarkTaskDoneRequest{
ID: t.selectedTask,
}
t.selectedTask = ""
}

View File

@ -13,9 +13,17 @@ type Memory struct {
latestSync time.Time
}
func NewMemory() *Memory {
func NewMemory(initTasks ...*task.Task) *Memory {
tasks := map[string]*task.LocalTask{}
for _, t := range initTasks {
tasks[t.Id] = &task.LocalTask{
Task: *t,
LocalUpdate: &task.LocalUpdate{},
}
}
return &Memory{
tasks: map[string]*task.LocalTask{},
tasks: tasks,
}
}

View File

@ -1,6 +1,7 @@
package task
import (
"encoding/json"
"fmt"
"sort"
"strings"
@ -49,6 +50,21 @@ type Date struct {
t time.Time
}
func (d *Date) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}
func (d *Date) UnmarshalJSON(data []byte) error {
dateString := ""
if err := json.Unmarshal(data, &dateString); err != nil {
return err
}
nd := NewDateFromString(dateString)
d.t = nd.Time()
return nil
}
func NewDate(year, month, day int) Date {
if year == 0 || month == 0 || month > 12 || day == 0 {

View File

@ -64,15 +64,15 @@ type Task struct {
// local situations. It will be filtered out in LocalRepository.SetTasks()
Message *mstore.Message
Id string
Version int
Folder string
Id string `json:"id"`
Version int `json:"version"`
Folder string `json:"folder"`
Action string
Project string
Due Date
Recur Recurrer
Done bool
Action string `json:"action"`
Project string `json:"project"`
Due Date `json:"date"`
Recur Recurrer `json:"-"`
Done bool `json:"done"`
}
func NewFromMessage(msg *mstore.Message) *Task {