From 38982bf2c972e733b72f12e95c6c59b2b84b409b Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 5 Jul 2016 03:54:02 +0100 Subject: [PATCH] switch from shaky ignores to a refractory period on commands --- adapters/irc/irc.go | 106 ---------------------------------- handlers/deadline/deadline.go | 55 ++++++++++++++++++ lysenko.go | 15 +++-- 3 files changed, 62 insertions(+), 114 deletions(-) delete mode 100644 adapters/irc/irc.go create mode 100644 handlers/deadline/deadline.go diff --git a/adapters/irc/irc.go b/adapters/irc/irc.go deleted file mode 100644 index 0e63bd6..0000000 --- a/adapters/irc/irc.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2016 Tristan Colgate-McFarlane -// -// This file is part of hugot. -// -// hugot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// hugot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with hugot. If not, see . - -// Package irc implements a simple adapter for IRC using -// github.com/thoj/go-ircevent -package irc - -import ( - "fmt" - "regexp" - "strings" - - "golang.org/x/net/context" - - "github.com/golang/glog" - "github.com/tcolgate/hugot" - irce "github.com/thoj/go-ircevent" -) - -// New creates a new adapter that communicates with an IRC server using -// github.com/thoj/go-ircevent -// -// You can specify a list of hosts (in the irc-event sense) to ignore. -func New(i *irce.Connection, ignores ...string) (hugot.Adapter, error) { - a := &irc{ - i, - make(chan *hugot.Message), - regexp.MustCompile(fmt.Sprintf("^%s[:, ]?(.*)", i.GetNick())), - make(map[string]struct{}, len(ignores)), - } - - for _, ignore := range ignores { - a.ignores[ignore] = struct{}{} - } - - i.AddCallback("PRIVMSG", a.gotEvent) - return a, nil -} - -type irc struct { - *irce.Connection - c chan *hugot.Message - dir *regexp.Regexp - ignores map[string]struct{} -} - -func (i *irc) gotEvent(e *irce.Event) { - if _, present := i.ignores[e.Host]; present { - return - } - - go func() { - if glog.V(3) { - glog.Infof("Got %#v", *e) - } - i.c <- i.eventToHugot(e) - }() -} - -func (irc *irc) Send(ctx context.Context, m *hugot.Message) { - for _, l := range strings.Split(m.Text, "\n") { - irc.Privmsg(m.Channel, l) - } -} - -func (irc *irc) Receive() <-chan *hugot.Message { - return irc.c -} - -func (irc *irc) eventToHugot(e *irce.Event) *hugot.Message { - txt := e.Message() - tobot := false - - // Check if the message was sent @bot, if so, set it as to us - // and strip the leading politeness - dirMatch := irc.dir.FindStringSubmatch(txt) - if glog.V(3) { - glog.Infof("Match %#v", dirMatch) - } - - if len(dirMatch) > 1 { - tobot = true - txt = strings.Trim(dirMatch[1], " ") - } - - return &hugot.Message{ - Channel: e.Arguments[0], - From: e.Nick, - Text: txt, - ToBot: tobot, - } -} diff --git a/handlers/deadline/deadline.go b/handlers/deadline/deadline.go new file mode 100644 index 0000000..9697924 --- /dev/null +++ b/handlers/deadline/deadline.go @@ -0,0 +1,55 @@ +// package deadline is a Hugot handler that aims to reduce channel noise on a +// wrapped handler. Upon invocation, a deadline is set. Further invocations will +// be ignored until after the deadline has passed. +package deadline + +import ( + "time" + + "github.com/tcolgate/hugot" + "golang.org/x/net/context" +) + +type HearsDeadline struct { + hugot.HearsHandler + + Deadline time.Time +} + +type CommandDeadline struct { + hugot.CommandHandler + + Deadline time.Time +} + +func NewCommand(next hugot.CommandHandler) hugot.CommandHandler { + return &CommandDeadline{CommandHandler: next, Deadline: time.Now().UTC()} +} + +func NewHears(next hugot.HearsHandler) hugot.HearsHandler { + return &HearsDeadline{HearsHandler: next, Deadline: time.Now().UTC()} +} + +func (i *HearsDeadline) Heard(ctx context.Context, w hugot.ResponseWriter, m *hugot.Message, matches [][]string) { + now := time.Now().UTC() + if now.After(i.Deadline) { + i.Deadline = now.Add(2 * time.Minute) + i.HearsHandler.Heard(ctx, w, m, matches) + return + } + + // punish channel noise harder if people start spamming + // i.Deadline = i.Deadline.Add(1 * time.Minute) +} + +func (i *CommandDeadline) Command(ctx context.Context, w hugot.ResponseWriter, m *hugot.Message) error { + now := time.Now().UTC() + if now.After(i.Deadline) { + i.Deadline = now.Add(2 * time.Minute) + return i.CommandHandler.Command(ctx, w, m) + } + + // punish channel noise harder if people start spamming + // i.Deadline = i.Deadline.Add(1 * time.Minute) + return nil +} diff --git a/lysenko.go b/lysenko.go index a59f546..d040470 100644 --- a/lysenko.go +++ b/lysenko.go @@ -8,11 +8,12 @@ import ( "time" "github.com/tcolgate/hugot" + "github.com/tcolgate/hugot/adapters/irc" irce "github.com/thoj/go-ircevent" "golang.org/x/net/context" - "ur.gs/lysenko/adapters/irc" + "ur.gs/lysenko/handlers/deadline" "ur.gs/lysenko/handlers/quotedb" ) @@ -20,7 +21,6 @@ var ( channels = flag.String("channels", "##testing,##test", "Channels to join (separated by comma)") host = flag.String("host", "chat.freenode.net", "Server host[:port]") ident = flag.String("ident", "lysenko", "Lysenko Bot") - ignores = flag.String("ignore", "", "nicks to ignore, comma-separated") nick = flag.String("nick", "lysenko", "Lysenko Bot") nickserv = flag.String("nickserv", "", "NickServ password") quotes = flag.String("quotedb", ":memory:", "sqlite3 quote database") @@ -34,7 +34,6 @@ func init() { func main() { flag.Parse() - ignoreList := strings.Split(*ignores, ",") channelList := strings.Split(*channels, ",") conn := irce.IRC(*nick, *ident) @@ -46,7 +45,7 @@ func main() { } defer conn.Quit() - adapter, err := irc.New(conn, ignoreList...) + adapter, err := irc.New(conn) if err != nil { log.Fatal(err) } @@ -64,10 +63,10 @@ func main() { mux := hugot.DefaultMux mux.AddHearsHandler("edb.AddQuoteHandler{QuoteDB: db}) - mux.AddHearsHandler("edb.LastQuoteHandler{QuoteDB: db}) - mux.AddHearsHandler("edb.FindQuoteHandler{QuoteDB: db}) - mux.AddHearsHandler("edb.RandQuoteHandler{QuoteDB: db}) - mux.AddHearsHandler("edb.QuoteHandler{QuoteDB: db}) + mux.AddHearsHandler(deadline.NewHears("edb.LastQuoteHandler{QuoteDB: db})) + mux.AddHearsHandler(deadline.NewHears("edb.FindQuoteHandler{QuoteDB: db})) + mux.AddHearsHandler(deadline.NewHears("edb.RandQuoteHandler{QuoteDB: db})) + mux.AddHearsHandler(deadline.NewHears("edb.QuoteHandler{QuoteDB: db})) go hugot.ListenAndServe(ctx, adapter, mux) conn.Loop()