marvin

A simple and modular IRC bot

git clone https://git.8pit.net/marvin.git

 1// This program is free software: you can redistribute it and/or modify
 2// it under the terms of the GNU Affero General Public License as
 3// published by the Free Software Foundation, either version 3 of the
 4// License, or (at your option) any later version.
 5//
 6// This program is distributed in the hope that it will be useful, but
 7// WITHOUT ANY WARRANTY; without even the implied warranty of
 8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 9// Affero General Public License for more details.
10//
11// You should have received a copy of the GNU Affero General Public
12// License along with this program. If not, see <http://www.gnu.org/licenses/>.
13
14package remind
15
16import (
17	"github.com/nmeum/marvin/irc"
18	"github.com/nmeum/marvin/modules"
19	"strings"
20	"time"
21)
22
23type Module struct {
24	TimeLimit int `json:"time_limit"`
25	UserLimit int `json:"user_limit"`
26}
27
28func Init(moduleSet *modules.ModuleSet) {
29	moduleSet.Register(new(Module))
30}
31
32func (m *Module) Name() string {
33	return "remind"
34}
35
36func (m *Module) Help() string {
37	return "USAGE: !remind DURATION MSG"
38}
39
40func (m *Module) Defaults() {
41	m.TimeLimit = 10
42	m.UserLimit = 3
43}
44
45func (m *Module) Load(client *irc.Client) error {
46	users := make(map[string]int)
47	client.CmdHook("privmsg", func(c *irc.Client, msg irc.Message) error {
48		splited := strings.Fields(msg.Data)
49		if len(splited) < 3 || splited[0] != "!remind" {
50			return nil
51		}
52
53		duration, err := time.ParseDuration(splited[1])
54		if err != nil {
55			return c.Write("NOTICE %s :ERROR: %s", msg.Receiver, err.Error())
56		}
57
58		limit := time.Duration(m.TimeLimit) * time.Hour
59		if duration > limit {
60			return c.Write("NOTICE %s :%v hours exceeds the limit of %v hours",
61				msg.Receiver, duration.Hours(), limit.Hours())
62		}
63
64		if users[msg.Sender.Host] >= m.UserLimit {
65			return c.Write("NOTICE %s :You can only run %d reminders at a time",
66				msg.Receiver, m.UserLimit)
67		}
68
69		users[msg.Sender.Host]++
70		reminder := strings.Join(splited[2:], " ")
71		time.AfterFunc(duration, func() {
72			users[msg.Sender.Host]--
73			c.Write("PRIVMSG %s :Reminder: %s",
74				msg.Sender.Name, reminder)
75		})
76
77		return c.Write("NOTICE %s :Reminder setup for %s",
78			msg.Receiver, duration.String())
79	})
80
81	return nil
82}