From 1c780ab0000890760bc923fc9322dd8462e83fa1 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 25 Dec 2016 14:31:37 +0100 Subject: Split last --- href.go | 8 ++--- last.go | 49 +++++++++++++++++++++++++ main.go | 126 +++++++++++++++++++--------------------------------------------- 3 files changed, 89 insertions(+), 94 deletions(-) create mode 100644 last.go diff --git a/href.go b/href.go index 0743807..b18b3f3 100644 --- a/href.go +++ b/href.go @@ -66,18 +66,18 @@ func getLinks(s string) (ret []string) { return } -func links(msg chan string) chan string { - c := make(chan string) +func linker(out chan string) chan string { + c := make(chan string, 1) go func() { for l := range c { for _, v := range getLinks(l) { - log.Println("URL:", v) + log.Println("URL", v) t, err := getTitle(v) if err != nil { log.Println(err) } if t != "" { - msg <- fmt.Sprintf("Title: %v", t) + out <- fmt.Sprintf("Title: %v", t) } } } diff --git a/last.go b/last.go new file mode 100644 index 0000000..34a3022 --- /dev/null +++ b/last.go @@ -0,0 +1,49 @@ +package main + +import ( + "container/ring" + "fmt" + "time" +) + +type Msg struct { + Time time.Time + Nick string + Text string +} + +type LastBuf struct { + *ring.Ring +} + +func NewLastBuf(n int) *LastBuf { + return &LastBuf{ring.New(n)} +} + +func (v *LastBuf) Push(t time.Time, nick, text string) { + v.Value = Msg{Time: t, Nick: nick, Text: text} + v.Ring = v.Next() +} + +// walk through buffer and find last message +func (v *LastBuf) Last(nick string) string { + var msg string + v.Do(func(v interface{}) { + if l, ok := v.(Msg); ok { + if l.Nick == nick { + msg = l.Text + } + } + }) + return msg +} + +func (v *LastBuf) Dump(c chan string) { + v.Do(func(v interface{}) { + if l, ok := v.(Msg); ok { + c <- fmt.Sprintf("%v <%v> %v", + l.Time.UTC().Format(time.Kitchen), + l.Nick, l.Text) + } + }) +} diff --git a/main.go b/main.go index 79fd538..82940ff 100644 --- a/main.go +++ b/main.go @@ -1,77 +1,23 @@ package main import ( - "container/ring" "flag" "fmt" "log" - "time" + "strings" irc "github.com/fluffle/goirc/client" ) -type bot struct { - room string - conn *irc.Conn - notice chan string - kick chan string - last *ring.Ring -} - -func New(name, node, room string, ssl bool) *bot { - conf := irc.NewConfig(name) - conf.Server = node - conf.SSL = ssl - conn := irc.Client(conf) - return &bot{ - room: room, - conn: conn, - notice: notify(conn, room), - kick: kicker(conn, room), - last: ring.New(10), - } -} - -func (b *bot) push(line *irc.Line) { - b.last.Value = line - b.last = b.last.Next() -} - -func (b *bot) find(c chan string, nick string) { - var msg string - b.last.Do(func(v interface{}) { - if v != nil { - l := v.(*irc.Line) - if l.Nick == nick { - msg = l.Text() - } - } - }) - if msg != "" { - c <- msg - } -} - -func (b *bot) lastMsgs(c chan string) { - b.last.Do(func(v interface{}) { - if v != nil { - l := v.(*irc.Line) - c <- fmt.Sprintf("%v <%v> %v", - l.Time.UTC().Format(time.Kitchen), - l.Nick, l.Text()) - } - }) -} - func notify(conn *irc.Conn, target string) chan string { const maxLen = 500 c := make(chan string, 1) go func() { for msg := range c { - log.Println("send", msg) if len(msg) > maxLen { msg = msg[:maxLen] + "..." } + log.Println("send", msg) conn.Notice(target, msg) } }() @@ -91,9 +37,9 @@ func kicker(conn *irc.Conn, channel string) chan string { return c } -func (b *bot) join() irc.HandlerFunc { +func join(room string) irc.HandlerFunc { return func(conn *irc.Conn, _ *irc.Line) { - conn.Join(b.room) + conn.Join(room) } } @@ -103,23 +49,30 @@ func discon(c chan struct{}) irc.HandlerFunc { } } -func (b *bot) privmsg() irc.HandlerFunc { - l := links(b.notice) +func privmsg(note, kick chan string) irc.HandlerFunc { + last := NewLastBuf(10) + links := linker(note) + go Watch(note, Feeds) return func(conn *irc.Conn, line *irc.Line) { - if isFlood(line.Text()) { - b.kick <- line.Nick - } - switch line.Text() { - case "last": + switch t := line.Text(); { + case isFlood(t): + kick <- line.Nick + case t == "last": c := notify(conn, line.Nick) - defer close(c) - b.lastMsgs(c) - case "find": - b.find(b.notice, line.Nick) + last.Dump(c) + close(c) + case strings.HasPrefix(t, "s"): + tofix := last.Last(line.Nick) + if fixed := re(tofix, t); fixed != "" { + note <- fmt.Sprintf("%v meant to say: %v", + line.Nick, fixed) + return + } + fallthrough default: - b.push(line) + links <- t + last.Push(line.Time, line.Nick, t) } - l <- line.Text() } } @@ -130,30 +83,23 @@ func main() { name := flag.String("name", "dim13", "Bots Name") flag.Parse() - b := New(*name, *node, *room, *ssl) + conf := irc.NewConfig(*name) + conf.Server = *node + conf.SSL = *ssl + conn := irc.Client(conf) + + note := notify(conn, *room) + kick := kicker(conn, *room) done := make(chan struct{}) - go Watch(b.notice, Feeds) // TODO shall it be there? - // setup event handler - handler := []struct { - ev string - f irc.HandlerFunc - }{ - {irc.DISCONNECTED, discon(done)}, - {irc.CONNECTED, b.join()}, - {irc.KICK, b.join()}, - {irc.PRIVMSG, b.privmsg()}, - } - for _, h := range handler { - b.conn.HandleFunc(h.ev, h.f) - } + conn.HandleFunc(irc.DISCONNECTED, discon(done)) + conn.HandleFunc(irc.CONNECTED, join(*room)) + conn.HandleFunc(irc.KICK, join(*room)) + conn.HandleFunc(irc.PRIVMSG, privmsg(note, kick)) - if err := b.conn.Connect(); err != nil { + if err := conn.Connect(); err != nil { log.Fatal(err) } - - log.Println("Connected") <-done - log.Println("Disconnected") } -- cgit v1.2.3