auto-backup, rework menu func structure
This commit is contained in:
parent
3a8e84414e
commit
941454d694
120
main.go
120
main.go
|
@ -2,42 +2,18 @@ package main
|
|||
|
||||
import (
|
||||
"brainbaking.com/restictray/restic"
|
||||
"fyne.io/systray"
|
||||
"fyne.io/systray/example/icon"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"fyne.io/systray"
|
||||
"fyne.io/systray/example/icon"
|
||||
)
|
||||
|
||||
// I'm ignoring go threading issues here; assume no clicks happen at the same time.
|
||||
var wrapper *restic.Wrapper
|
||||
|
||||
func main() {
|
||||
// init and setup logging
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
wrapper = &restic.Wrapper{}
|
||||
|
||||
// bootstrap systray (this is a blocking call, second func is onExit)
|
||||
systray.Run(onSystrayReady, func() {})
|
||||
}
|
||||
|
||||
func addMenuLatestSnapshot() {
|
||||
snapshot := wrapper.LastSnapshot()
|
||||
systray.AddMenuItem("Latest: "+snapshot.Id+" @ "+snapshot.ShortTime(), "Latest Restic snapshot")
|
||||
}
|
||||
|
||||
func addMenuNextTime(cnf *restic.Config) {
|
||||
nextTime := wrapper.LastSnapshot().Time.Add(time.Duration(cnf.BackupTimeInHours) * time.Hour)
|
||||
msg := "Next @ " + nextTime.Format(restic.ShortTimeFormat)
|
||||
if time.Now().After(nextTime) {
|
||||
msg = "⚠️ Overdue - " + msg
|
||||
}
|
||||
|
||||
systray.AddMenuItem(msg, "Future Restic snapshot")
|
||||
}
|
||||
|
||||
func addMenuQuit() {
|
||||
systray.AddSeparator()
|
||||
addMenuWithQuitAction("Quit", "Quit Restictray")
|
||||
|
@ -63,11 +39,43 @@ func addMenuWithQuitAction(title string, tooltip string) {
|
|||
}()
|
||||
}
|
||||
|
||||
func main() {
|
||||
// init and setup logging
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
wrapper = &restic.Wrapper{}
|
||||
|
||||
// bootstrap systray (this is a blocking call, second func is onExit)
|
||||
systray.Run(onSystrayReady, func() {})
|
||||
}
|
||||
|
||||
func updateSnapshots(cnf *restic.Config, mnuLatest *systray.MenuItem, mnuNext *systray.MenuItem, mnuBackupNow *systray.MenuItem) {
|
||||
err := wrapper.UpdateLatestSnapshots(cnf)
|
||||
if err != nil {
|
||||
handleError(err)
|
||||
return
|
||||
}
|
||||
|
||||
snapshot := wrapper.LastSnapshot()
|
||||
msg := strconv.Itoa(len(wrapper.LatestSnapshots)) + " snapshots. Next in " + strconv.Itoa(cnf.BackupTimeInHours) + " hour(s)"
|
||||
if isBackupNeeded(cnf) {
|
||||
msg = "⚠️ Overdue - " + msg
|
||||
}
|
||||
|
||||
mnuLatest.SetTitle("Latest: " + snapshot.Id + " @ " + snapshot.ShortTime())
|
||||
mnuNext.SetTitle(msg)
|
||||
mnuBackupNow.Enable()
|
||||
mnuBackupNow.SetTitle("Backup now")
|
||||
}
|
||||
|
||||
func isBackupNeeded(cnf *restic.Config) bool {
|
||||
nextTime := wrapper.LastSnapshot().Time.Add(time.Duration(cnf.BackupTimeInHours) * time.Hour)
|
||||
return time.Now().After(nextTime)
|
||||
}
|
||||
|
||||
// See https://github.com/fyne-io/systray/tree/master/example for more examples
|
||||
func onSystrayReady() {
|
||||
systray.SetTemplateIcon(icon.Data, icon.Data)
|
||||
systray.SetTooltip("Restictray")
|
||||
systray.AddMenuItem("... Initializing", "Initializing, please wait.")
|
||||
addMenuQuit()
|
||||
|
||||
cnf, err := restic.ReadConfig()
|
||||
if err != nil {
|
||||
|
@ -75,33 +83,41 @@ func onSystrayReady() {
|
|||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := wrapper.UpdateLatestSnapshots(cnf)
|
||||
if err != nil {
|
||||
handleError(err)
|
||||
return
|
||||
}
|
||||
|
||||
resetAndBuildMainMenu(cnf)
|
||||
}()
|
||||
}
|
||||
|
||||
// See https://github.com/fyne-io/systray/tree/master/example for more examples
|
||||
func resetAndBuildMainMenu(cnf *restic.Config) {
|
||||
systray.ResetMenu()
|
||||
addMenuLatestSnapshot()
|
||||
addMenuNextTime(cnf)
|
||||
mnuLatestSnapshot := systray.AddMenuItem("Latest: (Fetching...)", "Latest Restic snapshot")
|
||||
mnuNextSnapshot := systray.AddMenuItem("Next @ (Unknown)", "Future Restic snapshot")
|
||||
systray.AddSeparator()
|
||||
mnuBackupNow := systray.AddMenuItem("Backup now", "Backup now")
|
||||
mnuBackupNow.Disable()
|
||||
mnuBrowse := systray.AddMenuItem("Browse backups in Finder...", "Mount and browse backups")
|
||||
addMenuQuit()
|
||||
|
||||
go updateSnapshots(cnf, mnuLatestSnapshot, mnuNextSnapshot, mnuBackupNow)
|
||||
backupCheckTime := make(chan bool, 1)
|
||||
backupCheckFn := func() {
|
||||
time.Sleep(3 * time.Second)
|
||||
backupCheckTime <- true
|
||||
}
|
||||
go backupCheckFn()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-backupCheckTime:
|
||||
if !mnuBackupNow.Disabled() && isBackupNeeded(cnf) {
|
||||
go onClickedMenuBackupNow(mnuBackupNow, cnf, func() {
|
||||
updateSnapshots(cnf, mnuLatestSnapshot, mnuNextSnapshot, mnuBackupNow)
|
||||
go backupCheckFn()
|
||||
})
|
||||
} else {
|
||||
log.Debug().Msg("Backup not yet needed/in progress/impossible")
|
||||
go backupCheckFn()
|
||||
}
|
||||
case <-mnuBackupNow.ClickedCh:
|
||||
onClickedMenuBackupNow(mnuBackupNow, cnf)
|
||||
go onClickedMenuBackupNow(mnuBackupNow, cnf, func() {
|
||||
updateSnapshots(cnf, mnuLatestSnapshot, mnuNextSnapshot, mnuBackupNow)
|
||||
})
|
||||
case <-mnuBrowse.ClickedCh:
|
||||
onClickedMenuBrowse(mnuBrowse, cnf)
|
||||
// Restic allows backing up and consulting snapshots while mounted
|
||||
go onClickedMenuBrowse(mnuBrowse, cnf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,18 +129,14 @@ func onClickedMenuBrowse(browse *systray.MenuItem, cnf *restic.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
func onClickedMenuBackupNow(mnu *systray.MenuItem, cnf *restic.Config) {
|
||||
func onClickedMenuBackupNow(mnu *systray.MenuItem, cnf *restic.Config, onDone func()) {
|
||||
log.Debug().Msg("Backup triggered")
|
||||
mnu.SetTitle("🔄 Backup in progress...")
|
||||
mnu.Disable()
|
||||
// TODO after a backup, reinitialize latest snapshot + latest/next menus
|
||||
// TODO not by calling resetAndBuild again: this is from the for{}?
|
||||
// TODO how does this interop with a future goroutine that auto-backups?
|
||||
// TODO need for separate "backupInProgress" bool?
|
||||
err := wrapper.Backup(cnf)
|
||||
mnu.SetTitle("Backup now")
|
||||
mnu.Enable()
|
||||
|
||||
if err != nil {
|
||||
handleError(err)
|
||||
}
|
||||
onDone()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue