From 2700844318c370fda20bb39327620014d27dddf0 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 11 Jul 2015 20:02:57 +0200 Subject: Readd top10 --- main.go | 35 ++++++++---------------- score.go | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ top/main.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 24 deletions(-) create mode 100644 score.go create mode 100644 top/main.go 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) +} -- cgit v1.2.3