From aa73b6813c196df20b30a5f8094beb4ede55d6d0 Mon Sep 17 00:00:00 2001 From: Henesy Date: Sun, 15 Nov 2020 01:48:58 +0000 Subject: [PATCH] migrate config to One Big File ;; make a map of a=b values for config ;; rewrite reminders to be a slice --- main.go | 2 +- x/mux/commits.go | 86 ++++++++++++------------- x/mux/config.go | 163 +++++++---------------------------------------- x/mux/misc.go | 13 ---- x/mux/remind.go | 47 ++++++++++---- 5 files changed, 101 insertions(+), 210 deletions(-) diff --git a/main.go b/main.go index 72e090589c49bd9f972031f64a8b6ab6cdb9e787..06c7fa8f4996f258c0a0b5b8db2f39ad49e502fb 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ import ( sc "strconv" ) -const Version = "v0.1.0-alpha" +const Version = "v0.1.1" // Session is declared in the global space so it can be easily used // throughout this program. diff --git a/x/mux/commits.go b/x/mux/commits.go index 1d9894baa9955f80752e8f026a777c73c5a0918a..ce757e6349be03ba5641ec75f93acd1f54b5d323 100644 --- a/x/mux/commits.go +++ b/x/mux/commits.go @@ -15,35 +15,35 @@ import ( // Listen on the rss feed func Listener() { for { - for p, _ := range Feeds.Feeds { - //fmt.Print("Updating feed: ", Feeds.Feeds[p].Feed.Title, "\n") + for p, _ := range Config.Feeds { + //fmt.Print("Updating feed: ", Config.Feeds[p].Feed.Title, "\n") // maybe only do at init step? - str := Feeds.Feeds[p].Feed.UpdateURL + str := Config.Feeds[p].Feed.UpdateURL feed, err := rss.Fetch(str) if feed != nil { - Feeds.Feeds[p].Feed = *feed + Config.Feeds[p].Feed = *feed } else { //fmt.Println("Got a nil pointer for feed in commits for ", str, " as ", err) } - //err := Feeds.Feeds[p].Feed.Update() + //err := Config.Feeds[p].Feed.Update() if err != nil { fmt.Println("Error in updating RSS feed, see: x/mux/commits.go") fmt.Printf("%s\n\n", err) } else { additem := true - for j, _ := range Feeds.Feeds[p].Recent { - if Feeds.Feeds[p].Recent[j] == Feeds.Feeds[p].Feed.Items[0].Title { - //fmt.Println("Checking Recent ", j, " against ", Feeds.Feeds[p].Feed.Items[0].Title) + for j, _ := range Config.Feeds[p].Recent { + if Config.Feeds[p].Recent[j] == Config.Feeds[p].Feed.Items[0].Title { + //fmt.Println("Checking Recent ", j, " against ", Config.Feeds[p].Feed.Items[0].Title) additem = false break } } if additem { // x y z → x y z 0 → y z 0 - fmt.Println("Updating: ", Feeds.Feeds[p].Feed.Title) - Feeds.Feeds[p].Recent = append(Feeds.Feeds[p].Recent, Feeds.Feeds[p].Feed.Items[0].Title) - Feeds.Feeds[p].Recent = Feeds.Feeds[p].Recent[1:] + fmt.Println("Updating: ", Config.Feeds[p].Feed.Title) + Config.Feeds[p].Recent = append(Config.Feeds[p].Recent, Config.Feeds[p].Feed.Items[0].Title) + Config.Feeds[p].Recent = Config.Feeds[p].Recent[1:] Notify(p) break } @@ -59,11 +59,11 @@ func Listener() { // Notify subscribed channels to subscribed feeds func Notify(id int) { resp := ".\n" - resp += "**" + Feeds.Feeds[id].Feed.Title + ": **" + "\n" - resp += Feeds.Feeds[id].Feed.Items[0].Date.String() + "\n\n" + resp += "**" + Config.Feeds[id].Feed.Title + ": **" + "\n" + resp += Config.Feeds[id].Feed.Items[0].Date.String() + "\n\n" // If a 9front feed, extract the user ☺ - if strings.Contains(Feeds.Feeds[id].Feed.Items[0].Link, "http://code.9front.org/hg/") { - lines := strings.Split(Feeds.Feeds[id].Feed.Items[0].Summary, "\n") + if strings.Contains(Config.Feeds[id].Feed.Items[0].Link, "http://code.9front.org/hg/") { + lines := strings.Split(Config.Feeds[id].Feed.Items[0].Summary, "\n") for i, v := range lines { if strings.Contains(v, "user") { line := html.UnescapeString((lines[i+1])[6:len(lines[i+1])-5]) @@ -72,23 +72,23 @@ func Notify(id int) { } } } - resp += "`" + Feeds.Feeds[id].Feed.Items[0].Title + "`" + "\n" - resp += "\n" + Feeds.Feeds[id].Feed.Items[0].Link + "\n" - Feeds.Feeds[id].Feed.Items[0].Read = true + resp += "`" + Config.Feeds[id].Feed.Items[0].Title + "`" + "\n" + resp += "\n" + Config.Feeds[id].Feed.Items[0].Link + "\n" + Config.Feeds[id].Feed.Items[0].Read = true resp += "\n" // Loop through subbed chans and post notification message fmt.Println("Looping through subs to notify...") - for _, v := range Feeds.Subs { + for _, v := range Config.Subs { if v.SubID == id { Session.ChannelMessageSend(v.ChanID, resp) } time.Sleep(10 * time.Millisecond) } - fmt.Println("No new notifys for ", Feeds.Feeds[id].Feed.UpdateURL) - fmt.Println(Feeds.Feeds[id].Feed.Items[0]) - fmt.Println(Feeds.Feeds[id].Feed.Items[len(Feeds.Feeds[id].Feed.Items)-1]) + fmt.Println("No new notifys for ", Config.Feeds[id].Feed.UpdateURL) + fmt.Println(Config.Feeds[id].Feed.Items[0]) + fmt.Println(Config.Feeds[id].Feed.Items[len(Config.Feeds[id].Feed.Items)-1]) } @@ -99,12 +99,12 @@ func (m *Mux) Last(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { resp := ".\n" id, _ := strconv.Atoi(ctx.Fields[len(ctx.Fields) -1]) - if id >= 0 && id < len(Feeds.Feeds) { - resp += "**" + Feeds.Feeds[id].Feed.Title + ": **" + "\n" - resp += Feeds.Feeds[id].Feed.Items[0].Date.String() + "\n\n" + if id >= 0 && id < len(Config.Feeds) { + resp += "**" + Config.Feeds[id].Feed.Title + ": **" + "\n" + resp += Config.Feeds[id].Feed.Items[0].Date.String() + "\n\n" // If a 9front feed, extract the user ☺ - if strings.Contains(Feeds.Feeds[id].Feed.Items[0].Link, "http://code.9front.org/hg/") { - lines := strings.Split(Feeds.Feeds[id].Feed.Items[0].Summary, "\n") + if strings.Contains(Config.Feeds[id].Feed.Items[0].Link, "http://code.9front.org/hg/") { + lines := strings.Split(Config.Feeds[id].Feed.Items[0].Summary, "\n") for i, v := range lines { if strings.Contains(v, "user") { line := html.UnescapeString((lines[i+1])[6:len(lines[i+1])-5]) @@ -113,11 +113,11 @@ func (m *Mux) Last(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { } } } - resp += "`" + Feeds.Feeds[id].Feed.Items[0].Title + "`" + "\n" - //resp += "\n" + Feeds.Feeds[id].Feed.Items[0].Summary + "\n" - resp += "\n" + Feeds.Feeds[id].Feed.Items[0].Link + "\n" - Feeds.Feeds[id].Feed.Items[0].Read = true - fmt.Println("Last-ing notification: ", Feeds.Feeds[id].Feed.Items[0]) + resp += "`" + Config.Feeds[id].Feed.Items[0].Title + "`" + "\n" + //resp += "\n" + Config.Feeds[id].Feed.Items[0].Summary + "\n" + resp += "\n" + Config.Feeds[id].Feed.Items[0].Link + "\n" + Config.Feeds[id].Feed.Items[0].Read = true + fmt.Println("Last-ing notification: ", Config.Feeds[id].Feed.Items[0]) } else { resp += "Denied fetch. Invalid stream id, see: list command" } @@ -133,7 +133,7 @@ func (m *Mux) Last(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { func (m *Mux) List(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { resp := "```\n" - for p, v := range Feeds.Feeds { + for p, v := range Config.Feeds { resp += strconv.Itoa(p) + ": " + v.Feed.Title + ", " + v.Feed.Link + "\n" } @@ -152,7 +152,7 @@ func (m *Mux) Add(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { url := ctx.Fields[len(ctx.Fields) -1] fmt.Println("Proposed addition for: ", url) - for _, v := range Feeds.Feeds { + for _, v := range Config.Feeds { // this is bad matching, can't have two bitbucket url's? if strings.Contains(url, v.Feed.UpdateURL) { //fmt.Println(url) @@ -180,7 +180,7 @@ func (m *Mux) Add(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) { tmpFeed.Feed = *feed // Maybe make the size here a Config variable tmpFeed.Recent = make([]string, 3) - Feeds.Feeds = append(Feeds.Feeds, tmpFeed) + Config.Feeds = append(Config.Feeds, tmpFeed) resp += "Added." resp += "```\n" @@ -197,7 +197,7 @@ func (m *Mux) Remove(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) ID, err := strconv.Atoi(ctx.Fields[len(ctx.Fields) -1]) fmt.Println("Proposed removal for: ", ID) - if ID < 0 || ID > len(Feeds.Feeds) || err != nil { + if ID < 0 || ID > len(Config.Feeds) || err != nil { resp += "Denied! Feed does not exist!" resp += "```\n" goto REND; @@ -206,7 +206,7 @@ func (m *Mux) Remove(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) // Might not be thread safe - Feeds.Feeds = append(Feeds.Feeds[:ID], Feeds.Feeds[ID+1:]...) + Config.Feeds = append(Config.Feeds[:ID], Config.Feeds[ID+1:]...) resp += "Removed." REND: @@ -221,11 +221,11 @@ func (m *Mux) Subscribe(ds *discordgo.Session, dm *discordgo.Message, ctx *Conte resp := "\n" id, _ := strconv.Atoi(ctx.Fields[len(ctx.Fields) -1]) - if id >= 0 && id < len(Feeds.Feeds) { + if id >= 0 && id < len(Config.Feeds) { var sub Subscription // Check if already subscribed - for _, v := range Feeds.Subs { + for _, v := range Config.Subs { if v.ChanID == dm.ChannelID && v.SubID == id { resp += "Denied subscription. Already subscribed in this channel." goto NOSUB @@ -236,7 +236,7 @@ func (m *Mux) Subscribe(ds *discordgo.Session, dm *discordgo.Message, ctx *Conte sub.SubID = id // Might not be thread-safe - Feeds.Subs = append(Feeds.Subs, sub) + Config.Subs = append(Config.Subs, sub) resp += "Subscribed." NOSUB: } else { @@ -255,13 +255,13 @@ func (m *Mux) Unsubscribe(ds *discordgo.Session, dm *discordgo.Message, ctx *Con resp := "\n" id, _ := strconv.Atoi(ctx.Fields[len(ctx.Fields) -1]) - if id >= 0 && id < len(Feeds.Feeds) { + if id >= 0 && id < len(Config.Feeds) { // Check if subscribed removed := false - for i, v := range Feeds.Subs { + for i, v := range Config.Subs { if v.ChanID == dm.ChannelID && v.SubID == id { removed = true - Feeds.Subs = Feeds.Subs[:i+copy(Feeds.Subs[i:], Feeds.Subs[i+1:])] + Config.Subs = Config.Subs[:i+copy(Config.Subs[i:], Config.Subs[i+1:])] } } diff --git a/x/mux/config.go b/x/mux/config.go index f6935e468304c90bae01b706a3e36d1072eea193..d508d49464afa9b2f0b42e8de6d6a642e1fb76ec 100644 --- a/x/mux/config.go +++ b/x/mux/config.go @@ -9,14 +9,12 @@ import ( "strings" "github.com/SlyMarbo/rss" "github.com/bwmarrin/discordgo" - "container/list" + "time" ) // Global variables are bad var Config Configuration -var Feeds Feeder -var Rems *list.List var Session *discordgo.Session // Stores subscription information for channels related to RSS feeds @@ -38,40 +36,49 @@ type Feeder struct { // 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.Read() Session = s - for id, _ := range Feeds.Feeds { + for id, _ := range Config.Feeds { // maybe only do at init step? - str := Feeds.Feeds[id].Feed.UpdateURL + str := Config.Feeds[id].Feed.UpdateURL feed, _ := rss.Fetch(str) if feed != nil { - Feeds.Feeds[id].Feed = *feed + Config.Feeds[id].Feed = *feed } else { fmt.Println("Failed to fetch feed: ", id) } } - if Rems == nil { - Rems = list.New() + + if c.Db == nil { + c.Db = map[string]string { + "name": "glenda.cfg", + "dir": "./cfg", + } } + go Listener() } // Writes current config func (c *Configuration) Write() (rerr error) { - WRT: + WRITE: rerr = nil - f, err := os.OpenFile("./cfg/glenda.cfg", os.O_RDWR, 0666) + f, err := os.OpenFile(c.Db["dir"] + "/" + c.Db["name"], os.O_RDWR, 0666) defer f.Close() if err != nil { if strings.Contains(err.Error(), "no such file or directory") { + // Create and try again // danger: this can go infinite Config.Setup() - goto WRT + time.Sleep(5 * time.Millisecond) + goto WRITE } else { fmt.Println("Error opening config (w), see: config.go") fmt.Printf("%s\n", err) @@ -90,74 +97,16 @@ func (c *Configuration) Write() (rerr error) { return } -// Writes the Feed config file -func (c *Feeder) Write() (rerr error) { - FWRT: - rerr = nil - f, err := os.OpenFile("./cfg/feeds.cfg", os.O_RDWR, 0666) - defer f.Close() - if err != nil { - if strings.Contains(err.Error(), "no such file or directory") { - // danger: this can go infinite - Config.Setup() - goto FWRT - } else { - fmt.Println("Error opening feeds config (w), see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } else { - e := json.NewEncoder(f) - err = e.Encode(Feeds) - if err != nil { - fmt.Println("Error writing feeds config, see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } - - return -} - -// Writes the Reminders config file -func RemindersWrite() (rerr error) { - RWRT: - rerr = nil - f, err := os.OpenFile("./cfg/reminders.cfg", os.O_RDWR, 0666) - defer f.Close() - if err != nil { - if strings.Contains(err.Error(), "no such file or directory") { - // danger: this can go infinite - Config.Setup() - goto RWRT - } else { - fmt.Println("Error opening reminders config (w), see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } else { - e := json.NewEncoder(f) - err = e.Encode(*Rems) - if err != nil { - fmt.Println("Error writing reminders config, see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } - - return -} - // Reads current config into memory func (c *Configuration) Read() (rerr error) { - RD: - f, err := os.Open("./cfg/glenda.cfg") + READ: + f, err := os.Open(c.Db["dir"] + "/" + c.Db["name"]) defer f.Close() if err != nil { if strings.Contains(err.Error(), "no such file or directory") { // danger: this can go infinite Config.Setup() - goto RD + goto READ } else { fmt.Println("Error opening config (r), see: config.go") fmt.Printf("%s\n", err) @@ -173,85 +122,21 @@ func (c *Configuration) Read() (rerr error) { Config.Write() } } - f.Close() - - // Feeds - f, err = os.Open("./cfg/feeds.cfg") - if err != nil { - if strings.Contains(err.Error(), "no such file or directory") { - // danger: this can go infinite - Config.Setup() - goto RD - } else { - fmt.Println("Error opening feeds config (r), see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } else { - d := json.NewDecoder(f) - err = d.Decode(&Feeds) - if err != nil { - fmt.Println("Error reading feeds config, see: config.go") - fmt.Printf("%s\n", err) - rerr = err - Feeds.Write() - } - } - f.Close() - - // Reminders - f, err = os.Open("./cfg/reminders.cfg") - if err != nil { - if strings.Contains(err.Error(), "no such file or directory") { - // danger: this can go infinite - Config.Setup() - goto RD - } else { - fmt.Println("Error opening reminders config (r), see: config.go") - fmt.Printf("%s\n", err) - rerr = err - } - } else { - d := json.NewDecoder(f) - err = d.Decode(Rems) - if err != nil { - fmt.Println("Error reading reminders config, see: config.go") - fmt.Printf("%s\n", err) - rerr = err - Rems = list.New() - RemindersWrite() - } - } - f.Close() return } // Set up config for the first time (if one doesn't exist) func (c *Configuration) Setup() { - err := os.Mkdir("./cfg", 0774) + err := os.Mkdir(c.Db["dir"], 0774) if err != nil { fmt.Println("Error in making cfg dir, see: config.go") fmt.Println(err) } - _, err = os.Create("cfg/glenda.cfg") + _, err = os.Create(c.Db["dir"] + "/" + c.Db["name"]) if err != nil { fmt.Println("Error in making cfg file, see: config.go") fmt.Println(err) } - - // Feeds - _, err = os.Create("cfg/feeds.cfg") - if err != nil { - fmt.Println("Error in making feed cfg file, see: config.go") - fmt.Println(err) - } - - // Reminders - _, err = os.Create("cfg/reminders.cfg") - if err != nil { - fmt.Println("Error in making reminders cfg file, see: config.go") - fmt.Println(err) - } } diff --git a/x/mux/misc.go b/x/mux/misc.go index 0c46f5a6fe0010a91d5c7a6d1681da68eb5866ed..7fef7700e019779ad61caf8b08f93e120377c1a3 100644 --- a/x/mux/misc.go +++ b/x/mux/misc.go @@ -44,19 +44,6 @@ func dump() string { } else { resp += "Ok." } - err = Feeds.Write() - if err != nil { - resp += "Dump feeds failed. Check logs.\n" - } else { - resp += "Ok." - } - err = RemindersWrite() - if err != nil { - resp += "Dump reminders failed. Check logs.\n" - } else { - resp += "Ok." - } - resp += "\n" return resp } diff --git a/x/mux/remind.go b/x/mux/remind.go index 78d42785cdd102e943b4c9ea41eb0bfec16ad796..4a071e3d72a0460706ec5f8d8ae56c131c8858f7 100644 --- a/x/mux/remind.go +++ b/x/mux/remind.go @@ -25,33 +25,52 @@ type Reminder struct { func Reminders() { // TODO -- Should be a heap and more robust (fix config first) - //Rems := list.New() + //Config.Reminders := list.New() // Handle reminders for { select { case r := <- RemChan: // Handle new reminder - Rems.PushBack(r) + Config.Reminders = append(Config.Reminders, r) //write() default: // Check for any due reminders - if Rems != nil { - if Rems.Front() != nil { - for e := Rems.Front(); ; e = e.Next() { - if e == nil { - break + for i, r := range Config.Reminders { + if time.Now().After(r.NotifyAfter) { + // If we have passed the time of desired notification + r.Session.ChannelMessageSend(r.ChannelID, r.User.Mention() + " -- " + r.Reason) + + // Delete the reminder + // God this is ugly + switch len(Config.Reminders) { + case 1: + // Make empty safely + Config.Reminders = []Reminder{} + case 2: + // Binary switch + switch i { + case 0: + Config.Reminders = []Reminder{Config.Reminders[1]} + case 1: + Config.Reminders = []Reminder{Config.Reminders[0]} } - - r, _ := e.Value.(Reminder) - if time.Now().After(r.NotifyAfter) { - // If we have passed the time of desired notification - r.Session.ChannelMessageSend(r.ChannelID, r.User.Mention() + " -- " + r.Reason) - Rems.Remove(e) - //write() + default: + switch i { + case len(Config.Reminders) - 1: + // Last + Config.Reminders = Config.Reminders[:i] + case 0: + // First + Config.Reminders = Config.Reminders[i+1:] + default: + // Not first nor last + Config.Reminders = append(Config.Reminders[:i], Config.Reminders[i+1:]...) } } + + //write() } }