summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/feeds/rss.go19
-rw-r--r--internal/flood/flood.go20
-rw-r--r--internal/flood/flood_test.go2
-rw-r--r--internal/href/href.go34
-rw-r--r--internal/href/href_test.go2
-rw-r--r--internal/re/re.go28
6 files changed, 89 insertions, 16 deletions
diff --git a/internal/feeds/rss.go b/internal/feeds/rss.go
index f3dd39c..4386c57 100644
--- a/internal/feeds/rss.go
+++ b/internal/feeds/rss.go
@@ -3,7 +3,6 @@ package feeds
import (
"fmt"
"io"
- "log"
"time"
"dim13.org/rss"
@@ -31,19 +30,17 @@ func (n news) String() string {
return s
}
-func (f Feed) Watch(w io.Writer) {
+func (f Feed) watch(w io.Writer) {
ticker := time.NewTicker(f.Every)
defer ticker.Stop()
for t := range ticker.C {
r, err := rss.Fetch(f.URL)
- if err != nil {
- log.Println(f.Name, err)
- return
- }
- last := t.Add(-f.Every)
- for _, i := range r.Channel.Items {
- if i.PubDate.After(last) {
- fmt.Fprint(w, news{f, i})
+ if err == nil {
+ last := t.Add(-f.Every)
+ for _, i := range r.Channel.Items {
+ if i.PubDate.After(last) {
+ fmt.Fprint(w, news{f, i})
+ }
}
}
}
@@ -51,6 +48,6 @@ func (f Feed) Watch(w io.Writer) {
func Watch(w io.Writer, feeds []Feed) {
for _, feed := range feeds {
- go feed.Watch(w)
+ go feed.watch(w)
}
}
diff --git a/internal/flood/flood.go b/internal/flood/flood.go
index b8a71d1..b16b948 100644
--- a/internal/flood/flood.go
+++ b/internal/flood/flood.go
@@ -14,6 +14,24 @@ const (
black = "\u24B6\u262D\u272F\u262E\u2721\u5350\u534D\u2719\u0FD5\u0FD6\u16CB\uA5A6\u0FD7\u0FD8"
)
+type Kicker interface {
+ Kick(nick string, message ...string)
+}
+
+type Checker struct {
+ k Kicker
+}
+
+func New(k Kicker) *Checker {
+ return &Checker{k: k}
+}
+
+func (c Checker) Check(text, nick string) {
+ if isFlood(text) {
+ c.k.Kick(nick)
+ }
+}
+
func entropy(s string) (e float64) {
n := make(map[rune]float64)
for _, r := range s {
@@ -25,7 +43,7 @@ func entropy(s string) (e float64) {
return e
}
-func Is(s string) bool {
+func isFlood(s string) bool {
if strings.ContainsAny(s, black) {
return true
}
diff --git a/internal/flood/flood_test.go b/internal/flood/flood_test.go
index c16da7c..a09a3c4 100644
--- a/internal/flood/flood_test.go
+++ b/internal/flood/flood_test.go
@@ -20,7 +20,7 @@ func TestFlood(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.line, func(t *testing.T) {
- if Is(tc.line) != tc.ok {
+ if isFlood(tc.line) != tc.ok {
t.Errorf("want %v", tc.ok)
}
})
diff --git a/internal/href/href.go b/internal/href/href.go
index d134f67..f224d27 100644
--- a/internal/href/href.go
+++ b/internal/href/href.go
@@ -3,12 +3,14 @@ package href
import (
"context"
"errors"
+ "fmt"
"io"
"net/http"
"strings"
"time"
"unicode/utf8"
+ lru "github.com/hashicorp/golang-lru"
"golang.org/x/net/html"
"golang.org/x/net/html/charset"
)
@@ -23,6 +25,34 @@ var (
const maxLength = 10 * 1024 * 1024 // 10MB
+type Titles struct {
+ cache *lru.Cache
+ w io.Writer
+}
+
+func NewTitles(w io.Writer) *Titles {
+ cache, _ := lru.New(100)
+ return &Titles{cache: cache, w: w}
+}
+
+func (t *Titles) Resolve(text string) {
+ for _, v := range parseLinks(text) {
+ if v == "" {
+ continue
+ }
+ title, ok := t.cache.Get(v)
+ if ok {
+ fmt.Fprintf(t.w, "Title: %v (cached)", title)
+ continue
+ }
+ title, err := fetch(v)
+ if err == nil {
+ t.cache.Add(v, title)
+ fmt.Fprintf(t.w, "Title: %v", title)
+ }
+ }
+}
+
func title(r io.Reader) (string, error) {
var inTitle bool
z := html.NewTokenizer(r)
@@ -51,7 +81,7 @@ func title(r io.Reader) (string, error) {
return "", errNoTitle
}
-func Title(uri string) (string, error) {
+func fetch(uri string) (string, error) {
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return "", err
@@ -86,7 +116,7 @@ func Title(uri string) (string, error) {
return title(r)
}
-func Links(s string) (ret []string) {
+func parseLinks(s string) (ret []string) {
for _, v := range strings.Fields(s) {
switch {
case strings.HasPrefix(v, "www."):
diff --git a/internal/href/href_test.go b/internal/href/href_test.go
index ed2bc40..7f5de3f 100644
--- a/internal/href/href_test.go
+++ b/internal/href/href_test.go
@@ -51,7 +51,7 @@ func TestTitle(t *testing.T) {
io.Copy(w, fd)
}))
defer ts.Close()
- title, err := Title(ts.URL)
+ title, err := fetch(ts.URL)
if err != nil {
t.Error(tc.fixture, err)
}
diff --git a/internal/re/re.go b/internal/re/re.go
index b235282..f7e9543 100644
--- a/internal/re/re.go
+++ b/internal/re/re.go
@@ -2,12 +2,40 @@ package re
import (
"errors"
+ "fmt"
+ "io"
"regexp"
"strings"
+
+ lru "github.com/hashicorp/golang-lru"
)
var errNotRE = errors.New("not re")
+type RE struct {
+ last *lru.Cache
+ w io.Writer
+}
+
+func NewRE(w io.Writer) *RE {
+ last, _ := lru.New(100)
+ return &RE{last: last, w: w}
+}
+
+func (r *RE) Replace(text, nick string) {
+ defer r.last.Add(nick, text)
+ if !strings.HasPrefix(text, "s") {
+ return
+ }
+ if tofix, ok := r.last.Get(nick); ok {
+ global := strings.HasSuffix(text, "g")
+ fixed, err := Replace(tofix.(string), text[1:], global)
+ if err == nil && fixed != tofix {
+ fmt.Fprintf(r.w, "%v meant to say: %s", nick, fixed)
+ }
+ }
+}
+
func Replace(s, r string, global bool) (string, error) {
// min: at least two separators
if len(r) < 2 {