Skip to content

Instantly share code, notes, and snippets.

@apeace
Created April 22, 2014 03:28
Show Gist options
  • Save apeace/11164494 to your computer and use it in GitHub Desktop.
Save apeace/11164494 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
irc "github.com/fluffle/goirc/client"
"github.com/janne/go-lisp/lisp"
"log"
"os"
"os/signal"
"regexp"
"strconv"
)
const (
HOSTNAME = "dickson.freenode.net"
PORT = 6697
USE_SSL = true
NICK = "idled"
CHANNEL = "???"
DEBUG = false
)
func main() {
// TODO why is this not a const D:
MASTERS := []string{"apeace", "???"}
host := HOSTNAME + ":" + strconv.Itoa(PORT)
Log("Connecting to %s", host)
Log("Nick is %s", NICK)
client := irc.SimpleClient(NICK)
client.SSL = USE_SSL
client.AddHandler(irc.CONNECTED, LinePipe(
LogLine,
func(conn *irc.Conn, line *irc.Line) {
conn.Join(CHANNEL)
},
))
client.AddHandler("PING", LogLine)
ProcessCommand := func(conn *irc.Conn, cmd string, respondTo string, respondLabel string) {
Log("Command (%s): %s", respondTo, cmd)
response, err := lisp.EvalString(cmd)
if err != nil {
errStr := fmt.Sprintf("Error! %+v", err)
Log(errStr)
conn.Privmsg(respondTo, respondLabel+": "+errStr)
return
}
responseStr := fmt.Sprintf("%s", response)
Log("Response (%s): %s", respondTo, responseStr)
conn.Privmsg(respondTo, respondLabel+": "+responseStr)
}
ParseLine := func(conn *irc.Conn, line *irc.Line, respondTo string) {
commandMatch, err := regexp.MatchString("^"+NICK+": ", line.Args[1])
if err != nil {
commandMatch = false
Log("Error! %+v", err)
}
if commandMatch {
ProcessCommand(conn, line.Args[1][len(NICK)+2:], respondTo, line.Nick)
}
}
client.AddHandler("PRIVMSG", LinePipe(
LogLine,
func(conn *irc.Conn, line *irc.Line) {
isFromMaster := stringSliceContains(MASTERS, line.Nick) && len(line.Args) == 2
if !isFromMaster {
return
}
if line.Args[0] == CHANNEL {
ParseLine(conn, line, line.Args[0])
return
}
if line.Args[0] == NICK {
ParseLine(conn, line, line.Nick)
return
}
},
))
disconnected := make(chan bool)
client.AddHandler(irc.DISCONNECTED, LinePipe(
LogLine,
func(conn *irc.Conn, line *irc.Line) {
disconnected <- true
},
))
killed := make(chan os.Signal)
signal.Notify(killed, os.Kill, os.Interrupt)
err := client.Connect(host)
if err != nil {
Log("Connection error: %s", err)
Exit()
}
var reason string
select {
case <-disconnected:
reason = "disconnect"
case <-killed:
reason = "killed"
}
Log("Quitting due to %s", reason)
Exit()
}
func LinePipe(f ...func(*irc.Conn, *irc.Line)) func(*irc.Conn, *irc.Line) {
return func(conn *irc.Conn, line *irc.Line) {
for _, handler := range f {
handler(conn, line)
}
}
}
func LogLine(conn *irc.Conn, line *irc.Line) {
Debug("%+v", line)
}
func Log(format string, v ...interface{}) {
log.Printf(format, v...)
}
func Debug(format string, v ...interface{}) {
if DEBUG {
log.Printf(format, v...)
}
}
func Exit() {
Log("Exiting")
os.Exit(0)
}
func stringSliceContains(slice []string, search string) bool {
for _, v := range slice {
if v == search {
return true
}
}
return false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment