summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go35
-rw-r--r--score.go91
-rw-r--r--top/main.go79
3 files changed, 181 insertions, 24 deletions
diff --git a/main.go b/main.go
index 6c35121..bec3f53 100644
--- a/main.go
+++ b/main.go
@@ -41,7 +41,6 @@ type (
var (
commands = make(map[string]Commander)
- top = make(map[string]int)
buffer = ring.New(10)
)
@@ -77,7 +76,7 @@ func (v RSS) Handle(conn *irc.Conn, line *irc.Line) {
news.Channel.Items = news.Channel.Items[:3]
}
for n, i := range news.Channel.Items {
- s := fmt.Sprintf("%2d. %v", n+1, i.Title)
+ s := fmt.Sprintf("%2d. %v - %v", n+1, i.Title, i.Link)
conn.Privmsg(line.Target(), s)
}
}
@@ -114,22 +113,8 @@ func (_ Metar) Handle(conn *irc.Conn, line *irc.Line) {
}
func (_ Top) Handle(conn *irc.Conn, line *irc.Line) {
- score := make(map[int]string)
- var selector []int
- for nick, lines := range top {
- score[lines] = nick
- selector = append(selector, lines)
- }
- sort.Sort(sort.Reverse(sort.IntSlice(selector)))
- if line.Public() && len(selector) > 10 {
- selector = selector[:10]
- } else if len(selector) > 20 {
- selector = selector[:20]
- }
- for n, lines := range selector {
- s := fmt.Sprintf("%2d. %v (%v)", n+1, score[lines], lines)
- conn.Privmsg(line.Target(), s)
- }
+ s := fmt.Sprint(NewScores())
+ conn.Privmsg(line.Target(), s)
}
func privmsg(conn *irc.Conn, line *irc.Line) {
@@ -138,7 +123,7 @@ func privmsg(conn *irc.Conn, line *irc.Line) {
if line.Public() && line.Nick != conn.Me().Nick {
buffer.Value = line
buffer = buffer.Next()
- top[line.Nick]++
+ Count(line.Nick)
}
// lookup command
@@ -207,12 +192,12 @@ func init() {
Help: "This help",
},
})
+ Register("top", Top{
+ Command{
+ Help: "Top 10 flooder",
+ },
+ })
/*
- Register("top", Top{
- Command{
- Help: "Top 10 flooder",
- },
- })
Register("metar", Metar{
Command{
Help: "Weather (argument: ICAO-Code, msg private for verbose output)",
@@ -238,5 +223,7 @@ func main() {
log.Fatal(err)
}
+ go autoSave()
+
<-quit
}
diff --git a/score.go b/score.go
new file mode 100644
index 0000000..c449c9a
--- /dev/null
+++ b/score.go
@@ -0,0 +1,91 @@
+package main
+
+import (
+ "encoding/gob"
+ "fmt"
+ "log"
+ "os"
+ "sort"
+ "time"
+)
+
+const gobfile = `score.gob`
+
+var score map[string]int
+
+type Score struct {
+ Nick string
+ Count int
+}
+
+type Scores []Score
+
+func (s Scores) Len() int { return len(s) }
+func (s Scores) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s Scores) Less(i, j int) bool { return s[i].Count < s[j].Count }
+
+func NewScores() (s Scores) {
+ for k, v := range score {
+ s = append(s, Score{
+ Nick: k,
+ Count: v,
+ })
+ }
+ sort.Sort(sort.Reverse(s))
+ if len(s) > 10 {
+ s = s[:10]
+ }
+ return
+}
+
+func loadScore() map[string]int {
+ m := make(map[string]int)
+ fd, err := os.Open(gobfile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer fd.Close()
+ decoder := gob.NewDecoder(fd)
+ if err := decoder.Decode(&m); err != nil {
+ log.Fatal(err)
+ }
+ return m
+}
+
+func saveScore(m map[string]int) {
+ fd, err := os.Create(gobfile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer fd.Close()
+ encoder := gob.NewEncoder(fd)
+ if err := encoder.Encode(m); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func (s Score) String() string {
+ return fmt.Sprintf("%v (%v)", s.Nick, s.Count)
+}
+
+func (s Scores) String() (ret string) {
+ for n, sc := range s {
+ ret += fmt.Sprintf("%3d. %v", n+1, sc)
+ }
+ return
+}
+
+func init() {
+ score = loadScore()
+}
+
+func Count(nick string) {
+ score[nick]++
+}
+
+func autoSave() {
+ for {
+ saveScore(score)
+ time.Sleep(time.Minute)
+ }
+}
diff --git a/top/main.go b/top/main.go
new file mode 100644
index 0000000..e5b0737
--- /dev/null
+++ b/top/main.go
@@ -0,0 +1,79 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "os"
+ "regexp"
+ "sort"
+ "encoding/gob"
+)
+
+const (
+ logfile = `/home/demon/irclogs/RusNet/#lor.log`
+ gobfile = `score.gob`
+)
+
+var (
+ re = regexp.MustCompile(`[^ ]+ <.([^ ]+)> .*`)
+ score = make(map[string]int)
+)
+
+type Score struct {
+ Nick string
+ Count int
+}
+
+type Scores []Score
+
+func (s Scores) Len() int { return len(s) }
+func (s Scores) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s Scores) Less(i, j int) bool { return s[i].Count < s[j].Count }
+
+func newScore(m map[string]int) (s Scores) {
+ for k, v := range m {
+ s = append(s, Score{
+ Nick: k,
+ Count: v,
+ })
+ }
+ sort.Sort(sort.Reverse(s))
+ if len(s) > 10 {
+ s = s[:10]
+ }
+ return
+}
+
+func main() {
+ fd, err := os.Open(logfile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer fd.Close()
+
+ scanner := bufio.NewScanner(fd)
+ for scanner.Scan() {
+ m := re.FindAllStringSubmatch(scanner.Text(), -1)
+ if m != nil {
+ user := m[0][1]
+ score[user]++
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ log.Fatal(err)
+ }
+
+ for n, s := range newScore(score) {
+ fmt.Printf("%2d %v (%v)\n", n+1, s.Nick, s.Count)
+ }
+
+ gd, err := os.Create(gobfile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer gd.Close()
+
+ g := gob.NewEncoder(gd)
+ g.Encode(score)
+}