From 4db4bdb5343b184e0d905670219e9bdfbfafb726 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 6 Jul 2015 22:32:44 +0200 Subject: Initial import --- lor.go | 17 ++++++++ main.go | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ weather.go | 33 ++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 lor.go create mode 100644 main.go create mode 100644 weather.go diff --git a/lor.go b/lor.go new file mode 100644 index 0000000..011d03a --- /dev/null +++ b/lor.go @@ -0,0 +1,17 @@ +package main + +import "dim13.org/rss" + +const newsRss = `https://www.linux.org.ru/section-rss.jsp?section=1` + +func FetchNews(n int) (s []string) { + news, _ := rss.Fetch(newsRss) + items := news.Channel.Items + if n > 0 { + items = items[:n] + } + for _, i := range items { + s = append(s, i.Title) + } + return +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..1517f2d --- /dev/null +++ b/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "container/ring" + "fmt" + "log" + "strconv" + "strings" + "time" + + "dim13.org/theo" + "github.com/thoj/go-ircevent" +) + +const ( + server = "irc.rusnet.org.ru:6660" + room = "#lor" + name = "theo" +) + +var ( + buffer = ring.New(10) + cmds = make(map[string]CmdFn) + dscr []string + lastNews time.Time +) + +type CmdFn func(*irc.Event, []string) + +func last(e *irc.Event, _ []string) { + conn := e.Connection + nick := e.Nick + buffer.Do(func(v interface{}) { + if v != nil { + ev := v.(*irc.Event) + conn.Privmsgf(nick, "%v: %v", ev.Nick, ev.Message()) + } + }) +} + +func metar(e *irc.Event, arg []string) { + conn := e.Connection + metar, err := FetchMetar(arg[0]) + if err != nil { + conn.Privmsg(room, err.Error()) + } else { + conn.Privmsg(room, metar[1]) + } +} + +func help(e *irc.Event, _ []string) { + for _, m := range dscr { + e.Connection.Privmsg(room, m) + } +} + +func news(e *irc.Event, arg []string) { + conn := e.Connection + n := 5 + if len(arg) > 0 { + i, err := strconv.Atoi(arg[0]) + if err == nil { + n = i + } + } + if time.Since(lastNews) > time.Minute { + for _, n := range FetchNews(n) { + conn.Privmsg(room, n) + lastNews = time.Now() + } + } else { + conn.Privmsg(room, e.Nick+", me just said it") + } +} + +func register(cmd string, f func(*irc.Event, []string), help string) { + cmds[cmd] = f + h := fmt.Sprintf("!%v %v", cmd, help) + dscr = append(dscr, h) +} + +func privmsg(e *irc.Event) { + conn := e.Connection + msg := e.Message() + nick := e.Nick + + log.Println(nick, msg) + + switch msg[0] { + case '!': + arg := strings.Fields(msg[1:]) + if cmd, ok := cmds[arg[0]]; ok { + go cmd(e, arg[1:]) + } + default: + if strings.Contains(msg, name) { + conn.Privmsg(room, theo.Theo()) + } + buffer.Value = e + buffer = buffer.Next() + } +} + +func init() { + register("last", last, "shows last 10 messages") + register("metar", metar, " shows weather report") + register("help", help, "shows this message") + register("top", news, "shows top 10 news") +} + +// 001 Welcome +// 332 Topic +// 333 Unix Time +// 353 Names list +// 366 End of NAMES List +// JOIN +// CTCP_ACTION /me +// PRIVMSG + +func main() { + con := irc.IRC(name, name) + err := con.Connect(server) + if err != nil { + log.Fatal(err) + } + con.AddCallback("001", func(e *irc.Event) { + e.Connection.Join(room) + log.Println("joined", room) + }) + con.AddCallback("PRIVMSG", privmsg) + con.Loop() +} diff --git a/weather.go b/weather.go new file mode 100644 index 0000000..ed4a139 --- /dev/null +++ b/weather.go @@ -0,0 +1,33 @@ +package main + +import ( + "io/ioutil" + "net/http" + "strings" + "errors" +) + +const ( + noaa = `http://weather.noaa.gov/pub/data/observations/metar/` + noaaDecoded = noaa + `decoded/` + noaaStations = noaa + `stations/` +) + +var notFound = errors.New("not found") + +func FetchMetar(s string) ([]string, error) { + loc := noaaStations + strings.ToUpper(s[:4]) + ".TXT" + resp, err := http.Get(loc) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusNotFound { + return nil, notFound + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return strings.Split(strings.TrimSpace(string(body)), "\n"), nil +} -- cgit v1.2.3