package config import ( "encoding/json" "io/ioutil" "local/storage" "os" "sync" "time" ) type Config struct { Interval struct { Input Duration OK Duration Error Duration JobInfo Duration } Images struct { ClientID string ClientSecret string RefreshToken string AccessToken string RefreshURI string RefreshFormat string RefreshMethod string UploadURI string UploadMethod string } Maps struct { URIFormat string Pickup bool Dropoff bool Pathed struct { Enabled bool DirectionsURIFormat string PathedURIFormat string Zoom struct { AcceptableLatLngDelta float32 Override int } } } Clients map[string]Client Storage []string Message struct { Matrix struct { ReceiveEnabled bool Mock bool Homeserver string Username string Token string Device string Room string } } Once bool Brokers struct { NTG struct { JobInfo bool Mock bool LoadPageURIFormat string Username string Password string } } lock sync.Mutex db storage.DB } type Client struct { States []State IDs struct { Matrix string } Available Time } var live Config func configPath() string { p, ok := os.LookupEnv("CONFIG") if !ok { p = "./config.json" } return p } func Clients(t time.Time) map[string]Client { clients := Get().Clients result := map[string]Client{} for k := range clients { if clients[k].Available.Get().IsZero() || t.After(clients[k].Available.Get()) { result[k] = clients[k] } } return result } func AllStates() []State { statem := map[State]struct{}{} for _, v := range Clients(time.Now().Add(time.Hour * 24 * 365)) { for _, state := range v.States { statem[state] = struct{}{} } } states := make([]State, 0, len(statem)+1) for k := range statem { states = append(states, k) } return states } func Refresh() error { b, err := ioutil.ReadFile(configPath()) if err != nil { return err } var c Config if err := json.Unmarshal(b, &c); err != nil { return err } if live.db != nil { live.db.Close() } live = c return nil } func Get() *Config { return &live } func Set(other Config) { b, err := json.MarshalIndent(other, "", " ") if err != nil { return } ioutil.WriteFile(configPath(), b, os.ModePerm) Refresh() } func (c *Config) DB() storage.DB { if c.db == nil { c.lock.Lock() defer c.lock.Unlock() if c.db == nil { if len(c.Storage) == 0 { c.Storage = []string{storage.MAP.String()} } db, err := storage.New(storage.TypeFromString(c.Storage[0]), c.Storage[1:]...) if err != nil { panic(err) } c.db = db } } return c.db }