package mux // General configuration utilities for Glenda import ( "encoding/json" "os" "fmt" "strings" "errors" "strconv" "time" "github.com/SlyMarbo/rss" "github.com/bwmarrin/discordgo" ) // Global variables are bad var Config Configuration var Session *discordgo.Session // Stores subscription information for channels related to RSS feeds type Subscription struct { ChanID string SubID int } // Stores a Feed and a list of the last n commits; n=3 type Feed struct { Feed rss.Feed Recent []string } type Feeder struct { Feeds []Feed Subs []Subscription } // Stores config for current state type Configuration struct { Db map[string]string Feeder Reminders []Reminder } // Initializes current config (called once at start) ­ just .Read()? func (c *Configuration) Init(s *discordgo.Session) { c.Db = map[string]string { "owner": "188698402727526400", // Henesy "name": "glenda.cfg", // Config file name "dir": "./cfg", // Config dir "delay": "20", // Minutes "mansite": "http://man.postnix.pw/9front/", // Henesy's "lookman": "./x/mux/lookman/lookman", // Vendored "sig": "./x/mux/man/sig", // ^ "gendex": "./gendex", // ^ "bullshit": "./x/mux/misc/bullshit", // ^ "extrafortunes": "../sys/games/lib/fortunes", // Unix "fortunes": "/usr/share/mirror/plan9front/lib/", // Plan 9 "oracledbs": "./oracledbs/", // Vendored if you want it } // Regularly dump the config go func() { delay, err := strconv.Atoi(c.Db["delay"]) if err != nil { fmt.Println("bad delay value, using default") delay = 20 } for { select { case <-dumpChan: dump() case <- time.After(time.Duration(delay) * time.Minute): dump() } time.Sleep(5 * time.Millisecond) } }() err := c.Read() if err != nil { fmt.Println("read cfg failed: -", err) c.Setup() } Session = s for id, _ := range Config.Feeds { // maybe only do at init step? str := Config.Feeds[id].Feed.UpdateURL feed, _ := rss.Fetch(str) if feed != nil { Config.Feeds[id].Feed = *feed } else { fmt.Println("Failed to fetch feed: ", id) } } go Listener() } // Writes current config to file func (c *Configuration) Write() error { path := c.Db["dir"] + "/" + c.Db["name"] if path == "/" { return errors.New("'dir' and 'name' must be in config") } var f *os.File var err error WRITE: f, err = os.OpenFile(path, os.O_RDWR, 0666) defer f.Close() if err != nil { if strings.Contains(err.Error(), "no such file or directory") { // Create files err = Config.Setup() if err != nil { // We have a creation problem return err } // Try again goto WRITE } else { fmt.Println("Error opening config (w), see: config.go -", err) return err } } else { // Serialize e := json.NewEncoder(f) err = e.Encode(Config) if err != nil { fmt.Println("Error writing config (w), see: config.go -", err) defer Config.Write() return err } } return nil } // Reads current config into memory func (c *Configuration) Read() error { path := c.Db["dir"] + "/" + c.Db["name"] if path == "/" { return errors.New("'dir' and 'name' must be in config") } var f *os.File var err error f, err = os.Open(path) defer f.Close() if err != nil { return err } // De-serialize d := json.NewDecoder(f) err = d.Decode(&Config) if err != nil { fmt.Println("Error reading config (r), see: config.go -", err) // Overwrite since the file is bad defer Config.Write() return err } return nil } // Set up config for the first time (if one doesn't exist) func (c *Configuration) Setup() error { err := os.Mkdir(c.Db["dir"], 0774) if err != nil { fmt.Println("Error in making cfg dir, see: config.go -", err) if !strings.Contains(err.Error(), "exists") { return err } } _, err = os.Create(c.Db["dir"] + "/" + c.Db["name"]) if err != nil { fmt.Println("Error in making cfg file, see: config.go -", err) if !strings.Contains(err.Error(), "exists") { return err } } return nil }