1 | package main
|
2 |
|
3 | import (
|
4 | "encoding/json"
|
5 | "io/ioutil"
|
6 | "os"
|
7 | "path"
|
8 |
|
9 | "github.com/fatih/color"
|
10 | )
|
11 |
|
12 | const (
|
13 | defaultDateTimeFmt = "2006-01-02 15:04"
|
14 | )
|
15 |
|
16 | // Config represents user preferences
|
17 | type Config struct {
|
18 | Colors *ColorMap `json:"colors"`
|
19 | DateTimeFmt string `json:"dateTimeFmt"`
|
20 | BasePath string `json:"basePath"`
|
21 | DBPath string `json:"dbPath"`
|
22 | SocketPath string `json:"socketPath"`
|
23 | IconPath string `json:"iconPath"`
|
24 | }
|
25 |
|
26 | type ColorMap struct {
|
27 | colors map[string]*color.Color
|
28 | tags map[string]string
|
29 | }
|
30 |
|
31 | func (c *ColorMap) Get(name string) *color.Color {
|
32 | if color, ok := c.colors[name]; ok {
|
33 | return color
|
34 | }
|
35 | return nil
|
36 | }
|
37 |
|
38 | func (c *ColorMap) MarshalJSON() ([]byte, error) {
|
39 | return json.Marshal(c.tags)
|
40 | }
|
41 |
|
42 | func (c *ColorMap) UnmarshalJSON(raw []byte) error {
|
43 | lookup := map[string]*color.Color{
|
44 | "black": color.New(color.FgBlack),
|
45 | "hiblack": color.New(color.FgHiBlack),
|
46 | "blue": color.New(color.FgBlue),
|
47 | "hiblue": color.New(color.FgHiBlue),
|
48 | "cyan": color.New(color.FgCyan),
|
49 | "hicyan": color.New(color.FgHiCyan),
|
50 | "green": color.New(color.FgGreen),
|
51 | "higreen": color.New(color.FgHiGreen),
|
52 | "magenta": color.New(color.FgMagenta),
|
53 | "himagenta": color.New(color.FgHiMagenta),
|
54 | "red": color.New(color.FgRed),
|
55 | "hired": color.New(color.FgHiRed),
|
56 | "white": color.New(color.FgWhite),
|
57 | "hiwrite": color.New(color.FgHiWhite),
|
58 | "yellow": color.New(color.FgYellow),
|
59 | "hiyellow": color.New(color.FgHiYellow),
|
60 | }
|
61 | cm := &ColorMap{
|
62 | colors: map[string]*color.Color{},
|
63 | tags: map[string]string{},
|
64 | }
|
65 | err := json.Unmarshal(raw, &cm.tags)
|
66 | if err != nil {
|
67 | return err
|
68 | }
|
69 | for tag, colorName := range cm.tags {
|
70 | if color, ok := lookup[colorName]; ok {
|
71 | cm.colors[tag] = color
|
72 | }
|
73 | }
|
74 | *c = *cm
|
75 | return nil
|
76 | }
|
77 |
|
78 | func LoadConfig(configPath string, config *Config) error {
|
79 | raw, err := ioutil.ReadFile(configPath)
|
80 | if err != nil {
|
81 | os.MkdirAll(path.Dir(configPath), 0755)
|
82 | // Create an empty config file
|
83 | // if it does not already exist.
|
84 | if os.IsNotExist(err) {
|
85 | raw, _ := json.Marshal(map[string]string{})
|
86 | err := ioutil.WriteFile(configPath, raw, 0644)
|
87 | if err != nil {
|
88 | return err
|
89 | }
|
90 | return LoadConfig(configPath, config)
|
91 | }
|
92 | return err
|
93 | }
|
94 | err = json.Unmarshal(raw, config)
|
95 | if err != nil {
|
96 | return err
|
97 | }
|
98 | if config.DateTimeFmt == "" {
|
99 | config.DateTimeFmt = defaultDateTimeFmt
|
100 | }
|
101 | if config.BasePath == "" {
|
102 | config.BasePath = path.Dir(configPath)
|
103 | }
|
104 | if config.DBPath == "" {
|
105 | config.DBPath = path.Join(config.BasePath, "/pomo.db")
|
106 | }
|
107 | if config.SocketPath == "" {
|
108 | config.SocketPath = path.Join(config.BasePath, "/pomo.sock")
|
109 | }
|
110 | if config.IconPath == "" {
|
111 | config.IconPath = path.Join(config.BasePath, "/icon.png")
|
112 | }
|
113 | return nil
|
114 | }
|