Rework of module system.

This commit is contained in:
Andreas Neue 2016-02-16 00:17:42 +01:00
parent 69e8ef85b1
commit ae56ff904c
12 changed files with 219 additions and 199 deletions

41
main.go
View File

@ -16,15 +16,8 @@ import (
"github.com/nickvanw/ircx"
"github.com/sorcix/irc"
"flokatirc/modules"
"flokatirc/version"
modfortune "flokatirc/modules/fortune"
modrss "flokatirc/modules/rss"
modsaytime "flokatirc/modules/saytime"
modsc "flokatirc/modules/sc"
modstoll "flokatirc/modules/stoll"
modtwitch "flokatirc/modules/twitch"
modweather "flokatirc/modules/weather"
)
var (
@ -33,7 +26,7 @@ var (
channels = flag.String("chan", "#test", "Channels to join")
nsname = flag.String("nsname", "NickServ", "NickServ name")
nspass = flag.String("nspass", "", "NickServ password")
modules = flag.String("modules", "rss,starcitizen,fortune,saytime", "Module list, comma separated")
params = flag.String("params", "", "Module params")
)
func init() {
@ -59,28 +52,7 @@ func main() {
//mods := strings.Split(*modules, ",")
//TODO: implement more robust list parsing
//XXX: this sucks
if strings.Contains(*modules, "rss") {
go modrss.Init(sayCh, "newsfeeds.conf")
}
if strings.Contains(*modules, "starcitizen") {
go modsc.Init(sayCh)
}
if strings.Contains(*modules, "fortune") {
go modfortune.Init(sayCh)
}
if strings.Contains(*modules, "stoll") {
go modstoll.Init(sayCh)
}
if strings.Contains(*modules, "saytime") {
go modsaytime.Init(sayCh)
}
if strings.Contains(*modules, "twitch") {
go modtwitch.Init(sayCh)
}
if strings.Contains(*modules, "weather") {
go modweather.Init(sayCh)
}
modules.Initialize(sayCh)
go func() {
for {
@ -150,12 +122,7 @@ func PingHandler(s ircx.Sender, m *irc.Message) {
func PrivmsgHandler(s ircx.Sender, m *irc.Message) {
//TODO: implement message handler table
HandleMessage(m)
modsc.HandleMessage(m)
modfortune.HandleMessage(m)
modstoll.HandleMessage(m)
modsaytime.HandleMessage(m)
modtwitch.HandleMessage(m)
modweather.HandleMessage(m)
modules.HandleMessage(m)
}
func HandleMessage(m *irc.Message) {

View File

@ -1,6 +1,6 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
package announcements
package modules
import (
"log"
@ -9,16 +9,14 @@ import (
"github.com/sorcix/irc"
)
var (
sayCh chan string
)
var ()
func Init(ch chan string) {
func init() {
msgHandlers["announcements"] = anncouncementsHandleMessage
log.Println("Initializing announcements module")
sayCh = ch
}
func HandleMessage(m *irc.Message) {
func anncouncementsHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return

57
modules/coffee.go Normal file
View File

@ -0,0 +1,57 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
//
// flokatirc coffee module
//
// Copyright (c) 2016 Daniel Aberger <da@ixab.de>
package modules
import (
"log"
"strings"
"time"
"github.com/sorcix/irc"
)
func init() {
msgHandlers["coffee"] = coffeeHandleMessage
log.Println("Initializing coffee module")
}
func coffeeHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
}
switch tok[0] {
case "!kaffee":
switch len(tok) {
case 1:
go coffeeMake(nil)
default:
go coffeeMake(tok[1:])
}
default:
}
}
func coffeeMake(rec []string) {
sayCh <- "*\nsetzt Kaffee auf."
time.Sleep(30 * time.Second)
sayCh <- "*\nstellt eine frische Kanne Kaffee in den Raum."
if rec != nil {
var users string
for i, v := range rec {
users += v
if i < len(rec)-2 {
users += ", "
} else if i == len(rec)-2 {
users += " und "
}
}
sayCh <- "*\ngibt " + users + " einen frischen, richtig schwarzen, richtig leckeren Kaffee."
}
time.Sleep(10 * time.Second)
sayCh <- "*\nProst! (c)"
}

View File

@ -1,6 +1,6 @@
// vim:ts=4:sts=4:sw=4:noet:tw=72
package fortune
package modules
import (
"bytes"
@ -12,16 +12,12 @@ import (
"github.com/sorcix/irc"
)
var (
sayCh chan string
)
func Init(ch chan string) {
func init() {
msgHandlers["fortune"] = fortuneHandleMessage
log.Println("Initializing fortune module")
sayCh = ch
}
func HandleMessage(m *irc.Message) {
func fortuneHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return

84
modules/fuzzytime.go Normal file
View File

@ -0,0 +1,84 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
package modules
import (
"fmt"
"log"
"strings"
"time"
"github.com/sorcix/irc"
)
func init() {
msgHandlers["fuzzytime"] = fuzzytimeHandleMessage
log.Println("Initializing fuzzytime module")
}
func fuzzytimeHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
}
switch tok[0] {
case "!time":
fuzzytimeShow()
//case "!q":
// show()
default:
}
}
func fuzzytimeShow() {
log.Println("timeshow")
t := time.Now()
h := t.Hour()
tzcorrect := 1
h = h + tzcorrect // XXX: This should not be hardcoded
m := t.Minute()
s := "Es ist "
switch {
case m < 3:
s += fmt.Sprintf("%s Uhr\n", fuzzytimeSayHour(h))
case m < 8:
s += fmt.Sprintf("fünf nach %s\n", fuzzytimeSayHour(h))
case m < 13:
s += fmt.Sprintf("zehn nach %s\n", fuzzytimeSayHour(h))
case m < 18:
s += fmt.Sprintf("viertel nach %s\n", fuzzytimeSayHour(h))
case m < 23:
s += fmt.Sprintf("zwanzig nach %s\n", fuzzytimeSayHour(h))
case m < 28:
s += fmt.Sprintf("fünf vor halb %s\n", fuzzytimeSayHour(h+1))
case m < 33:
s += fmt.Sprintf("halb %s\n", fuzzytimeSayHour(h+1))
case m < 38:
s += fmt.Sprintf("fünf nach halb %s\n", fuzzytimeSayHour(h+1))
case m < 43:
s += fmt.Sprintf("zehn nach halb %s\n", fuzzytimeSayHour(h+1))
case m < 48:
s += fmt.Sprintf("viertel vor %s\n", fuzzytimeSayHour(h+1))
case m < 53:
s += fmt.Sprintf("zehn vor %s\n", fuzzytimeSayHour(h+1))
case m < 58:
s += fmt.Sprintf("fünf vor %s\n", fuzzytimeSayHour(h+1))
default:
s += fmt.Sprintf("%s Uhr\n", fuzzytimeSayHour(h+1))
}
log.Println("saying now:", s)
sayCh <- fmt.Sprintf("*\n%s", s)
}
func fuzzytimeSayHour(h int) string {
words := [...]string{"zwölf", "eins", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn", "elf"}
for {
if h > 11 {
h = h - 12
} else {
break
}
}
return words[h]
}

View File

@ -4,7 +4,7 @@
// and is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
// license.
package rss
package modules
import (
"bufio"
@ -17,14 +17,15 @@ import (
gorss "github.com/jteeuwen/go-pkg-rss"
"github.com/jteeuwen/go-pkg-xmlx"
"github.com/sorcix/irc"
)
var sayCh chan string
var hideOutput = true
func Init(ch chan string, path string) {
func init() {
msgHandlers["rss"] = rssHandleMessage
log.Printf("Initializing news module")
sayCh = ch
path := "newsfeeds.conf"
file, err := os.Open(path)
if err != nil {
log.Fatal(err)
@ -32,17 +33,22 @@ func Init(ch chan string, path string) {
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
go PollFeed(scanner.Text(), 5, charsetReader)
go rssPollFeed(scanner.Text(), 5, rssCharsetReader)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
go func() {
time.Sleep(60 * time.Second)
hideOutput = false
}()
}
func PollFeed(uri string, timeout int, cr xmlx.CharsetFunc) {
feed := gorss.New(timeout, true, chanHandler, itemHandler)
func rssHandleMessage(m *irc.Message) {
}
func rssPollFeed(uri string, timeout int, cr xmlx.CharsetFunc) {
feed := gorss.New(timeout, true, rssChanHandler, rssItemHandler)
for {
log.Printf("Polling feed: %s", uri)
if err := feed.Fetch(uri, cr); err != nil {
@ -54,11 +60,11 @@ func PollFeed(uri string, timeout int, cr xmlx.CharsetFunc) {
}
}
func chanHandler(feed *gorss.Feed, newchannels []*gorss.Channel) {
func rssChanHandler(feed *gorss.Feed, newchannels []*gorss.Channel) {
sayCh <- fmt.Sprintf("%s\n[RSS] %d new channel(s) in %s", "*", len(newchannels), feed.Url)
}
func itemHandler(feed *gorss.Feed, ch *gorss.Channel, newitems []*gorss.Item) {
func rssItemHandler(feed *gorss.Feed, ch *gorss.Channel, newitems []*gorss.Item) {
if hideOutput {
return
}
@ -67,7 +73,7 @@ func itemHandler(feed *gorss.Feed, ch *gorss.Channel, newitems []*gorss.Item) {
}
}
func charsetReader(charset string, r io.Reader) (io.Reader, error) {
func rssCharsetReader(charset string, r io.Reader) (io.Reader, error) {
if charset == "ISO-8859-1" || charset == "iso-8859-1" {
return r, nil
}

View File

@ -1,84 +0,0 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
package sc
import (
"fmt"
"log"
"strings"
"time"
"github.com/sorcix/irc"
)
var sayCh chan string
func Init(ch chan string) {
log.Println("Initializing saytime module")
sayCh = ch
}
func HandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
}
switch tok[0] {
case "!time":
show()
//case "!q":
// show()
default:
}
}
func show() {
t := time.Now()
h := t.Hour()
tzcorrect := 1
h = h + tzcorrect
m := t.Minute()
s := "Es ist "
switch {
case m < 3:
s += fmt.Sprintf("%s Uhr\n", sayhour(h))
case m < 8:
s += fmt.Sprintf("fünf nach %s\n", sayhour(h))
case m < 13:
s += fmt.Sprintf("zehn nach %s\n", sayhour(h))
case m < 18:
s += fmt.Sprintf("viertel nach %s\n", sayhour(h))
case m < 23:
s += fmt.Sprintf("zwanzig nach %s\n", sayhour(h))
case m < 28:
s += fmt.Sprintf("fünf vor halb %s\n", sayhour(h+1))
case m < 33:
s += fmt.Sprintf("halb %s\n", sayhour(h+1))
case m < 38:
s += fmt.Sprintf("fünf nach halb %s\n", sayhour(h+1))
case m < 43:
s += fmt.Sprintf("zehn nach halb %s\n", sayhour(h+1))
case m < 48:
s += fmt.Sprintf("viertel vor %s\n", sayhour(h+1))
case m < 53:
s += fmt.Sprintf("zehn vor %s\n", sayhour(h+1))
case m < 58:
s += fmt.Sprintf("fünf vor %s\n", sayhour(h+1))
default:
s += fmt.Sprintf("%s Uhr\n", sayhour(h+1))
}
sayCh <- fmt.Sprintf("*\n%s", s)
}
func sayhour(h int) string {
words := [...]string{"zwölf", "eins", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn", "elf"}
for {
if h > 11 {
h = h - 12
} else {
break
}
}
return words[h]
}

View File

@ -1,6 +1,6 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
package sc
package modules
import (
"encoding/json"
@ -11,7 +11,6 @@ import (
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"time"
@ -42,19 +41,18 @@ const (
)
var (
sayCh chan string
fans = 0
fleet = 0
funds = 0
)
func Init(ch chan string) {
func init() {
msgHandlers["sc"] = scHandleMessage
log.Println("Initializing sc module")
sayCh = ch
go scrapeLoop()
go scScrapeLoop()
}
func HandleMessage(m *irc.Message) {
func scHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
@ -74,28 +72,14 @@ func HandleMessage(m *irc.Message) {
}
}
func toInt(v interface{}) int {
switch v.(type) {
case int:
return v.(int)
case float64:
return int(v.(float64))
case string:
ret, _ := strconv.Atoi(v.(string))
return ret
default:
return 0
}
}
func scrapeLoop() {
func scScrapeLoop() {
for {
scraper()
scScraper()
time.Sleep(1 * time.Minute)
}
}
func scraper() {
func scScraper() {
var data interface{}
log.Println("Scraping SC stats")
@ -118,9 +102,9 @@ func scraper() {
}
stats := data.(map[string]interface{})["data"].(map[string]interface{})
//fmt.Println(stats["fans"].(type))
curFans := toInt(stats["fans"])
curFleet := toInt(stats["fleet"])
curFunds := toInt(stats["funds"]) / 100
curFans := util.ToInt(stats["fans"])
curFleet := util.ToInt(stats["fleet"])
curFunds := util.ToInt(stats["funds"]) / 100
nextFans := ((fans / FANS_INT) * FANS_INT) + FANS_INT
nextFleet := ((fleet / FLEET_INT) * FLEET_INT) + FLEET_INT

View File

@ -1,12 +1,11 @@
// vi:ts=4:sts=4:sw=4:noet:tw=72
package stoll
package modules
import (
"flokatirc/util"
"fmt"
"math/rand"
"strings"
"time"
"github.com/sorcix/irc"
)
@ -520,13 +519,11 @@ var quotes = [][]string{
},
}
var sayCh chan string
func Init(ch chan string) {
sayCh = ch
func init() {
msgHandlers["stoll"] = stollHandleMessage
}
func HandleMessage(m *irc.Message) {
func stollHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
@ -534,15 +531,10 @@ func HandleMessage(m *irc.Message) {
if tok[0] == "!stoll" {
line := ""
for i := 0; i < 3; i++ {
line += quotes[i][random(0, len(quotes[i]))]
line += quotes[i][util.Random(0, len(quotes[i]))]
line += " "
}
line += "[Dr. Axel Stoll, promovierter Naturwissenschaftler]"
sayCh <- fmt.Sprintf("%s\n%s", "*", line)
}
}
func random(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}

View File

@ -4,7 +4,7 @@
//
// Copyright (c) 2016 Daniel Aberger <da@ixab.de>
package twitch
package modules
import (
"encoding/json"
@ -118,7 +118,6 @@ type TwitchStreamObject struct {
}
var (
sayCh chan string
twitch = map[string]bool{
"rocketbeanstv": false,
"scnr_onair": false,
@ -136,13 +135,13 @@ var (
twitchapiurlchannels = "https://api.twitch.tv/kraken/channels/"
)
func Init(ch chan string) {
func init() {
msgHandlers["twitch"] = twitchHandleMessage
log.Println("Initializing twitch module")
sayCh = ch
go pollStreamData()
}
func HandleMessage(m *irc.Message) {
func twitchHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return

View File

@ -4,7 +4,7 @@
//
// Copyright (c) 2016 Daniel Aberger <da@ixab.de>
package weather
package modules
import (
"encoding/json"
@ -19,7 +19,6 @@ import (
)
var (
sayCh chan string
owmQueryAPIKey = ""
owmQueryURLPrefix = "http://api.openweathermap.org/data/2.5/weather?q="
owmQueryURLSuffix = "&appid="
@ -69,12 +68,12 @@ type WeatherObject struct {
} `json:"wind"`
}
func Init(ch chan string) {
func init() {
msgHandlers["weather"] = weatherHandleMessage
log.Println("Initializing weather module")
sayCh = ch
}
func HandleMessage(m *irc.Message) {
func weatherHandleMessage(m *irc.Message) {
tok := strings.Split(m.Trailing, " ")
if len(tok) < 1 {
return
@ -94,6 +93,7 @@ func HandleMessage(m *irc.Message) {
default:
}
}
func getWeather(query string) {
q := owmQueryURLPrefix + query + owmQueryURLSuffix + owmQueryAPIKey
r, err := http.Get(q)

View File

@ -4,9 +4,25 @@ package util
import (
"bytes"
"math/rand"
"strconv"
"time"
)
func ToInt(v interface{}) int {
switch v.(type) {
case int:
return v.(int)
case float64:
return int(v.(float64))
case string:
ret, _ := strconv.Atoi(v.(string))
return ret
default:
return 0
}
}
func NumberToString(n int, sep rune) string {
start := 0
var buf bytes.Buffer
@ -31,3 +47,8 @@ func NumberToString(n int, sep rune) string {
}
return buf.String()
}
func Random(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}