Move commands into cmd-*.go files

This commit is contained in:
raylu 2010-10-26 21:21:51 -04:00
parent 78d5511cf8
commit 2cc4781249
5 changed files with 377 additions and 356 deletions

View File

@ -5,10 +5,7 @@
include $(GOROOT)/src/Make.inc
TARG=rbot
GOFILES=\
rbot.go\
handler.go\
auth.go
GOFILES=rbot.go handler.go auth.go cmd-access.go cmd-op.go cmd-google.go
include $(GOROOT)/src/Make.cmd

85
cmd-access.go Normal file
View File

@ -0,0 +1,85 @@
package main
import (
"irc"
"strings"
)
func add(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "a")
if channel == "" {
return
}
split := strings.Fields(args)
if len(split) != 2 {
return
}
host, nflags := addAccess(conn, channel, split[0], strings.TrimSpace(split[1]))
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else {
say(conn, target, "%s now has flags %s", host, nflags)
}
}
func remove(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "a")
if channel == "" {
return
}
split := strings.Fields(args)
if len(split) == 2 {
host, nflags := removeAccess(conn, channel, split[0], strings.TrimSpace(split[1]))
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else {
say(conn, target, "%s now has flags %s", host, nflags)
}
} else if len(split) == 1 {
host, removed := removeUser(conn, channel, split[0])
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else if removed {
say(conn, target, "Removed %s", host)
} else {
say(conn, target, "%s did not have any flags", host)
}
}
}
func flags(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "")
if channel == "" {
return
}
query := strings.TrimSpace(args)
if query == "" {
query = nick.Nick
}
n := conn.GetNick(query)
if n == nil {
say(conn, target, "Could not find nick %s", query)
return
}
user := user(n)
if owner, _ := auth.String(conn.Network, "owner"); owner == user {
say(conn, target, "%s is the owner", user)
return
}
flags, _ := auth.String(conn.Network + " " + channel, user)
if flags == "" {
say(conn, target, "%s has no flags", user)
} else {
say(conn, target, "%s: %s", user, flags)
}
}
func csay(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "s")
if channel != "" {
say(conn, channel, args)
}
}

81
cmd-google.go Normal file
View File

@ -0,0 +1,81 @@
package main
import (
"irc"
"fmt"
"strings"
"http"
"json"
"io/ioutil"
"container/vector"
"html"
)
const googleAPIKey = "ABQIAAAA6-N_jl4ETgtMf2M52JJ_WRQjQjNunkAJHIhTdFoxe8Di7fkkYhRRcys7ZxNbH3MIy_MKKcEO4-9_Ag"
func translate(conn *irc.Conn, nick *irc.Nick, args, target string) {
var langPairs vector.StringVector
for {
split := strings.Split(args, " ", 2)
if len(split) == 2 && len(split[0]) == 5 && split[0][2] == '|' {
langPairs.Push("&langpair=" + split[0])
args = split[1]
} else {
break
}
}
var url string
if langPairs.Len() > 0 {
// translate
langPairsSlice := []string(langPairs)
url = fmt.Sprintf("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s%s&key=%s",
http.URLEscape(args), strings.Join(langPairsSlice, ""), googleAPIKey)
} else {
// language detect
url = fmt.Sprintf("http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=%s&key=%s",
http.URLEscape(args), googleAPIKey)
}
response, _, err := http.Get(url)
defer response.Body.Close()
if err != nil {
say(conn, target, "%s: Error while requesting translation", nick.Nick); return
}
b, err := ioutil.ReadAll(response.Body)
if err != nil {
say(conn, target, "%s: Error while downloading translation", nick.Nick); return
}
var result map[string]interface{}
err = json.Unmarshal(b, &result)
if err != nil {
say(conn, target, "%s: Error while decoding translation", nick.Nick); return
}
if result["responseStatus"] != float64(200) {
say(conn, target, "%s: %s", nick.Nick, result["responseDetails"]); return
}
if langPairs.Len() > 0 {
// translate
sayTr(conn, target, result["responseData"])
} else {
// language detect
var data map[string]interface{} = result["responseData"].(map[string]interface{})
say(conn, target, "Language: %s, confidence: %f, is reliable: %t", data["language"], data["confidence"], data["isReliable"])
}
}
func sayTr(conn *irc.Conn, target string, data interface{}) {
switch t := data.(type) {
case []interface{}:
var dataList []interface{} = data.([]interface{})
for _, d := range dataList {
var innerData map[string]interface{} = d.(map[string]interface{})
sayTr(conn, target, innerData["responseData"])
}
case map[string]interface{}:
trText := data.(map[string]interface{})["translatedText"].(string)
say(conn, target, html.UnescapeString(trText))
}
}

203
cmd-op.go Normal file
View File

@ -0,0 +1,203 @@
package main
import (
"irc"
"strings"
)
func op(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "o")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "+o " + nick.Nick)
} else {
ops := strings.TrimSpace(args)
count := strings.Count(ops, " ") + 1
modestring := "+" + strings.Repeat("o", count) + " " + ops
conn.Mode(channel, modestring)
}
}
func deop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "o")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "-o " + nick.Nick)
} else {
ops := strings.TrimSpace(args)
count := strings.Count(ops, " ") + 1
modestring := "-" + strings.Repeat("o", count) + " " + ops
conn.Mode(channel, modestring)
}
}
func halfop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "+h " + nick.Nick)
} else {
// giving others +h requires o
if !hasAccess(conn, nick, channel, "o") {
return
}
halfops := strings.TrimSpace(args)
count := strings.Count(halfops, " ") + 1
modestring := "+" + strings.Repeat("h", count) + " " + halfops
conn.Mode(channel, modestring)
}
}
func dehalfop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "-h " + nick.Nick)
} else {
if !hasAccess(conn, nick, channel, "o") {
return
}
halfops := strings.TrimSpace(args)
count := strings.Count(halfops, " ") + 1
modestring := "-" + strings.Repeat("h", count) + " " + halfops
conn.Mode(channel, modestring)
}
}
func kick(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
split := strings.Split(args, " ", 2)
if n := conn.GetNick(split[0]); n == nil ||
(!hasAccess(conn, nick, channel, "o") && hasAccess(conn, n, channel, "oh")) {
// if we only have h, we can't kick people with o or h
return
}
reason := "(" + nick.Nick + ")"
if len(split) == 2 {
reason += " " + split[1]
}
conn.Kick(channel, split[0], reason)
}
func ban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
bans := strings.TrimSpace(args)
split := strings.Fields(bans)
// turn nicks into *!*@host
for i, ban := range(split) {
if strings.Index(ban, "@") != -1 {
// already a host
continue
}
n := conn.GetNick(ban)
if n == nil {
//couldn't find the nick, so just cross our fingers
continue
}
split[i] = "*!*@" + n.Host
}
bans = strings.Join(split, " ")
modestring := "+" + strings.Repeat("b", len(bans)) + " " + bans
conn.Mode(channel, modestring)
}
func unban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
bans := strings.TrimSpace(args)
split := strings.Fields(bans)
for i, ban := range(split) {
if strings.Index(ban, "@") != -1 {
continue
}
n := conn.GetNick(ban)
if n == nil {
continue
}
split[i] = "*!*@" + n.Host
}
bans = strings.Join(split, " ")
modestring := "-" + strings.Repeat("b", len(bans)) + " " + bans
conn.Mode(channel, modestring)
}
func kickban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
split := strings.Split(args, " ", 2)
n := conn.GetNick(split[0])
if n == nil ||
(!hasAccess(conn, nick, channel, "o") && hasAccess(conn, n, channel, "oh")) {
return
}
conn.Mode(channel, "+b *!*@" + n.Host)
reason := "(" + nick.Nick + ")"
if len(split) == 2 {
reason += " " + split[1]
}
conn.Kick(channel, split[0], reason)
}
func topic(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "t")
if channel == "" {
return
}
section := conn.Network + " " + channel
if args != "" {
updateConf(section, "basetopic", args)
conn.Topic(channel, args)
} else {
basetopic, _ := conf.String(section, "basetopic")
say(conn, nick.Nick, "Basetopic: %s", basetopic)
}
}
func appendtopic(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "t")
if channel == "" {
return
}
c := conn.GetChannel(channel)
if c == nil {
say(conn, target, "Error while getting channel information for %s", channel)
return
}
section := conn.Network + " " + channel
basetopic, _ := conf.String(section, "basetopic")
if basetopic == "" || !strings.HasPrefix(c.Topic, basetopic) {
basetopic = c.Topic
say(conn, nick.Nick, "New basetopic: %s", basetopic)
updateConf(section, "basetopic", basetopic)
}
conn.Topic(channel, basetopic + args)
}

View File

@ -5,23 +5,18 @@ import (
"fmt"
"strings"
"http"
"io/ioutil"
"json"
"container/vector"
"html"
"xml"
"strconv"
)
var commands = map [string]func(*irc.Conn, *irc.Nick, string, string) {
"tr": translate,
// access
"flags": flags,
"add": add,
"remove": remove,
"topic": topic,
"appendtopic": appendtopic,
"say": csay,
// op
"halfop": halfop,
"hop": halfop,
"op": op,
@ -35,9 +30,12 @@ var commands = map [string]func(*irc.Conn, *irc.Nick, string, string) {
"unban": unban,
"u": unban,
"kb": kickban,
}
"topic": topic,
"appendtopic": appendtopic,
const googleAPIKey = "ABQIAAAA6-N_jl4ETgtMf2M52JJ_WRQjQjNunkAJHIhTdFoxe8Di7fkkYhRRcys7ZxNbH3MIy_MKKcEO4-9_Ag"
// google
"tr": translate,
}
func handlePrivmsg(conn *irc.Conn, line *irc.Line) {
nick := conn.GetNick(line.Nick)
@ -202,346 +200,3 @@ func parseChannel(target, args string) (string, string) {
}
return channel, args
}
func translate(conn *irc.Conn, nick *irc.Nick, args, target string) {
var langPairs vector.StringVector
for {
split := strings.Split(args, " ", 2)
if len(split) == 2 && len(split[0]) == 5 && split[0][2] == '|' {
langPairs.Push("&langpair=" + split[0])
args = split[1]
} else {
break
}
}
var url string
if langPairs.Len() > 0 {
// translate
langPairsSlice := []string(langPairs)
url = fmt.Sprintf("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s%s&key=%s",
http.URLEscape(args), strings.Join(langPairsSlice, ""), googleAPIKey)
} else {
// language detect
url = fmt.Sprintf("http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=%s&key=%s",
http.URLEscape(args), googleAPIKey)
}
response, _, err := http.Get(url)
defer response.Body.Close()
if err != nil {
say(conn, target, "%s: Error while requesting translation", nick.Nick); return
}
b, err := ioutil.ReadAll(response.Body)
if err != nil {
say(conn, target, "%s: Error while downloading translation", nick.Nick); return
}
var result map[string]interface{}
err = json.Unmarshal(b, &result)
if err != nil {
say(conn, target, "%s: Error while decoding translation", nick.Nick); return
}
if result["responseStatus"] != float64(200) {
say(conn, target, "%s: %s", nick.Nick, result["responseDetails"]); return
}
if langPairs.Len() > 0 {
// translate
sayTr(conn, target, result["responseData"])
} else {
// language detect
var data map[string]interface{} = result["responseData"].(map[string]interface{})
say(conn, target, "Language: %s, confidence: %f, is reliable: %t", data["language"], data["confidence"], data["isReliable"])
}
}
func sayTr(conn *irc.Conn, target string, data interface{}) {
switch t := data.(type) {
case []interface{}:
var dataList []interface{} = data.([]interface{})
for _, d := range dataList {
var innerData map[string]interface{} = d.(map[string]interface{})
sayTr(conn, target, innerData["responseData"])
}
case map[string]interface{}:
trText := data.(map[string]interface{})["translatedText"].(string)
say(conn, target, html.UnescapeString(trText))
}
}
func add(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "a")
if channel == "" {
return
}
split := strings.Fields(args)
if len(split) != 2 {
return
}
host, nflags := addAccess(conn, channel, split[0], strings.TrimSpace(split[1]))
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else {
say(conn, target, "%s now has flags %s", host, nflags)
}
}
func remove(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "a")
if channel == "" {
return
}
split := strings.Fields(args)
if len(split) == 2 {
host, nflags := removeAccess(conn, channel, split[0], strings.TrimSpace(split[1]))
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else {
say(conn, target, "%s now has flags %s", host, nflags)
}
} else if len(split) == 1 {
host, removed := removeUser(conn, channel, split[0])
if host == "" {
say(conn, target, "Could not find nick %s", split[0])
} else if removed {
say(conn, target, "Removed %s", host)
} else {
say(conn, target, "%s did not have any flags", host)
}
}
}
func flags(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "")
if channel == "" {
return
}
query := strings.TrimSpace(args)
if query == "" {
query = nick.Nick
}
n := conn.GetNick(query)
if n == nil {
say(conn, target, "Could not find nick %s", query)
return
}
user := user(n)
if owner, _ := auth.String(conn.Network, "owner"); owner == user {
say(conn, target, "%s is the owner", user)
return
}
flags, _ := auth.String(conn.Network + " " + channel, user)
if flags == "" {
say(conn, target, "%s has no flags", user)
} else {
say(conn, target, "%s: %s", user, flags)
}
}
func topic(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "t")
if channel == "" {
return
}
section := conn.Network + " " + channel
if args != "" {
updateConf(section, "basetopic", args)
conn.Topic(channel, args)
} else {
basetopic, _ := conf.String(section, "basetopic")
say(conn, nick.Nick, "Basetopic: %s", basetopic)
}
}
func appendtopic(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "t")
if channel == "" {
return
}
c := conn.GetChannel(channel)
if c == nil {
say(conn, target, "Error while getting channel information for %s", channel)
return
}
section := conn.Network + " " + channel
basetopic, _ := conf.String(section, "basetopic")
if basetopic == "" || !strings.HasPrefix(c.Topic, basetopic) {
basetopic = c.Topic
say(conn, nick.Nick, "New basetopic: %s", basetopic)
updateConf(section, "basetopic", basetopic)
}
conn.Topic(channel, basetopic + args)
}
func csay(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "s")
if channel != "" {
say(conn, channel, args)
}
}
func op(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "o")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "+o " + nick.Nick)
} else {
ops := strings.TrimSpace(args)
count := strings.Count(ops, " ") + 1
modestring := "+" + strings.Repeat("o", count) + " " + ops
conn.Mode(channel, modestring)
}
}
func deop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "o")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "-o " + nick.Nick)
} else {
ops := strings.TrimSpace(args)
count := strings.Count(ops, " ") + 1
modestring := "-" + strings.Repeat("o", count) + " " + ops
conn.Mode(channel, modestring)
}
}
func halfop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "+h " + nick.Nick)
} else {
// giving others +h requires o
if !hasAccess(conn, nick, channel, "o") {
return
}
halfops := strings.TrimSpace(args)
count := strings.Count(halfops, " ") + 1
modestring := "+" + strings.Repeat("h", count) + " " + halfops
conn.Mode(channel, modestring)
}
}
func dehalfop(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" {
return
}
if args == "" {
conn.Mode(channel, "-h " + nick.Nick)
} else {
if !hasAccess(conn, nick, channel, "o") {
return
}
halfops := strings.TrimSpace(args)
count := strings.Count(halfops, " ") + 1
modestring := "-" + strings.Repeat("h", count) + " " + halfops
conn.Mode(channel, modestring)
}
}
func kick(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
split := strings.Split(args, " ", 2)
if n := conn.GetNick(split[0]); n == nil ||
(!hasAccess(conn, nick, channel, "o") && hasAccess(conn, n, channel, "oh")) {
// if we only have h, we can't kick people with o or h
return
}
reason := "(" + nick.Nick + ")"
if len(split) == 2 {
reason += " " + split[1]
}
conn.Kick(channel, split[0], reason)
}
func ban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
bans := strings.TrimSpace(args)
split := strings.Fields(bans)
// turn nicks into *!*@host
for i, ban := range(split) {
if strings.Index(ban, "@") != -1 {
// already a host
continue
}
n := conn.GetNick(ban)
if n == nil {
//couldn't find the nick, so just cross our fingers
continue
}
split[i] = "*!*@" + n.Host
}
bans = strings.Join(split, " ")
modestring := "+" + strings.Repeat("b", len(bans)) + " " + bans
conn.Mode(channel, modestring)
}
func unban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
bans := strings.TrimSpace(args)
split := strings.Fields(bans)
for i, ban := range(split) {
if strings.Index(ban, "@") != -1 {
continue
}
n := conn.GetNick(ban)
if n == nil {
continue
}
split[i] = "*!*@" + n.Host
}
bans = strings.Join(split, " ")
modestring := "-" + strings.Repeat("b", len(bans)) + " " + bans
conn.Mode(channel, modestring)
}
func kickban(conn *irc.Conn, nick *irc.Nick, args, target string) {
channel, args := parseAccess(conn, nick, target, args, "oh")
if channel == "" || args == "" {
return
}
split := strings.Split(args, " ", 2)
n := conn.GetNick(split[0])
if n == nil ||
(!hasAccess(conn, nick, channel, "o") && hasAccess(conn, n, channel, "oh")) {
return
}
conn.Mode(channel, "+b *!*@" + n.Host)
reason := "(" + nick.Nick + ")"
if len(split) == 2 {
reason += " " + split[1]
}
conn.Kick(channel, split[0], reason)
}