mirror of https://github.com/qwc/backive.git
Reworking UI concept...
This commit is contained in:
parent
f62c670955
commit
cfc37e575f
|
@ -40,6 +40,7 @@ backups:
|
|||
settings:
|
||||
systemMountPoint: /mnt/backups
|
||||
unixSocketLocation: /var/local/backive/backive.sock
|
||||
uiUnixSocketLocation: /var/local/backive/ui.sock
|
||||
logLocation: /var/log/backive
|
||||
dbLocation: /var/lib/backive
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ var (
|
|||
config backive.Configuration
|
||||
database backive.Database
|
||||
events backive.EventHandler
|
||||
uihdl backive.UIHandler
|
||||
)
|
||||
|
||||
func defaultCallback(envMap map[string]string) {
|
||||
|
@ -127,17 +128,22 @@ func main() {
|
|||
if err != nil {
|
||||
log.Printf("Removal of %s failed.", config.Settings.UnixSocketLocation)
|
||||
}
|
||||
err = os.Remove(config.Settings.UIUnixSocketLocation)
|
||||
if err != nil {
|
||||
log.Printf("Removal of %s failed.", config.Settings.UIUnixSocketLocation)
|
||||
}
|
||||
os.Exit(code)
|
||||
}()
|
||||
|
||||
// TODO: do proper signal handling!
|
||||
log.Println("backive starting up...")
|
||||
// find and load config
|
||||
database.Load()
|
||||
config.Load()
|
||||
setupLogging()
|
||||
backive.Init(config, database)
|
||||
|
||||
uihdl.Init(config.Settings.UIUnixSocketLocation)
|
||||
// Start UIHandler to be able to inform users through notifications
|
||||
go uihdl.Listen()
|
||||
// init scheduler and check for next needed runs?
|
||||
// start event loop
|
||||
events.Init(config.Settings.UnixSocketLocation)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2/app"
|
||||
|
||||
"github.com/qwc/backive"
|
||||
|
@ -20,7 +22,10 @@ func main() {
|
|||
app := app.NewWithID("Backive UI")
|
||||
backiveui.Init(app, nil, config, database)
|
||||
go func() {
|
||||
for {
|
||||
backiveui.NotificationRun()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
app.Run()
|
||||
|
|
|
@ -21,6 +21,7 @@ type Settings struct {
|
|||
SystemMountPoint string `mapstructure:"systemMountPoint"`
|
||||
UserMountPoint string `mapstructure:"userMountPoint"`
|
||||
UnixSocketLocation string `mapstructure:"unixSocketLocation"`
|
||||
UIUnixSocketLocation string `mapstructure:"uiUnixSocketLocation"`
|
||||
LogLocation string `mapstructure:"logLocation"`
|
||||
DbLocation string `mapstructure:"dbLocation"`
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
|
@ -16,16 +18,52 @@ var (
|
|||
config backive.Configuration
|
||||
db backive.Database
|
||||
doNotShowUntil time.Time = time.Unix(0, 0)
|
||||
c net.Conn
|
||||
)
|
||||
|
||||
func Init(a fyne.App, w fyne.Window, c backive.Configuration, d backive.Database) {
|
||||
func Init(a fyne.App, w fyne.Window, conf backive.Configuration, d backive.Database) {
|
||||
app = a
|
||||
a.SetIcon(theme.FyneLogo())
|
||||
makeTray(app)
|
||||
config = c
|
||||
config = conf
|
||||
db = d
|
||||
go PollConnection()
|
||||
}
|
||||
|
||||
func PollConnection() {
|
||||
var err error
|
||||
for {
|
||||
if c == nil {
|
||||
c, err = net.Dial("unix", config.Settings.UIUnixSocketLocation)
|
||||
} else {
|
||||
err = fmt.Errorf("Connection already established")
|
||||
}
|
||||
if err != nil {
|
||||
// ignore
|
||||
err = nil
|
||||
// sleep a while and then retry
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NotificationRun() {
|
||||
if c != nil {
|
||||
b := make([]byte, 2048)
|
||||
i, err := c.Read(b)
|
||||
if err == nil && i > 0 {
|
||||
var data map[string]string
|
||||
err = json.Unmarshal(b, &data)
|
||||
if err == nil {
|
||||
ShowNotification(data)
|
||||
}
|
||||
// else ignore and try to read again
|
||||
err = nil
|
||||
}
|
||||
// we just try again and discard the error
|
||||
err = nil
|
||||
}
|
||||
/*
|
||||
if doNotShowUntil == time.Unix(0, 0) || time.Now().After(doNotShowUntil) {
|
||||
ShowNotification()
|
||||
if doNotShowUntil != time.Unix(0, 0) {
|
||||
|
@ -34,40 +72,22 @@ func NotificationRun() {
|
|||
}
|
||||
h, _ := time.ParseDuration("15m")
|
||||
time.Sleep(h)
|
||||
//*/
|
||||
}
|
||||
|
||||
func ShowNotification() {
|
||||
displayStr, err := MakeNotificationString()
|
||||
if err == nil {
|
||||
func ShowNotification(data map[string]string) {
|
||||
if ShallShow(data) {
|
||||
app.SendNotification(
|
||||
fyne.NewNotification(
|
||||
"Backups are overdue...",
|
||||
fmt.Sprintf("Name\t(device)\t[overdue]\n%s", displayStr),
|
||||
data["header"],
|
||||
data["message"],
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func MakeNotificationString() (string, error) {
|
||||
db.Load()
|
||||
var displayStr string = ""
|
||||
var runs backive.Runs
|
||||
runs.Load(db)
|
||||
fmt.Printf("Notification run\n")
|
||||
for _, v := range config.Backups {
|
||||
fmt.Printf("Notification run %s\n", v.Name)
|
||||
if v.ShouldRun() && v.Frequency > 0 {
|
||||
fmt.Printf("Notification for %s\n", v.Name)
|
||||
lastBackup, err := runs.LastRun(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
freq, _ := time.ParseDuration(fmt.Sprintf("%dd", v.Frequency))
|
||||
days := time.Now().Sub(lastBackup.Add(freq))
|
||||
displayStr += fmt.Sprintf("%s\t(%s)\t[%f days]\n", v.Name, v.TargetDevice, days.Hours()/24)
|
||||
}
|
||||
}
|
||||
return displayStr, nil
|
||||
func ShallShow(data map[string]string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func makeTray(app fyne.App) {
|
||||
|
@ -75,7 +95,6 @@ func makeTray(app fyne.App) {
|
|||
menu := fyne.NewMenu(
|
||||
"backive",
|
||||
fyne.NewMenuItem("Show notifications again", func() {
|
||||
ShowNotification()
|
||||
}),
|
||||
fyne.NewMenuItem("Hide notifications for today", func() {
|
||||
doNotShowUntil = time.Now().AddDate(0, 0, 1)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package backive
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"path"
|
||||
)
|
||||
|
||||
type UIHandler struct {
|
||||
ls net.Listener
|
||||
client net.Conn
|
||||
}
|
||||
|
||||
var mockUIAccept = func(uh *UIHandler) (net.Conn, error) {
|
||||
log.Println("Calling eh.ls.Accept()")
|
||||
return uh.ls.Accept()
|
||||
}
|
||||
|
||||
func (uh *UIHandler) Init(socketPath string) error {
|
||||
log.Println("Initializing UIHandler")
|
||||
var err error
|
||||
dir, _ := path.Split(socketPath)
|
||||
CreateDirectoryIfNotExists(dir)
|
||||
uh.ls, err = net.Listen("unix", socketPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uh *UIHandler) Listen() {
|
||||
log.Println("Running UIHandler loop")
|
||||
func() {
|
||||
for {
|
||||
var err error
|
||||
uh.client, err = uh.ls.Accept()
|
||||
if err != nil {
|
||||
log.Printf("Accept failed %e\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (uh *UIHandler) DisplayMessage(header string, message string, level int) error {
|
||||
if uh.client != nil {
|
||||
var data map[string]interface{}
|
||||
data["level"] = level
|
||||
data["header"] = header
|
||||
data["message"] = message
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
log.Printf("Problem in sending message to UI: %e", err)
|
||||
return err
|
||||
}
|
||||
uh.client.Write(b)
|
||||
return nil
|
||||
} else {
|
||||
log.Println("No UI client available, msg did not get delivered.")
|
||||
return fmt.Errorf("No UI client available, msg not delivered.")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue