package mux
import (
"github.com/bwmarrin/discordgo"
"time"
sc "strconv"
"container/list"
"fmt"
"os"
"encoding/json"
"strings"
)
// 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() {
// TODO -- Should be a heap and more robus (fix config first)
rems := list.New()
RD:
f, err := os.Open("./cfg/reminders.cfg")
write := func() (rerr error) {
e := json.NewEncoder(f)
err = e.Encode(rems)
if err != nil {
fmt.Println("Error writing config, see: remind.go")
fmt.Printf("%s\n", err)
rerr = err
}
return
}
setup := func() (rerr error) {
err := os.Mkdir("./cfg", 0774)
if err != nil {
fmt.Println("Error in making cfg dir, see: remind.go")
fmt.Println(err)
}
_, err = os.Create("cfg/reminders.cfg")
if err != nil {
fmt.Println("Error in making cfg file, see: remind.go")
fmt.Println(err)
}
rerr = err
return
}
defer f.Close()
if err != nil {
if strings.Contains(err.Error(), "no such file or directory") {
// danger: this can go infinite
setup()
goto RD
} else {
fmt.Println("Error opening config (r), see: remind.go")
fmt.Printf("%s\n", err)
}
} else {
d := json.NewDecoder(f)
err = d.Decode(&rems)
if err != nil {
fmt.Println("Error reading config, see: remind.go")
fmt.Printf("%s\n", err)
write()
}
}
// Handle reminders
for {
select {
case r := <- RemChan:
// Handle new reminder
rems.PushBack(r)
write()
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.User.Mention() + " -- " + r.Reason)
rems.Remove(e)
write()
}
}
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[1]
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)-1])
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
case 'd':
dur = time.Hour * time.Duration(24)
default:
resp += "Invalid interval specifier."
goto SEND
}
rem.NotifyAfter = time.Now().Add(time.Duration(period) * dur)
RemChan <- rem
resp += "Ok."
} 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
}