M TODO => TODO +3 -0
@@ 14,3 14,6 @@ Problems
* Move feed caching to another file than the .cfg (seriously this is a fcking mess)
* Scripts should have a universal config such as an environment variable (more portable/configurable)
* No role/user restrictions (should be a txt file of admin/mod users, maybe)
+* Reminders don't persist between bot reboots
+* Reminders should be hashed and deletable/modifiable by the creating user
+* Reminders should use a min heap
M main.go => main.go +2 -5
@@ 77,12 77,9 @@ func main() {
}
// Init Mux daemons
- // Problem child Listener is
-// go mux.Listener()
-
-// go mux.CommMux()
-// go CommMux()
go mux.Config.Init(Session)
+ mux.RemChan = make(chan mux.Reminder, 5)
+ go mux.Reminders()
Session.UpdateStatus(0, "with #cat-v")
M mux.go => mux.go +2 -0
@@ 43,4 43,6 @@ func init() {
Router.Route("beer", ":beer:", Router.Beer)
Router.Route("whiskey", ":tumbler_glass:", Router.Whiskey)
+
+ Router.Route("remindme", "Set a reminder for a given time interval ([int][hmsdny] [reminder]).", Router.RemindMe)
}
M x/mux/config.go => x/mux/config.go +5 -4
@@ 11,6 11,11 @@ import (
"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
@@ 114,7 119,3 @@ func (c *Configuration) Setup() {
fmt.Println(err)
}
}
-
-// Global variables are bad
-var Config Configuration
-var Session *discordgo.Session
A x/mux/remind.go => x/mux/remind.go +107 -0
@@ 0,0 1,107 @@
+package mux
+
+import (
+ "github.com/bwmarrin/discordgo"
+ "time"
+sc "strconv"
+ "container/list"
+)
+
+
+// Channel for posting reminders -- inits in main
+var RemChan chan Reminder
+
+// Stores a reminder to be posted to a given user
+type Reminder struct {
+ NotifyAfter time.Time
+ Reason string
+ User discordgo.User
+ ChannelID string
+ Session discordgo.Session
+}
+
+// Reminder daemon process that gets started in main and listens on RemChan
+func Reminders() {
+ // Should be a heap and persist across reboots
+ rems := list.New()
+ for {
+ select {
+ case r := <- RemChan:
+ // Handle new reminder
+ rems.PushBack(r)
+
+ default:
+ // Check for any due reminders
+ for e := rems.Front(); ; e = e.Next() {
+ if e == nil {
+ break
+ }
+
+ 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.Reason)
+ rems.Remove(e)
+ }
+ }
+
+ time.Sleep(50 * time.Millisecond)
+ }
+ }
+}
+
+// Reminds a user about a given reason after a specified time interval has passed
+func (m *Mux) RemindMe(ds *discordgo.Session, dm *discordgo.Message, ctx *Context) {
+ resp := ""
+
+ // remindme 20m dothing
+ if len(ctx.Fields) >= 3 {
+ var rem Reminder
+ periodLong := ctx.Fields[len(ctx.Fields)-2]
+ reasonLong := ctx.Fields[2 : len(ctx.Fields)]
+ rem.User = *dm.Author
+ rem.ChannelID = dm.ChannelID
+ rem.Session = *ds
+
+ reason := ""
+ for _, v := range reasonLong {
+ reason += v
+ reason += " "
+ }
+ rem.Reason = reason
+
+ interval := periodLong[len(periodLong)-1]
+ period, err := sc.Atoi(periodLong[:len(periodLong)-2])
+ if err != nil {
+ resp += "Invalid period value."
+ goto SEND
+ }
+
+ var dur time.Duration
+ switch interval {
+ case 's':
+ dur = time.Second
+ case 'm':
+ dur = time.Minute
+ case 'h':
+ dur = time.Hour
+ default:
+ resp += "Invalid interval specifier."
+ goto SEND
+ }
+
+ rem.NotifyAfter = time.Now().Add(time.Duration(period) * dur)
+
+ RemChan <- rem
+
+ } else {
+ resp += "Please specify a time operator in the form [int][type] and a description (20h do thing)."
+ }
+
+ SEND:
+ resp += "\n"
+
+ ds.ChannelMessageSend(dm.ChannelID, resp)
+
+ return
+}