Move from an ignore handler to hacking the IRC adapter
This commit is contained in:
106
adapters/irc/irc.go
Normal file
106
adapters/irc/irc.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
@@ -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)
|
|
||||||
}
|
|
@@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
36
lysenko.go
36
lysenko.go
@@ -8,11 +8,11 @@ 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/handlers/ignore"
|
"ur.gs/lysenko/adapters/irc"
|
||||||
"ur.gs/lysenko/handlers/quotedb"
|
"ur.gs/lysenko/handlers/quotedb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,13 +32,6 @@ func init() {
|
|||||||
rand.Seed(time.Now().Unix())
|
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() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
ignoreList := strings.Split(*ignores, ",")
|
ignoreList := strings.Split(*ignores, ",")
|
||||||
@@ -55,30 +48,29 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer conn.Quit()
|
defer conn.Quit()
|
||||||
|
|
||||||
|
adapter, err := irc.New(conn, ignoreList...)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, channel := range channelList {
|
for _, channel := range channelList {
|
||||||
conn.Join(channel)
|
conn.Join(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
adapter, err := irc.New(conn)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := quotedb.New(*quotes)
|
db, err := quotedb.New(*quotes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer db.DB.Close()
|
defer db.DB.Close()
|
||||||
|
|
||||||
add := buildAdder(hugot.DefaultMux, ignoreList)
|
mux := hugot.DefaultMux
|
||||||
add("edb.AddQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.AddQuoteHandler{QuoteDB: db})
|
||||||
add("edb.LastQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.LastQuoteHandler{QuoteDB: db})
|
||||||
add("edb.FindQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.FindQuoteHandler{QuoteDB: db})
|
||||||
add("edb.RandQuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.RandQuoteHandler{QuoteDB: db})
|
||||||
add("edb.QuoteHandler{QuoteDB: db})
|
mux.AddHearsHandler("edb.QuoteHandler{QuoteDB: db})
|
||||||
|
|
||||||
go hugot.ListenAndServe(ctx, adapter, hugot.DefaultMux)
|
|
||||||
|
|
||||||
|
go hugot.ListenAndServe(ctx, adapter, mux)
|
||||||
conn.Loop()
|
conn.Loop()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user