Move from an ignore handler to hacking the IRC adapter

This commit is contained in:
2016-07-05 03:01:56 +01:00
parent 41e45e8f13
commit e8853b3be9
4 changed files with 120 additions and 127 deletions

106
adapters/irc/irc.go Normal file
View File

@@ -0,0 +1,106 @@
// 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,
}
}

View File

@@ -1,59 +0,0 @@
// package ignore is a Hugot handler that will force any messages received from
// a set of matching idents to be ignored
package ignore
import (
"github.com/tcolgate/hugot"
"golang.org/x/net/context"
)
type IgnoreHearsHandler struct {
hugot.HearsHandler
Ignores map[string]struct{}
}
type IgnoreCommandHandler struct {
hugot.CommandHandler
Ignores map[string]struct{}
}
func NewCommand(list []string, next hugot.CommandHandler) hugot.CommandHandler {
return &IgnoreCommandHandler{
CommandHandler: next,
Ignores: buildIgnores(list),
}
}
func NewHears(list []string, next hugot.HearsHandler) hugot.HearsHandler {
return &IgnoreHearsHandler{
HearsHandler: next,
Ignores: buildIgnores(list),
}
}
func buildIgnores(ignores []string) map[string]struct{} {
out := make(map[string]struct{}, len(ignores))
for _, nick := range ignores {
out[nick] = struct{}{}
}
return out
}
func (i *IgnoreHearsHandler) Heard(ctx context.Context, w hugot.ResponseWriter, m *hugot.Message, matches [][]string) {
if _, present := i.Ignores[m.From]; present {
return
}
i.HearsHandler.Heard(ctx, w, m, matches)
}
func (i *IgnoreCommandHandler) Command(ctx context.Context, w hugot.ResponseWriter, m *hugot.Message) error {
if _, present := i.Ignores[m.From]; present {
return nil
}
return i.CommandHandler.Command(ctx, w, m)
}

View File

@@ -1,46 +0,0 @@
package ignore_test
import (
"regexp"
"testing"
"github.com/tcolgate/hugot"
"golang.org/x/net/context"
"ur.gs/lysenko/handlers/ignore"
)
type DummyHearsHandler struct {
Called bool
}
func (h *DummyHearsHandler) Describe() (string, string) {
return "", ""
}
func (h *DummyHearsHandler) Hears() *regexp.Regexp {
return regexp.MustCompile(``)
}
func (h *DummyHearsHandler) Heard(ctx context.Context, w hugot.ResponseWriter, m *hugot.Message, submatches [][]string) {
h.Called = true
}
func TestIgnoreHearsPassesOKNick(t *testing.T) {
msg := hugot.Message{}
dummy := &DummyHearsHandler{}
ignorer := ignore.NewHears([]string{"foo"}, dummy)
ignorer.Heard(context.TODO(), hugot.NewNullResponseWriter(msg), &msg, [][]string{})
if !dummy.Called {
t.Fatal("Dummy not called when it should have been")
}
}
func TestIgnoreHearsBlocksBadNick(t *testing.T) {
msg := hugot.Message{From: "foo"}
dummy := &DummyHearsHandler{}
ignorer := ignore.NewHears([]string{"foo"}, dummy)
ignorer.Heard(context.TODO(), hugot.NewNullResponseWriter(msg), &msg, [][]string{})
if dummy.Called {
t.Fatal("Dummy called when it shouldn't have been")
}
}

View File

@@ -8,11 +8,11 @@ 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/handlers/ignore"
"ur.gs/lysenko/adapters/irc"
"ur.gs/lysenko/handlers/quotedb"
)
@@ -32,13 +32,6 @@ func init() {
rand.Seed(time.Now().Unix())
}
func buildAdder(mux *hugot.Mux, ignoreList []string) func(next hugot.HearsHandler) {
return func(next hugot.HearsHandler) {
mux.AddHearsHandler(ignore.NewHears(ignoreList, next))
}
}
func main() {
flag.Parse()
ignoreList := strings.Split(*ignores, ",")
@@ -55,30 +48,29 @@ func main() {
}
defer conn.Quit()
adapter, err := irc.New(conn, ignoreList...)
if err != nil {
log.Fatal(err)
}
for _, channel := range channelList {
conn.Join(channel)
}
ctx := context.Background()
adapter, err := irc.New(conn)
if err != nil {
log.Fatal(err)
}
db, err := quotedb.New(*quotes)
if err != nil {
log.Fatal(err)
}
defer db.DB.Close()
add := buildAdder(hugot.DefaultMux, ignoreList)
add(&quotedb.AddQuoteHandler{QuoteDB: db})
add(&quotedb.LastQuoteHandler{QuoteDB: db})
add(&quotedb.FindQuoteHandler{QuoteDB: db})
add(&quotedb.RandQuoteHandler{QuoteDB: db})
add(&quotedb.QuoteHandler{QuoteDB: db})
go hugot.ListenAndServe(ctx, adapter, hugot.DefaultMux)
mux := hugot.DefaultMux
mux.AddHearsHandler(&quotedb.AddQuoteHandler{QuoteDB: db})
mux.AddHearsHandler(&quotedb.LastQuoteHandler{QuoteDB: db})
mux.AddHearsHandler(&quotedb.FindQuoteHandler{QuoteDB: db})
mux.AddHearsHandler(&quotedb.RandQuoteHandler{QuoteDB: db})
mux.AddHearsHandler(&quotedb.QuoteHandler{QuoteDB: db})
go hugot.ListenAndServe(ctx, adapter, mux)
conn.Loop()
}