From 8cf9b1f905e41251b731c91433a53fb6af02ee47 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Sun, 16 May 2021 16:23:28 +0100 Subject: [PATCH] add basic tray functionality enable with `make TRAY=on ...`. Cross compilation apparently should work from linux to linux & windows. --- Makefile | 14 ++++++++- go.mod | 1 + go.sum | 19 +++++++++++ main.go | 27 ++++++++++++---- notray.go | 7 +++++ tray.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 notray.go create mode 100644 tray.go diff --git a/Makefile b/Makefile index 67139ea..f5f9aff 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,18 @@ else TAGS := -tags external endif +TRAY ?= off +ifeq ($(INTERNAL)$(TRAY), offon) + TAGS := $(TAGS) tray +else ifeq ($(INTERNAL)$(TRAY), onon) + TAGS := -tags tray +endif + +OS := $(shell go env GOOS) +ifeq ($(TRAY)$(OS), onwindows) + LDFLAGS := $(LDFLAGS) -H=windowsgui +endif + DEBUG ?= off ifeq ($(DEBUG), on) SOURCEMAP := --sourcemap @@ -79,7 +91,7 @@ compile: $(GOBINARY) mod download $(info Building) mkdir -p build - CGO_ENABLED=0 $(GOBINARY) build -ldflags="$(LDFLAGS)" $(TAGS) -o build/jfa-go + $(GOBINARY) build -ldflags="$(LDFLAGS)" $(TAGS) -o build/jfa-go compress: upx --lzma build/jfa-go diff --git a/go.mod b/go.mod index 5be7638..b8ffdb2 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/fatih/color v1.10.0 github.com/fsnotify/fsnotify v1.4.9 + github.com/getlantern/systray v1.1.0 // indirect github.com/gin-contrib/pprof v1.3.0 github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e github.com/gin-gonic/gin v1.6.3 diff --git a/go.sum b/go.sum index 5b09672..acb961a 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,20 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/systray v1.1.0 h1:U0wCEqseLi2ok1fE6b88gJklzriavPJixZysZPkZd/Y= +github.com/getlantern/systray v1.1.0/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= @@ -93,6 +107,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -181,6 +197,8 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -289,6 +307,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index 7dffd90..e233a30 100644 --- a/main.go +++ b/main.go @@ -41,6 +41,8 @@ var ( PPROF *bool TEST bool SWAGGER *bool + QUIT = false + RUNNING = false warning = color.New(color.FgYellow).SprintfFunc() info = color.New(color.FgMagenta).SprintfFunc() hiwhite = color.New(color.FgHiWhite).SprintfFunc() @@ -147,6 +149,8 @@ func test(app *appContext) { } func start(asDaemon, firstCall bool) { + RUNNING = true + defer func() { RUNNING = false }() // app encompasses essentially all useful functions. app := new(appContext) @@ -618,13 +622,19 @@ func start(asDaemon, firstCall bool) { func (app *appContext) shutdown() { app.info.Println("Shutting down...") - - cntx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - if err := SRV.Shutdown(cntx); err != nil { - app.err.Fatalf("Server shutdown error: %s", err) + QUIT = true + RESTART <- true + for { + if RUNNING { + continue + } + cntx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + if err := SRV.Shutdown(cntx); err != nil { + app.err.Fatalf("Server shutdown error: %s", err) + } + os.Exit(1) } - os.Exit(1) } func flagPassed(name string) (found bool) { @@ -745,10 +755,15 @@ You can then run: fmt.Print(info("systemctl --user stop jfa-go\n\n")) color.New(color.FgYellow).PrintFunc()("To restart: ") fmt.Print(info("systemctl --user stop jfa-go\n")) + } else if TRAY && flagPassed("tray") { + RunTray() } else { RESTART = make(chan bool, 1) start(false, true) for { + if QUIT { + continue + } printVersion() start(false, false) } diff --git a/notray.go b/notray.go new file mode 100644 index 0000000..4e9164e --- /dev/null +++ b/notray.go @@ -0,0 +1,7 @@ +// +build !tray + +package main + +var TRAY = false + +func RunTray() {} diff --git a/tray.go b/tray.go new file mode 100644 index 0000000..e9fa7c4 --- /dev/null +++ b/tray.go @@ -0,0 +1,94 @@ +// +build tray + +package main + +import ( + "log" + "os" + "os/signal" + "syscall" + + "github.com/getlantern/systray" +) + +var TRAY = true + +func RunTray() { + systray.Run(onReady, onExit) +} + +func onExit() { + if RUNNING { + QUIT = true + RESTART <- true + } + os.Remove(SOCK) +} + +func onReady() { + icon, err := localFS.ReadFile("web/favicon.ico") + if err != nil { + log.Fatalf("Failed to load favicon: %v", err) + } + + systray.SetIcon(icon) + systray.SetTitle("jfa-go") + mStart := systray.AddMenuItem("Start", "Start jfa-go") + mStop := systray.AddMenuItem("Stop", "Stop jfa-go") + mRestart := systray.AddMenuItem("Restart", "Restart jfa-go") + mQuit := systray.AddMenuItem("Quit", "Quit jfa-go") + mOnBoot := systray.AddMenuItemCheckbox("Run on login", "Run jfa-go on user login.", false) + + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + systray.Quit() + os.Exit(1) + }() + defer func() { + systray.Quit() + }() + + RESTART = make(chan bool, 1) + go start(false, true) + mStart.Disable() + mStop.Enable() + mRestart.Enable() + for { + select { + case <-mStart.ClickedCh: + if !RUNNING { + go start(false, false) + mStart.Disable() + mStop.Enable() + mRestart.Enable() + } + case <-mStop.ClickedCh: + if RUNNING { + RESTART <- true + mStop.Disable() + mStart.Enable() + mRestart.Disable() + } + case <-mRestart.ClickedCh: + if RUNNING { + RESTART <- true + mStop.Disable() + mStart.Enable() + mRestart.Disable() + for { + if !RUNNING { + break + } + } + go start(false, false) + mStart.Disable() + mStop.Enable() + mRestart.Enable() + } + case <-mQuit.ClickedCh: + systray.Quit() + } + } +}