Passed
Push — master ( efbd13...e46f8b )
by Stanislav
01:09
created

main.Notify   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
nop 1
1
package main
2
3
import (
4
	"fmt"
5
	"io"
6
	"log"
7
	"os"
8
9
	"flag"
10
	"github.com/getlantern/systray"
11
	"github.com/popstas/go-toggl"
12
	"github.com/viasite/beeep"
13
	"github.com/viasite/planfix-toggl-server/app/client"
14
	"github.com/viasite/planfix-toggl-server/app/config"
15
	"github.com/viasite/planfix-toggl-server/app/icon"
16
	"github.com/viasite/planfix-toggl-server/app/rest"
17
	"github.com/viasite/planfix-toggl-server/app/util"
18
	"runtime"
19
)
20
21
var version string
22
var trayMenu map[string] *systray.MenuItem
23
24
func getLogger(cfg config.Config) *log.Logger {
25
	// logging
26
	logger := log.New(os.Stderr, "[planfix-toggl] ", log.LstdFlags)
27
	if cfg.Debug {
28
		logger.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
29
	} else {
30
		toggl.DisableLog()
31
	}
32
	if cfg.LogFile != "" {
33
		f, err := os.OpenFile(cfg.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
34
		if err != nil {
35
			logger.Fatalf("[ERROR] Failed to open log file: %s", cfg.LogFile)
36
		}
37
		defer f.Close()
38
		mw := io.MultiWriter(os.Stdout, f)
39
		logger.SetOutput(mw)
40
	}
41
	return logger
42
}
43
44
func parseFlags(cfg *config.Config) {
45
	dryRun := flag.Bool("dry-run", false, "Don't actually change data")
46
	if runtime.GOOS == "windows" {
47
		// Allow user to hide the console window
48
		flag.BoolVar(&cfg.NoConsole, "no-console", false, "Hide console window")
49
	}
50
	flag.Parse()
51
52
	if *dryRun {
53
		cfg.DryRun = true
54
	}
55
}
56
57
func Notify(msg string) error {
0 ignored issues
show
introduced by
exported function Notify should have comment or be unexported
Loading history...
58
	err := beeep.Notify("", msg, "assets/icon.png")
59
	return err
60
}
61
62
func connectServices(cfg *config.Config, logger *log.Logger, togglClient *client.TogglClient) (err error) {
63
	// toggl
64
	logger.Println("[INFO] подключение к Toggl...")
65
	account, err := togglClient.GetTogglUser()
66
	cfg.TogglUserID = account.Data.ID
67
	if err != nil {
68
		return err
69
	}
70
71
	ok, err := togglClient.IsWorkspaceExists(cfg.TogglWorkspaceID)
72
	if err != nil {
73
		return err
74
	}
75
	if !ok {
76
		return fmt.Errorf("Toggl workspace ID %d не найден", cfg.TogglWorkspaceID)
77
	}
78
79
	// planfix
80
	if cfg.PlanfixUserName != "" && cfg.PlanfixUserPassword != "" {
81
		logger.Println("[INFO] подключение к Планфиксу...")
82
		user, err := togglClient.GetPlanfixUser()
83
		cfg.PlanfixUserID = user.ID
84
		if err != nil {
85
			return err
86
		}
87
88
		logger.Println("[INFO] получение данных аналитики Планфикса...")
89
		_, err = togglClient.GetAnaliticDataCached(
90
			cfg.PlanfixAnaliticName,
91
			cfg.PlanfixAnaliticTypeName,
92
			cfg.PlanfixAnaliticTypeValue,
93
			cfg.PlanfixAnaliticCountName,
94
			cfg.PlanfixAnaliticCommentName,
95
			cfg.PlanfixAnaliticDateName,
96
			cfg.PlanfixAnaliticUsersName,
97
		)
98
		if err != nil {
99
			return fmt.Errorf("Поля аналитики указаны неправильно: %s", err.Error())
100
		}
101
	}
102
	return nil
103
}
104
105
func initApp() {
106
	fmt.Printf("planfix-toggl %s\n", version)
107
	cfg := config.GetConfig()
108
109
	parseFlags(&cfg)
110
111
	logger := getLogger(cfg)
112
113
	errors, isValid := cfg.Validate()
114
	if !isValid {
115
		for _, e := range errors {
116
			log.Println(e)
117
		}
118
	}
119
120
	if cfg.NoConsole {
121
		util.HideConsole()
122
	}
123
124
	togglClient := client.TogglClient{
125
		Config: &cfg,
126
		Logger: logger,
127
	}
128
	togglClient.ReloadConfig()
129
130
	// get planfix and toggl user IDs, for early API check
131
	err := connectServices(&cfg, logger, &togglClient)
132
	if err != nil {
133
		isValid = false
134
		logger.Printf("[ERROR] %s", err.Error())
135
		Notify(err.Error())
136
	}
137
138
	if isValid {
139
		togglClient.Run()
140
	} else {
141
		util.OpenBrowser(fmt.Sprintf("https://localhost:%d", cfg.PortSSL))
142
	}
143
144
	go func() {
145
		// tray menu actions
146
		for {
147
			select {
148
			case <-trayMenu["web"].ClickedCh:
149
				cfg := config.GetConfig()
150
				util.OpenBrowser(fmt.Sprintf("https://localhost:%d", cfg.PortSSL))
151
152
			case <-trayMenu["send"].ClickedCh:
153
				err := togglClient.SendToPlanfix()
154
				if err != nil {
155
					logger.Println(err)
156
				}
157
158
			case <-trayMenu["quit"].ClickedCh:
159
				onExit()
160
			}
161
		}
162
	}()
163
164
	// start API server
165
	server := rest.Server{
166
		Version:     version,
167
		TogglClient: &togglClient,
168
		Config:      &cfg,
169
		Logger:      logger,
170
	}
171
	server.Run(cfg.PortSSL)
172
}
173
174
func onReady() {
175
	go initApp()
176
177
	// systray.EnableAppWindow("Lantern", 1024, 768) // in next systray versions
178
	systray.SetIcon(icon.Data)
179
	systray.SetTitle("planfix-toggl")
180
	systray.SetTooltip("tooltip")
181
182
	trayMenu = make(map[string]*systray.MenuItem)
183
	trayMenu["web"] = systray.AddMenuItem("Open web interface", "")
184
	trayMenu["send"] = systray.AddMenuItem("Sync", "")
185
	trayMenu["quit"] = systray.AddMenuItem("Quit", "Quit the whole app")
186
}
187
188
func onExit() {
189
	systray.Quit()
190
	//os.Exit(0)
191
}
192
193
func main() {
194
	systray.Run(onReady, onExit)
195
}
196