This repository has been archived by the owner on Sep 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tray.go
108 lines (89 loc) · 2.36 KB
/
tray.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// © 2021 Ilya Mateyko. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE.md file.
//go:build windows
package main
import (
_ "embed"
"encoding/xml"
"errors"
"os"
"os/exec"
"path/filepath"
"github.com/getlantern/systray"
"tawesoft.co.uk/go/dialog"
)
//go:embed logo.ico
var icon []byte
func main() { systray.Run(onReady, func() {}) }
func onReady() {
systray.SetIcon(icon)
systray.SetTitle("Syncthing")
info := systray.AddMenuItem("Loading...", "")
info.Disable()
systray.AddSeparator()
gui := systray.AddMenuItem("Open web interface", "")
systray.AddSeparator()
var (
restart = systray.AddMenuItem("Restart", "")
shutdown = systray.AddMenuItem("Shutdown", "")
)
systray.AddSeparator()
quit := systray.AddMenuItem("Quit", "")
url, key, err := loadConfig()
if err != nil {
dialog.Alert("Unable to fetch URL and API key from config: %v", err)
}
c := newClient(url, key)
version, err := c.version()
if err != nil {
dialog.Alert("Unable to fetch Syncthing version: %v", err)
} else {
info.SetTitle(version)
}
go func() {
for {
select {
case <-gui.ClickedCh:
if err := exec.Command("rundll32", "url.dll,FileProtocolHandler", c.url).Start(); err != nil {
dialog.Alert("Unable to open web interface: %v", err)
}
case <-restart.ClickedCh:
if err := c.restart(); err != nil {
dialog.Alert("Unable to restart Syncthing: %v", err)
}
case <-shutdown.ClickedCh:
if err := c.shutdown(); err != nil {
dialog.Alert("Unable to shutdown Syncthing: %v", err)
}
case <-quit.ClickedCh:
systray.Quit()
}
}
}()
}
// loadConfig fetches URL and key that is used to contact Syncthing by
// parsing it's config.
func loadConfig() (url, key string, err error) {
// TODO(astrophena): Support non-default config paths.
dir := os.Getenv("LocalAppData")
if dir == "" {
return "", "", errors.New("%LocalAppData% is not defined")
}
type config struct {
XMLName xml.Name `xml:"configuration"`
GUI struct {
Address string `xml:"address"`
APIKey string `xml:"apikey"`
} `xml:"gui"`
}
b, err := os.ReadFile(filepath.Join(dir, "Syncthing", "config.xml"))
if err != nil {
return "", "", err
}
cfg := &config{}
if err := xml.Unmarshal(b, cfg); err != nil {
return "", "", err
}
return "http://" + cfg.GUI.Address, cfg.GUI.APIKey, nil
}