Passed
Push — master ( 4e812f...3ec1a1 )
by Stanislav
01:33
created

main.initApp   C

Complexity

Conditions 11

Size

Total Lines 64
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 40
dl 0
loc 64
rs 5.4
c 0
b 0
f 0
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like main.initApp often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package main
2
3
import (
4
	"fmt"
5
	"io"
6
	"log"
7
	"os"
8
9
	"flag"
10
	//"github.com/gen2brain/beeep"
11
	"github.com/getlantern/systray"
12
	"github.com/popstas/go-toggl"
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 connectServices(cfg *config.Config, logger *log.Logger, togglClient *client.TogglClient) (err error) {
58
	// toggl
59
	logger.Println("[INFO] подключение к Toggl...")
60
	account, err := togglClient.GetTogglUser()
61
	cfg.TogglUserID = account.Data.ID
62
	if err != nil {
63
		return err
64
	}
65
66
	ok, err := togglClient.IsWorkspaceExists(cfg.TogglWorkspaceID)
67
	if err != nil {
68
		return err
69
	}
70
	if !ok {
71
		return fmt.Errorf("Toggl workspace ID %d не найден", cfg.TogglWorkspaceID)
72
	}
73
74
	// planfix
75
	if cfg.PlanfixUserName != "" && cfg.PlanfixUserPassword != "" {
76
		logger.Println("[INFO] подключение к Планфиксу...")
77
		user, err := togglClient.GetPlanfixUser()
78
		cfg.PlanfixUserID = user.ID
79
		if err != nil {
80
			return err
81
		}
82
83
		logger.Println("[INFO] получение данных аналитики Планфикса...")
84
		_, err = togglClient.GetAnaliticDataCached(
85
			cfg.PlanfixAnaliticName,
86
			cfg.PlanfixAnaliticTypeName,
87
			cfg.PlanfixAnaliticTypeValue,
88
			cfg.PlanfixAnaliticCountName,
89
			cfg.PlanfixAnaliticCommentName,
90
			cfg.PlanfixAnaliticDateName,
91
			cfg.PlanfixAnaliticUsersName,
92
		)
93
		if err != nil {
94
			return fmt.Errorf("Поля аналитики указаны неправильно: %s", err.Error())
95
		}
96
	}
97
	return nil
98
}
99
100
func initApp() {
101
	fmt.Printf("planfix-toggl %s\n", version)
102
	cfg := config.GetConfig()
103
104
	parseFlags(&cfg)
105
106
	logger := getLogger(cfg)
107
108
	errors, isValid := cfg.Validate()
109
	if !isValid {
110
		for _, e := range errors {
111
			log.Println(e)
112
		}
113
	}
114
115
	if cfg.NoConsole {
116
		util.HideConsole()
117
	}
118
119
	togglClient := client.TogglClient{
120
		Config: &cfg,
121
		Logger: logger,
122
	}
123
	togglClient.ReloadConfig()
124
125
	// get planfix and toggl user IDs, for early API check
126
	err := connectServices(&cfg, logger, &togglClient)
127
	if err != nil {
128
		isValid = false
129
		logger.Printf("[ERROR] %s", err.Error())
130
	}
131
132
	if isValid {
133
		togglClient.Run()
134
	} else {
135
		util.OpenBrowser(fmt.Sprintf("https://localhost:%d", cfg.PortSSL))
136
	}
137
138
	// tray menu actions
139
	for {
140
		select {
141
		case <-trayMenu["web"].ClickedCh:
142
			cfg := config.GetConfig()
143
			util.OpenBrowser(fmt.Sprintf("https://localhost:%d", cfg.PortSSL))
144
145
		case <-trayMenu["send"].ClickedCh:
146
			err := togglClient.SendToPlanfix()
147
			if err != nil {
148
				logger.Println(err)
149
			}
150
151
		case <-trayMenu["quit"].ClickedCh:
152
			onExit()
153
		}
154
	}
155
156
	// start API server
157
	server := rest.Server{
0 ignored issues
show
introduced by
unreachable code
Loading history...
158
		Version:     version,
159
		TogglClient: &togglClient,
160
		Config:      &cfg,
161
		Logger:      logger,
162
	}
163
	server.Run(cfg.PortSSL)
164
}
165
166
func onReady() {
167
	go initApp()
168
169
	systray.SetIcon(icon.Data)
170
	systray.SetTitle("planfix-toggl")
171
	systray.SetTooltip("tooltip")
172
173
	trayMenu = make(map[string]*systray.MenuItem)
174
	trayMenu["web"] = systray.AddMenuItem("Open web interface", "")
175
	trayMenu["send"] = systray.AddMenuItem("Sync", "")
176
	trayMenu["quit"] = systray.AddMenuItem("Quit", "Quit the whole app")
177
}
178
179
func onExit() {
180
	systray.Quit()
181
	//os.Exit(0)
182
}
183
184
func main() {
185
	systray.Run(onReady, onExit)
186
}
187