non-functional wip state

This commit is contained in:
2025-08-18 18:54:08 +02:00
commit e7293464c1
20 changed files with 534 additions and 0 deletions

73
app/application.go Normal file
View File

@@ -0,0 +1,73 @@
package app
import (
"os"
"os/signal"
"syscall"
"fyne.io/systray"
"mikescher.com/kpsync"
)
type Application struct {
config kpsync.Config
trayReady bool
sigStopChan chan bool
sigErrChan chan error
dbFile string
stateFile string
}
func NewApplication() *Application {
cfg := kpsync.LoadConfig()
return &Application{
config: cfg,
trayReady: false,
sigStopChan: make(chan bool, 128),
sigErrChan: make(chan error, 128),
}
}
func (app *Application) Run() {
go func() { app.initTray() }()
go func() {
err := app.initSync()
if err != nil {
app.sigErrChan <- err
return
}
err = app.runSyncLoop()
if err != nil {
app.sigErrChan <- err
return
}
}()
sigTerm := make(chan os.Signal, 1)
signal.Notify(sigTerm, os.Interrupt, syscall.SIGTERM)
select {
case <-sigTerm:
// TODO term
case _ = <-app.sigErrChan:
// TODO stop
case _ = <-app.sigStopChan:
// TODO stop
}
if app.trayReady {
systray.Quit()
}
}

67
app/sync.go Normal file
View File

@@ -0,0 +1,67 @@
package app
import (
"fmt"
"os"
"path"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"mikescher.com/kpsync/assets"
"mikescher.com/kpsync/log"
)
func (app *Application) initSync() error {
err := os.MkdirAll(app.config.WorkDir, os.ModePerm)
if err != nil {
return exerr.Wrap(err, "").Build()
}
app.dbFile = path.Join(app.config.WorkDir, path.Base(app.config.LocalFallback))
app.stateFile = path.Join(app.config.WorkDir, "kpsync.state")
state := app.readState()
needsDownload := true
if state != nil && fileExists(app.dbFile) {
localCS, err := app.calcLocalChecksum()
if err != nil {
log.LogError("Failed to calculate local database checksum", err)
} else if localCS == state.Checksum {
remoteETag, err := app.getRemoteETag()
if err != nil {
log.LogError("Failed to get remote ETag", err)
} else if remoteETag == state.ETag {
log.LogInfo(fmt.Sprintf("Found local database matching remote database - skip initial download"))
log.LogInfo(fmt.Sprintf("Checksum (cached) := %s", state.Checksum))
log.LogInfo(fmt.Sprintf("Checksum (local) := %s", localCS))
log.LogInfo(fmt.Sprintf("ETag (cached) := %s", state.ETag))
log.LogInfo(fmt.Sprintf("ETag (remote) := %s", remoteETag))
needsDownload = false
}
}
}
if needsDownload {
func() {
fin := app.setTrayState("Downloading database", assets.IconDefault)
defer fin()
log.LogInfo(fmt.Sprintf("Downloading remote database to %s", app.dbFile))
etag, err := app.downloadDatabase()
if err != nil {
log.LogError("Failed to download remote database", err)
app.sigErrChan <- exerr.Wrap(err, "Failed to download remote database").Build()
return
}
}()
}
}
func (app *Application) runSyncLoop() error {
}

20
app/tray.go Normal file
View File

@@ -0,0 +1,20 @@
package app
import (
"fyne.io/systray"
"mikescher.com/kpsync/assets"
)
func (app *Application) initTray() {
trayOnReady := func() {
systray.SetIcon(assets.IconInit)
systray.SetTitle("KeepassXC Sync")
systray.SetTooltip("Initializing...")
app.trayReady = true
}
systray.Run(trayOnReady, nil)
}

47
app/utils.go Normal file
View File

@@ -0,0 +1,47 @@
package app
import (
"encoding/json"
"os"
"git.blackforestbytes.com/BlackForestBytes/goext/cryptext"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
)
func fileExists(p string) bool {
_, err := os.Stat(p)
if os.IsNotExist(err) {
return false
}
return true
}
type State struct {
ETag string `json:"etag"`
Size int64 `json:"size"`
Checksum string `json:"checksum"`
}
func (app *Application) readState() *State {
bin, err := os.ReadFile(app.stateFile)
if err != nil {
return nil
}
var state State
err = json.Unmarshal(bin, &state)
if err != nil {
return nil
}
return &state
}
func (app *Application) calcLocalChecksum() (string, error) {
bin, err := os.ReadFile(app.dbFile)
if err != nil {
return "", exerr.Wrap(err, "").Build()
}
return cryptext.BytesSha256(bin), nil
}

5
app/webdav.go Normal file
View File

@@ -0,0 +1,5 @@
package app
func (app *Application) initSync() {
}