From e8853b3be9e8fd48b9234fb124190caea5a89d94 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 5 Jul 2016 03:01:56 +0100 Subject: [PATCH] Move from an ignore handler to hacking the IRC adapter --- adapters/irc/irc.go | 106 +++++++++++++++++++++++++++++++++ handlers/ignore/ignore.go | 59 ------------------ handlers/ignore/ignore_test.go | 46 -------------- lysenko.go | 36 +++++------ 4 files changed, 120 insertions(+), 127 deletions(-) create mode 100644 adapters/irc/irc.go delete mode 100644 handlers/ignore/ignore.go delete mode 100644 handlers/ignore/ignore_test.go diff --git a/adapters/irc/irc.go b/adapters/irc/irc.go new file mode 100644 index 0000000..0e63bd6 --- /dev/null +++ b/adapters/irc/irc.go @@ -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 . + +// 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/ignore/ignore.go b/handlers/ignore/ignore.go deleted file mode 100644 index 1fba0c7..0000000 --- a/handlers/ignore/ignore.go +++ /dev/null @@ -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) -} diff --git a/handlers/ignore/ignore_test.go b/handlers/ignore/ignore_test.go deleted file mode 100644 index eb449b7..0000000 --- a/handlers/ignore/ignore_test.go +++ /dev/null @@ -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") - } -} diff --git a/lysenko.go b/lysenko.go index a88ac9f..f4ed7a5 100644 --- a/lysenko.go +++ b/lysenko.go @@ -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("edb.AddQuoteHandler{QuoteDB: db}) - add("edb.LastQuoteHandler{QuoteDB: db}) - add("edb.FindQuoteHandler{QuoteDB: db}) - add("edb.RandQuoteHandler{QuoteDB: db}) - add("edb.QuoteHandler{QuoteDB: db}) - - go hugot.ListenAndServe(ctx, adapter, hugot.DefaultMux) + 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}) + go hugot.ListenAndServe(ctx, adapter, mux) conn.Loop() }