summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-12-25 14:31:37 +0100
committerDimitri Sokolyuk <demon@dim13.org>2016-12-25 14:31:37 +0100
commit1c780ab0000890760bc923fc9322dd8462e83fa1 (patch)
tree8e58d997b1d09eeee20330d470ed3bd40a7a6ab8
parentb6158fe79d01268a0033c2b220f1a104193290a4 (diff)
Split last
-rw-r--r--href.go8
-rw-r--r--last.go49
-rw-r--r--main.go126
3 files changed, 89 insertions, 94 deletions
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")
}