switch from shaky ignores to a refractory period on commands
This commit is contained in:
@@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
}
|
|
||||||
}
|
|
55
handlers/deadline/deadline.go
Normal file
55
handlers/deadline/deadline.go
Normal file
@@ -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
|
||||||
|
}
|
15
lysenko.go
15
lysenko.go
@@ -8,11 +8,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tcolgate/hugot"
|
"github.com/tcolgate/hugot"
|
||||||
|
"github.com/tcolgate/hugot/adapters/irc"
|
||||||
|
|
||||||
irce "github.com/thoj/go-ircevent"
|
irce "github.com/thoj/go-ircevent"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"ur.gs/lysenko/adapters/irc"
|
"ur.gs/lysenko/handlers/deadline"
|
||||||
"ur.gs/lysenko/handlers/quotedb"
|
"ur.gs/lysenko/handlers/quotedb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,7 +21,6 @@ var (
|
|||||||
channels = flag.String("channels", "##testing,##test", "Channels to join (separated by comma)")
|
channels = flag.String("channels", "##testing,##test", "Channels to join (separated by comma)")
|
||||||
host = flag.String("host", "chat.freenode.net", "Server host[:port]")
|
host = flag.String("host", "chat.freenode.net", "Server host[:port]")
|
||||||
ident = flag.String("ident", "lysenko", "Lysenko Bot")
|
ident = flag.String("ident", "lysenko", "Lysenko Bot")
|
||||||
ignores = flag.String("ignore", "", "nicks to ignore, comma-separated")
|
|
||||||
nick = flag.String("nick", "lysenko", "Lysenko Bot")
|
nick = flag.String("nick", "lysenko", "Lysenko Bot")
|
||||||
nickserv = flag.String("nickserv", "", "NickServ password")
|
nickserv = flag.String("nickserv", "", "NickServ password")
|
||||||
quotes = flag.String("quotedb", ":memory:", "sqlite3 quote database")
|
quotes = flag.String("quotedb", ":memory:", "sqlite3 quote database")
|
||||||
@@ -34,7 +34,6 @@ func init() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
ignoreList := strings.Split(*ignores, ",")
|
|
||||||
channelList := strings.Split(*channels, ",")
|
channelList := strings.Split(*channels, ",")
|
||||||
|
|
||||||
conn := irce.IRC(*nick, *ident)
|
conn := irce.IRC(*nick, *ident)
|
||||||
@@ -46,7 +45,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer conn.Quit()
|
defer conn.Quit()
|
||||||
|
|
||||||
adapter, err := irc.New(conn, ignoreList...)
|
adapter, err := irc.New(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -64,10 +63,10 @@ func main() {
|
|||||||
|
|
||||||
mux := hugot.DefaultMux
|
mux := hugot.DefaultMux
|
||||||
mux.AddHearsHandler("edb.AddQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.AddQuoteHandler{QuoteDB: db})
|
||||||
mux.AddHearsHandler("edb.LastQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler(deadline.NewHears("edb.LastQuoteHandler{QuoteDB: db}))
|
||||||
mux.AddHearsHandler("edb.FindQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler(deadline.NewHears("edb.FindQuoteHandler{QuoteDB: db}))
|
||||||
mux.AddHearsHandler("edb.RandQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler(deadline.NewHears("edb.RandQuoteHandler{QuoteDB: db}))
|
||||||
mux.AddHearsHandler("edb.QuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler(deadline.NewHears("edb.QuoteHandler{QuoteDB: db}))
|
||||||
|
|
||||||
go hugot.ListenAndServe(ctx, adapter, mux)
|
go hugot.ListenAndServe(ctx, adapter, mux)
|
||||||
conn.Loop()
|
conn.Loop()
|
||||||
|
Reference in New Issue
Block a user