truckstop/config/config.go

203 lines
3.6 KiB
Go

package config
import (
"encoding/json"
"io/ioutil"
"local/storage"
"local/truckstop/logtr"
"os"
"sync"
"time"
)
type Matrix struct {
ReceiveEnabled bool
Mock bool
Homeserver string
Username string
Token string
Device string
Room string
}
type Config struct {
Log struct {
Path string
Level logtr.Level
SOSMatrix Matrix
}
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 Matrix
}
Once bool
Brokers struct {
UseZips bool
RadiusMiles int
NTG struct {
Working struct {
Hours []int
Weekdays []int
}
Enabled bool
JobInfo bool
Mock bool
LoadPageURIFormat string
LoadPageAPIURIFormat string
Username string
Password string
}
FastExact struct {
Enabled bool
Mock bool
Username string
Password string
}
}
lock sync.Mutex
db storage.DB
}
type Client struct {
States []State
Zips []string
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 AllZips() []string {
zipm := map[string]struct{}{}
for _, v := range Clients(time.Now().Add(time.Hour * 24 * 365)) {
for _, state := range v.Zips {
zipm[state] = struct{}{}
}
}
zips := make([]string, 0, len(zipm)+1)
for k := range zipm {
zips = append(zips, k)
}
return zips
}
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(soser func() logtr.SOSer) error {
b, err := ioutil.ReadFile(configPath())
if err != nil {
return err
}
var c Config
if err := json.Unmarshal(b, &c); err != nil {
return err
}
logtr.SetLogpath(c.Log.Path)
logtr.SetLevel(c.Log.Level)
if live.db != nil {
live.db.Close()
}
live = c
if soser != nil {
logtr.SetSOSer(soser())
}
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(nil)
}
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
}