~kris/9p

glenda

352a41b723f098445ffa966cab812fb07ce10a53 — Sean Hinchee 8 years ago 9b03336
most of remindme done; need to fix time interval counting
5 files changed, 119 insertions(+), 9 deletions(-)

M TODO
M main.go
M mux.go
M x/mux/config.go
A x/mux/remind.go
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
}