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:
|
settings:
|
||||||
systemMountPoint: /mnt/backups
|
systemMountPoint: /mnt/backups
|
||||||
unixSocketLocation: /var/local/backive/backive.sock
|
unixSocketLocation: /var/local/backive/backive.sock
|
||||||
|
uiUnixSocketLocation: /var/local/backive/ui.sock
|
||||||
logLocation: /var/log/backive
|
logLocation: /var/log/backive
|
||||||
dbLocation: /var/lib/backive
|
dbLocation: /var/lib/backive
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ var (
|
||||||
config backive.Configuration
|
config backive.Configuration
|
||||||
database backive.Database
|
database backive.Database
|
||||||
events backive.EventHandler
|
events backive.EventHandler
|
||||||
|
uihdl backive.UIHandler
|
||||||
)
|
)
|
||||||
|
|
||||||
func defaultCallback(envMap map[string]string) {
|
func defaultCallback(envMap map[string]string) {
|
||||||
|
@ -127,17 +128,22 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Removal of %s failed.", config.Settings.UnixSocketLocation)
|
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)
|
os.Exit(code)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO: do proper signal handling!
|
|
||||||
log.Println("backive starting up...")
|
log.Println("backive starting up...")
|
||||||
// find and load config
|
// find and load config
|
||||||
database.Load()
|
database.Load()
|
||||||
config.Load()
|
config.Load()
|
||||||
setupLogging()
|
setupLogging()
|
||||||
backive.Init(config, database)
|
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?
|
// init scheduler and check for next needed runs?
|
||||||
// start event loop
|
// start event loop
|
||||||
events.Init(config.Settings.UnixSocketLocation)
|
events.Init(config.Settings.UnixSocketLocation)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"fyne.io/fyne/v2/app"
|
"fyne.io/fyne/v2/app"
|
||||||
|
|
||||||
"github.com/qwc/backive"
|
"github.com/qwc/backive"
|
||||||
|
@ -20,7 +22,10 @@ func main() {
|
||||||
app := app.NewWithID("Backive UI")
|
app := app.NewWithID("Backive UI")
|
||||||
backiveui.Init(app, nil, config, database)
|
backiveui.Init(app, nil, config, database)
|
||||||
go func() {
|
go func() {
|
||||||
|
for {
|
||||||
backiveui.NotificationRun()
|
backiveui.NotificationRun()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
app.Run()
|
app.Run()
|
||||||
|
|
|
@ -21,6 +21,7 @@ type Settings struct {
|
||||||
SystemMountPoint string `mapstructure:"systemMountPoint"`
|
SystemMountPoint string `mapstructure:"systemMountPoint"`
|
||||||
UserMountPoint string `mapstructure:"userMountPoint"`
|
UserMountPoint string `mapstructure:"userMountPoint"`
|
||||||
UnixSocketLocation string `mapstructure:"unixSocketLocation"`
|
UnixSocketLocation string `mapstructure:"unixSocketLocation"`
|
||||||
|
UIUnixSocketLocation string `mapstructure:"uiUnixSocketLocation"`
|
||||||
LogLocation string `mapstructure:"logLocation"`
|
LogLocation string `mapstructure:"logLocation"`
|
||||||
DbLocation string `mapstructure:"dbLocation"`
|
DbLocation string `mapstructure:"dbLocation"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
|
@ -16,16 +18,52 @@ var (
|
||||||
config backive.Configuration
|
config backive.Configuration
|
||||||
db backive.Database
|
db backive.Database
|
||||||
doNotShowUntil time.Time = time.Unix(0, 0)
|
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
|
app = a
|
||||||
a.SetIcon(theme.FyneLogo())
|
a.SetIcon(theme.FyneLogo())
|
||||||
makeTray(app)
|
makeTray(app)
|
||||||
config = c
|
config = conf
|
||||||
db = d
|
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() {
|
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) {
|
if doNotShowUntil == time.Unix(0, 0) || time.Now().After(doNotShowUntil) {
|
||||||
ShowNotification()
|
ShowNotification()
|
||||||
if doNotShowUntil != time.Unix(0, 0) {
|
if doNotShowUntil != time.Unix(0, 0) {
|
||||||
|
@ -34,40 +72,22 @@ func NotificationRun() {
|
||||||
}
|
}
|
||||||
h, _ := time.ParseDuration("15m")
|
h, _ := time.ParseDuration("15m")
|
||||||
time.Sleep(h)
|
time.Sleep(h)
|
||||||
|
//*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowNotification() {
|
func ShowNotification(data map[string]string) {
|
||||||
displayStr, err := MakeNotificationString()
|
if ShallShow(data) {
|
||||||
if err == nil {
|
|
||||||
app.SendNotification(
|
app.SendNotification(
|
||||||
fyne.NewNotification(
|
fyne.NewNotification(
|
||||||
"Backups are overdue...",
|
data["header"],
|
||||||
fmt.Sprintf("Name\t(device)\t[overdue]\n%s", displayStr),
|
data["message"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeNotificationString() (string, error) {
|
func ShallShow(data map[string]string) bool {
|
||||||
db.Load()
|
return true
|
||||||
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 makeTray(app fyne.App) {
|
func makeTray(app fyne.App) {
|
||||||
|
@ -75,7 +95,6 @@ func makeTray(app fyne.App) {
|
||||||
menu := fyne.NewMenu(
|
menu := fyne.NewMenu(
|
||||||
"backive",
|
"backive",
|
||||||
fyne.NewMenuItem("Show notifications again", func() {
|
fyne.NewMenuItem("Show notifications again", func() {
|
||||||
ShowNotification()
|
|
||||||
}),
|
}),
|
||||||
fyne.NewMenuItem("Hide notifications for today", func() {
|
fyne.NewMenuItem("Hide notifications for today", func() {
|
||||||
doNotShowUntil = time.Now().AddDate(0, 0, 1)
|
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