@@ -57,6 +57,16 @@ class BaseCommand(object): | |||||
self.config = bot.config | self.config = bot.config | ||||
self.logger = bot.commands.logger.getChild(self.name) | self.logger = bot.commands.logger.getChild(self.name) | ||||
# Convenience functions: | |||||
self.say = lambda target, msg: self.bot.frontend.say(target, msg) | |||||
self.reply = lambda data, msg: self.bot.frontend.reply(data, msg) | |||||
self.action = lambda target, msg: self.bot.frontend.action(target, msg) | |||||
self.notice = lambda target, msg: self.bot.frontend.notice(target, msg) | |||||
self.join = lambda chan: self.bot.frontend.join(chan) | |||||
self.part = lambda chan: self.bot.frontend.part(chan) | |||||
self.mode = lambda t, level, msg: self.bot.frontend.mode(t, level, msg) | |||||
self.pong = lambda target: self.bot.frontend.pong(target) | |||||
def _wrap_check(self, data): | def _wrap_check(self, data): | ||||
"""Check whether this command should be called, catching errors.""" | """Check whether this command should be called, catching errors.""" | ||||
try: | try: | ||||
@@ -66,8 +76,7 @@ class BaseCommand(object): | |||||
self.logger.exception(e.format(self.name, data)) | self.logger.exception(e.format(self.name, data)) | ||||
def _wrap_process(self, data): | def _wrap_process(self, data): | ||||
"""Make a connection alias, process() the message, and catch errors.""" | |||||
self.connection = self.bot.frontend | |||||
"""process() the message, catching and reporting any errors.""" | |||||
try: | try: | ||||
self.process(data) | self.process(data) | ||||
except Exception: | except Exception: | ||||
@@ -43,7 +43,7 @@ class Command(BaseCommand): | |||||
if not data.args: | if not data.args: | ||||
msg = "what submission do you want me to give information about?" | msg = "what submission do you want me to give information about?" | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
title = " ".join(data.args) | title = " ".join(data.args) | ||||
@@ -67,8 +67,7 @@ class Command(BaseCommand): | |||||
if page: | if page: | ||||
return self.report(page) | return self.report(page) | ||||
msg = "submission \x0302{0}\x0301 not found.".format(title) | |||||
self.connection.reply(data, msg) | |||||
self.reply(data, "submission \x0302{0}\x0301 not found.".format(title)) | |||||
def get_page(self, title): | def get_page(self, title): | ||||
page = self.site.get_page(title, follow_redirects=False) | page = self.site.get_page(title, follow_redirects=False) | ||||
@@ -89,9 +88,9 @@ class Command(BaseCommand): | |||||
if status == "accepted": | if status == "accepted": | ||||
msg3 = "Reviewed by \x0302{0}\x0301 ({1})" | msg3 = "Reviewed by \x0302{0}\x0301 ({1})" | ||||
self.connection.reply(self.data, msg1.format(short, url)) | |||||
self.connection.say(self.data.chan, msg2.format(status)) | |||||
self.connection.say(self.data.chan, msg3.format(user_name, user_url)) | |||||
self.reply(self.data, msg1.format(short, url)) | |||||
self.say(self.data.chan, msg2.format(status)) | |||||
self.say(self.data.chan, msg3.format(user_name, user_url)) | |||||
def get_status(self, page): | def get_status(self, page): | ||||
if page.is_redirect(): | if page.is_redirect(): | ||||
@@ -49,7 +49,7 @@ class Command(BaseCommand): | |||||
if data.line[1] == "JOIN": | if data.line[1] == "JOIN": | ||||
status = " ".join(("\x02Current status:\x0F", self.get_status())) | status = " ".join(("\x02Current status:\x0F", self.get_status())) | ||||
self.connection.notice(data.nick, status) | |||||
self.notice(data.nick, status) | |||||
return | return | ||||
if data.args: | if data.args: | ||||
@@ -57,17 +57,17 @@ class Command(BaseCommand): | |||||
if action.startswith("sub") or action == "s": | if action.startswith("sub") or action == "s": | ||||
subs = self.count_submissions() | subs = self.count_submissions() | ||||
msg = "there are \x0305{0}\x0301 pending AfC submissions (\x0302WP:AFC\x0301)." | msg = "there are \x0305{0}\x0301 pending AfC submissions (\x0302WP:AFC\x0301)." | ||||
self.connection.reply(data, msg.format(subs)) | |||||
self.reply(data, msg.format(subs)) | |||||
elif action.startswith("redir") or action == "r": | elif action.startswith("redir") or action == "r": | ||||
redirs = self.count_redirects() | redirs = self.count_redirects() | ||||
msg = "there are \x0305{0}\x0301 open redirect requests (\x0302WP:AFC/R\x0301)." | msg = "there are \x0305{0}\x0301 open redirect requests (\x0302WP:AFC/R\x0301)." | ||||
self.connection.reply(data, msg.format(redirs)) | |||||
self.reply(data, msg.format(redirs)) | |||||
elif action.startswith("file") or action == "f": | elif action.startswith("file") or action == "f": | ||||
files = self.count_redirects() | files = self.count_redirects() | ||||
msg = "there are \x0305{0}\x0301 open file upload requests (\x0302WP:FFU\x0301)." | msg = "there are \x0305{0}\x0301 open file upload requests (\x0302WP:FFU\x0301)." | ||||
self.connection.reply(data, msg.format(files)) | |||||
self.reply(data, msg.format(files)) | |||||
elif action.startswith("agg") or action == "a": | elif action.startswith("agg") or action == "a": | ||||
try: | try: | ||||
@@ -78,21 +78,21 @@ class Command(BaseCommand): | |||||
agg_num = self.get_aggregate_number(agg_data) | agg_num = self.get_aggregate_number(agg_data) | ||||
except ValueError: | except ValueError: | ||||
msg = "\x0303{0}\x0301 isn't a number!" | msg = "\x0303{0}\x0301 isn't a number!" | ||||
self.connection.reply(data, msg.format(data.args[1])) | |||||
self.reply(data, msg.format(data.args[1])) | |||||
return | return | ||||
aggregate = self.get_aggregate(agg_num) | aggregate = self.get_aggregate(agg_num) | ||||
msg = "aggregate is \x0305{0}\x0301 (AfC {1})." | msg = "aggregate is \x0305{0}\x0301 (AfC {1})." | ||||
self.connection.reply(data, msg.format(agg_num, aggregate)) | |||||
self.reply(data, msg.format(agg_num, aggregate)) | |||||
elif action.startswith("nocolor") or action == "n": | elif action.startswith("nocolor") or action == "n": | ||||
self.connection.reply(data, self.get_status(color=False)) | |||||
self.reply(data, self.get_status(color=False)) | |||||
else: | else: | ||||
msg = "unknown argument: \x0303{0}\x0301. Valid args are 'subs', 'redirs', 'files', 'agg', 'nocolor'." | msg = "unknown argument: \x0303{0}\x0301. Valid args are 'subs', 'redirs', 'files', 'agg', 'nocolor'." | ||||
self.connection.reply(data, msg.format(data.args[0])) | |||||
self.reply(data, msg.format(data.args[0])) | |||||
else: | else: | ||||
self.connection.reply(data, self.get_status()) | |||||
self.reply(data, self.get_status()) | |||||
def get_status(self, color=True): | def get_status(self, color=True): | ||||
subs = self.count_submissions() | subs = self.count_submissions() | ||||
@@ -32,7 +32,7 @@ class Command(BaseCommand): | |||||
def process(self, data): | def process(self, data): | ||||
if not data.args: | if not data.args: | ||||
self.connection.reply(data, "what do you want me to calculate?") | |||||
self.reply(data, "what do you want me to calculate?") | |||||
return | return | ||||
query = ' '.join(data.args) | query = ' '.join(data.args) | ||||
@@ -47,7 +47,7 @@ class Command(BaseCommand): | |||||
match = r_result.search(result) | match = r_result.search(result) | ||||
if not match: | if not match: | ||||
self.connection.reply(data, "Calculation error.") | |||||
self.reply(data, "Calculation error.") | |||||
return | return | ||||
result = match.group(1) | result = match.group(1) | ||||
@@ -62,7 +62,7 @@ class Command(BaseCommand): | |||||
result += " " + query.split(" in ", 1)[1] | result += " " + query.split(" in ", 1)[1] | ||||
res = "%s = %s" % (query, result) | res = "%s = %s" % (query, result) | ||||
self.connection.reply(data, res) | |||||
self.reply(data, res) | |||||
def cleanup(self, query): | def cleanup(self, query): | ||||
fixes = [ | fixes = [ | ||||
@@ -23,32 +23,45 @@ | |||||
from earwigbot.commands import BaseCommand | from earwigbot.commands import BaseCommand | ||||
class Command(BaseCommand): | class Command(BaseCommand): | ||||
"""Voice, devoice, op, or deop users in the channel.""" | |||||
"""Voice, devoice, op, or deop users in the channel, or join or part from | |||||
other channels.""" | |||||
name = "chanops" | name = "chanops" | ||||
def check(self, data): | def check(self, data): | ||||
commands = ["chanops", "voice", "devoice", "op", "deop"] | |||||
commands = ["chanops", "voice", "devoice", "op", "deop", "join", "part"] | |||||
if data.is_command and data.command in commands: | if data.is_command and data.command in commands: | ||||
return True | return True | ||||
return False | return False | ||||
def process(self, data): | def process(self, data): | ||||
if data.command == "chanops": | if data.command == "chanops": | ||||
msg = "available commands are !voice, !devoice, !op, and !deop." | |||||
self.connection.reply(data, msg) | |||||
msg = "available commands are !voice, !devoice, !op, !deop, !join, and !part." | |||||
self.reply(data, msg) | |||||
return | return | ||||
if data.host not in self.config.irc["permissions"]["admins"]: | if data.host not in self.config.irc["permissions"]["admins"]: | ||||
msg = "you must be a bot admin to use this command." | |||||
self.connection.reply(data, msg) | |||||
self.reply(data, "you must be a bot admin to use this command.") | |||||
return | return | ||||
# If it is just !op/!devoice/whatever without arguments, assume they | |||||
# want to do this to themselves: | |||||
if not data.args: | |||||
target = data.nick | |||||
else: | |||||
target = data.args[0] | |||||
if data.command in ["voice", "devoice", "op", "deop"]: | |||||
# If it is just !op/!devoice/whatever without arguments, assume they | |||||
# want to do this to themselves: | |||||
if not data.args: | |||||
target = data.nick | |||||
else: | |||||
target = data.args[0] | |||||
msg = " ".join((data.command, data.chan, target)) | |||||
self.connection.say("ChanServ", msg) | |||||
msg = " ".join((data.command, data.chan, target)) | |||||
self.say("ChanServ", msg) | |||||
else: | |||||
if not data.args: | |||||
msg = "you must specify a channel to join or part from." | |||||
self.reply(data, msg) | |||||
return | |||||
channel = data.args[0] | |||||
if not channel.startswith("#"): | |||||
channel = "#" + channel | |||||
if data.command == "join": | |||||
self.join(channel) | |||||
else: | |||||
self.part(channel) |
@@ -39,12 +39,12 @@ class Command(BaseCommand): | |||||
def process(self, data): | def process(self, data): | ||||
if data.command == "crypt": | if data.command == "crypt": | ||||
msg = "available commands are !hash, !encrypt, and !decrypt." | msg = "available commands are !hash, !encrypt, and !decrypt." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
if not data.args: | if not data.args: | ||||
msg = "what do you want me to {0}?".format(data.command) | msg = "what do you want me to {0}?".format(data.command) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
if data.command == "hash": | if data.command == "hash": | ||||
@@ -52,14 +52,14 @@ class Command(BaseCommand): | |||||
if algo == "list": | if algo == "list": | ||||
algos = ', '.join(hashlib.algorithms) | algos = ', '.join(hashlib.algorithms) | ||||
msg = algos.join(("supported algorithms: ", ".")) | msg = algos.join(("supported algorithms: ", ".")) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
elif algo in hashlib.algorithms: | elif algo in hashlib.algorithms: | ||||
string = ' '.join(data.args[1:]) | string = ' '.join(data.args[1:]) | ||||
result = getattr(hashlib, algo)(string).hexdigest() | result = getattr(hashlib, algo)(string).hexdigest() | ||||
self.connection.reply(data, result) | |||||
self.reply(data, result) | |||||
else: | else: | ||||
msg = "unknown algorithm: '{0}'.".format(algo) | msg = "unknown algorithm: '{0}'.".format(algo) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
else: | else: | ||||
key = data.args[0] | key = data.args[0] | ||||
@@ -67,14 +67,14 @@ class Command(BaseCommand): | |||||
if not text: | if not text: | ||||
msg = "a key was provided, but text to {0} was not." | msg = "a key was provided, but text to {0} was not." | ||||
self.connection.reply(data, msg.format(data.command)) | |||||
self.reply(data, msg.format(data.command)) | |||||
return | return | ||||
try: | try: | ||||
if data.command == "encrypt": | if data.command == "encrypt": | ||||
self.connection.reply(data, blowfish.encrypt(key, text)) | |||||
self.reply(data, blowfish.encrypt(key, text)) | |||||
else: | else: | ||||
self.connection.reply(data, blowfish.decrypt(key, text)) | |||||
self.reply(data, blowfish.decrypt(key, text)) | |||||
except blowfish.BlowfishError as error: | except blowfish.BlowfishError as error: | ||||
msg = "{0}: {1}.".format(error.__class__.__name__, error) | msg = "{0}: {1}.".format(error.__class__.__name__, error) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) |
@@ -52,17 +52,17 @@ class Command(BaseCommand): | |||||
if command == "PING": | if command == "PING": | ||||
msg = " ".join(data.line[4:]) | msg = " ".join(data.line[4:]) | ||||
if msg: | if msg: | ||||
self.connection.notice(target, "\x01PING {0}\x01".format(msg)) | |||||
self.notice(target, "\x01PING {0}\x01".format(msg)) | |||||
else: | else: | ||||
self.connection.notice(target, "\x01PING\x01") | |||||
self.notice(target, "\x01PING\x01") | |||||
elif command == "TIME": | elif command == "TIME": | ||||
ts = time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()) | ts = time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime()) | ||||
self.connection.notice(target, "\x01TIME {0}\x01".format(ts)) | |||||
self.notice(target, "\x01TIME {0}\x01".format(ts)) | |||||
elif command == "VERSION": | elif command == "VERSION": | ||||
default = "EarwigBot - $1 - Python/$2 https://github.com/earwig/earwigbot" | default = "EarwigBot - $1 - Python/$2 https://github.com/earwig/earwigbot" | ||||
vers = self.config.irc.get("version", default) | vers = self.config.irc.get("version", default) | ||||
vers = vers.replace("$1", __version__) | vers = vers.replace("$1", __version__) | ||||
vers = vers.replace("$2", platform.python_version()) | vers = vers.replace("$2", platform.python_version()) | ||||
self.connection.notice(target, "\x01VERSION {0}\x01".format(vers)) | |||||
self.notice(target, "\x01VERSION {0}\x01".format(vers)) |
@@ -49,10 +49,10 @@ class Command(BaseCommand): | |||||
count = user.editcount() | count = user.editcount() | ||||
except wiki.UserNotFoundError: | except wiki.UserNotFoundError: | ||||
msg = "the user \x0302{0}\x0301 does not exist." | msg = "the user \x0302{0}\x0301 does not exist." | ||||
self.connection.reply(data, msg.format(name)) | |||||
self.reply(data, msg.format(name)) | |||||
return | return | ||||
safe = quote_plus(user.name()) | safe = quote_plus(user.name()) | ||||
url = "http://toolserver.org/~tparis/pcount/index.php?name={0}&lang=en&wiki=wikipedia" | url = "http://toolserver.org/~tparis/pcount/index.php?name={0}&lang=en&wiki=wikipedia" | ||||
msg = "\x0302{0}\x0301 has {1} edits ({2})." | msg = "\x0302{0}\x0301 has {1} edits ({2})." | ||||
self.connection.reply(data, msg.format(name, count, url.format(safe))) | |||||
self.reply(data, msg.format(name, count, url.format(safe))) |
@@ -35,7 +35,7 @@ class Command(BaseCommand): | |||||
self.data = data | self.data = data | ||||
if data.host not in self.config.irc["permissions"]["owners"]: | if data.host not in self.config.irc["permissions"]["owners"]: | ||||
msg = "you must be a bot owner to use this command." | msg = "you must be a bot owner to use this command." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
if not data.args: | if not data.args: | ||||
@@ -65,7 +65,7 @@ class Command(BaseCommand): | |||||
else: # They asked us to do something we don't know | else: # They asked us to do something we don't know | ||||
msg = "unknown argument: \x0303{0}\x0301.".format(data.args[0]) | msg = "unknown argument: \x0303{0}\x0301.".format(data.args[0]) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
def exec_shell(self, command): | def exec_shell(self, command): | ||||
"""Execute a shell command and get the output.""" | """Execute a shell command and get the output.""" | ||||
@@ -89,13 +89,13 @@ class Command(BaseCommand): | |||||
for key in sorted(help.keys()): | for key in sorted(help.keys()): | ||||
msg += "\x0303{0}\x0301 ({1}), ".format(key, help[key]) | msg += "\x0303{0}\x0301 ({1}), ".format(key, help[key]) | ||||
msg = msg[:-2] # Trim last comma and space | msg = msg[:-2] # Trim last comma and space | ||||
self.connection.reply(self.data, "sub-commands are: {0}.".format(msg)) | |||||
self.reply(self.data, "sub-commands are: {0}.".format(msg)) | |||||
def do_branch(self): | def do_branch(self): | ||||
"""Get our current branch.""" | """Get our current branch.""" | ||||
branch = self.exec_shell("git name-rev --name-only HEAD") | branch = self.exec_shell("git name-rev --name-only HEAD") | ||||
msg = "currently on branch \x0302{0}\x0301.".format(branch) | msg = "currently on branch \x0302{0}\x0301.".format(branch) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_branches(self): | def do_branches(self): | ||||
"""Get a list of branches.""" | """Get a list of branches.""" | ||||
@@ -106,14 +106,14 @@ class Command(BaseCommand): | |||||
branches = branches.replace('\n ', ', ') | branches = branches.replace('\n ', ', ') | ||||
branches = branches.strip() | branches = branches.strip() | ||||
msg = "branches: \x0302{0}\x0301.".format(branches) | msg = "branches: \x0302{0}\x0301.".format(branches) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_checkout(self): | def do_checkout(self): | ||||
"""Switch branches.""" | """Switch branches.""" | ||||
try: | try: | ||||
branch = self.data.args[1] | branch = self.data.args[1] | ||||
except IndexError: # no branch name provided | except IndexError: # no branch name provided | ||||
self.connection.reply(self.data, "switch to which branch?") | |||||
self.reply(self.data, "switch to which branch?") | |||||
return | return | ||||
current_branch = self.exec_shell("git name-rev --name-only HEAD") | current_branch = self.exec_shell("git name-rev --name-only HEAD") | ||||
@@ -122,51 +122,51 @@ class Command(BaseCommand): | |||||
result = self.exec_shell("git checkout %s" % branch) | result = self.exec_shell("git checkout %s" % branch) | ||||
if "Already on" in result: | if "Already on" in result: | ||||
msg = "already on \x0302{0}\x0301!".format(branch) | msg = "already on \x0302{0}\x0301!".format(branch) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
else: | else: | ||||
ms = "switched from branch \x0302{1}\x0301 to \x0302{1}\x0301." | ms = "switched from branch \x0302{1}\x0301 to \x0302{1}\x0301." | ||||
msg = ms.format(current_branch, branch) | msg = ms.format(current_branch, branch) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
except subprocess.CalledProcessError: | except subprocess.CalledProcessError: | ||||
# Git couldn't switch branches; assume the branch doesn't exist: | # Git couldn't switch branches; assume the branch doesn't exist: | ||||
msg = "branch \x0302{0}\x0301 doesn't exist!".format(branch) | msg = "branch \x0302{0}\x0301 doesn't exist!".format(branch) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_delete(self): | def do_delete(self): | ||||
"""Delete a branch, while making sure that we are not already on it.""" | """Delete a branch, while making sure that we are not already on it.""" | ||||
try: | try: | ||||
delete_branch = self.data.args[1] | delete_branch = self.data.args[1] | ||||
except IndexError: # no branch name provided | except IndexError: # no branch name provided | ||||
self.connection.reply(self.data, "delete which branch?") | |||||
self.reply(self.data, "delete which branch?") | |||||
return | return | ||||
current_branch = self.exec_shell("git name-rev --name-only HEAD") | current_branch = self.exec_shell("git name-rev --name-only HEAD") | ||||
if current_branch == delete_branch: | if current_branch == delete_branch: | ||||
msg = "you're currently on this branch; please checkout to a different branch before deleting." | msg = "you're currently on this branch; please checkout to a different branch before deleting." | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
return | return | ||||
try: | try: | ||||
self.exec_shell("git branch -d %s" % delete_branch) | self.exec_shell("git branch -d %s" % delete_branch) | ||||
msg = "branch \x0302{0}\x0301 has been deleted locally." | msg = "branch \x0302{0}\x0301 has been deleted locally." | ||||
self.connection.reply(self.data, msg.format(delete_branch)) | |||||
self.reply(self.data, msg.format(delete_branch)) | |||||
except subprocess.CalledProcessError: | except subprocess.CalledProcessError: | ||||
# Git couldn't switch branches; assume the branch doesn't exist: | # Git couldn't switch branches; assume the branch doesn't exist: | ||||
msg = "branch \x0302{0}\x0301 doesn't exist!".format(delete_branch) | msg = "branch \x0302{0}\x0301 doesn't exist!".format(delete_branch) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_pull(self): | def do_pull(self): | ||||
"""Pull from our remote repository.""" | """Pull from our remote repository.""" | ||||
branch = self.exec_shell("git name-rev --name-only HEAD") | branch = self.exec_shell("git name-rev --name-only HEAD") | ||||
msg = "pulling from remote (currently on \x0302{0}\x0301)..." | msg = "pulling from remote (currently on \x0302{0}\x0301)..." | ||||
self.connection.reply(self.data, msg.format(branch)) | |||||
self.reply(self.data, msg.format(branch)) | |||||
result = self.exec_shell("git pull") | result = self.exec_shell("git pull") | ||||
if "Already up-to-date." in result: | if "Already up-to-date." in result: | ||||
self.connection.reply(self.data, "done; no new changes.") | |||||
self.reply(self.data, "done; no new changes.") | |||||
else: | else: | ||||
regex = "\s*((.*?)\sfile(.*?)tions?\(-\))" | regex = "\s*((.*?)\sfile(.*?)tions?\(-\))" | ||||
changes = re.findall(regex, result)[0][0] | changes = re.findall(regex, result)[0][0] | ||||
@@ -176,11 +176,11 @@ class Command(BaseCommand): | |||||
cmnd_url = "git config --get remote.{0}.url".format(remote) | cmnd_url = "git config --get remote.{0}.url".format(remote) | ||||
url = self.exec_shell(cmnd_url) | url = self.exec_shell(cmnd_url) | ||||
msg = "done; {0} [from {1}].".format(changes, url) | msg = "done; {0} [from {1}].".format(changes, url) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
except subprocess.CalledProcessError: | except subprocess.CalledProcessError: | ||||
# Something in .git/config is not specified correctly, so we | # Something in .git/config is not specified correctly, so we | ||||
# cannot get the remote's URL. However, pull was a success: | # cannot get the remote's URL. However, pull was a success: | ||||
self.connection.reply(self.data, "done; %s." % changes) | |||||
self.reply(self.data, "done; %s." % changes) | |||||
def do_status(self): | def do_status(self): | ||||
"""Check whether we have anything to pull.""" | """Check whether we have anything to pull.""" | ||||
@@ -188,7 +188,7 @@ class Command(BaseCommand): | |||||
result = self.exec_shell("git fetch --dry-run") | result = self.exec_shell("git fetch --dry-run") | ||||
if not result: # Nothing was fetched, so remote and local are equal | if not result: # Nothing was fetched, so remote and local are equal | ||||
msg = "last commit was {0}. Local copy is \x02up-to-date\x0F with remote." | msg = "last commit was {0}. Local copy is \x02up-to-date\x0F with remote." | ||||
self.connection.reply(self.data, msg.format(last)) | |||||
self.reply(self.data, msg.format(last)) | |||||
else: | else: | ||||
msg = "last local commit was {0}. Remote is \x02ahead\x0F of local copy." | msg = "last local commit was {0}. Remote is \x02ahead\x0F of local copy." | ||||
self.connection.reply(self.data, msg.format(last)) | |||||
self.reply(self.data, msg.format(last)) |
@@ -40,7 +40,7 @@ class Command(BaseCommand): | |||||
msg = "Hi, I'm a bot! I have {0} commands loaded: {1}. You can get help for any command with '!help <command>'." | msg = "Hi, I'm a bot! I have {0} commands loaded: {1}. You can get help for any command with '!help <command>'." | ||||
cmnds = sorted(self.bot.commands) | cmnds = sorted(self.bot.commands) | ||||
msg = msg.format(len(cmnds), ', '.join(cmnds)) | msg = msg.format(len(cmnds), ', '.join(cmnds)) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
def do_command_help(self, data): | def do_command_help(self, data): | ||||
"""Give the user help for a specific command.""" | """Give the user help for a specific command.""" | ||||
@@ -60,9 +60,9 @@ class Command(BaseCommand): | |||||
doc = cmnd.__doc__.replace("\n", "") | doc = cmnd.__doc__.replace("\n", "") | ||||
doc = re.sub("\s\s+", " ", doc) | doc = re.sub("\s\s+", " ", doc) | ||||
msg = "help for command \x0303{0}\x0301: \"{1}\"" | msg = "help for command \x0303{0}\x0301: \"{1}\"" | ||||
self.connection.reply(data, msg.format(command, doc)) | |||||
self.reply(data, msg.format(command, doc)) | |||||
return | return | ||||
break | break | ||||
msg = "sorry, no help for \x0303{0}\x0301.".format(command) | msg = "sorry, no help for \x0303{0}\x0301.".format(command) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) |
@@ -43,15 +43,15 @@ class Command(BaseCommand): | |||||
if re.search("(\[\[(.*?)\]\])|(\{\{(.*?)\}\})", msg): | if re.search("(\[\[(.*?)\]\])|(\{\{(.*?)\}\})", msg): | ||||
links = self.parse_line(msg) | links = self.parse_line(msg) | ||||
links = " , ".join(links) | links = " , ".join(links) | ||||
self.connection.reply(data, links) | |||||
self.reply(data, links) | |||||
elif data.command == "link": | elif data.command == "link": | ||||
if not data.args: | if not data.args: | ||||
self.connection.reply(data, "what do you want me to link to?") | |||||
self.reply(data, "what do you want me to link to?") | |||||
return | return | ||||
pagename = ' '.join(data.args) | pagename = ' '.join(data.args) | ||||
link = self.parse_link(pagename) | link = self.parse_link(pagename) | ||||
self.connection.reply(data, link) | |||||
self.reply(data, link) | |||||
def parse_line(self, line): | def parse_line(self, line): | ||||
results = [] | results = [] | ||||
@@ -45,7 +45,7 @@ class Command(BaseCommand): | |||||
msg = "You use this command to praise certain people. Who they are is a secret." | msg = "You use this command to praise certain people. Who they are is a secret." | ||||
else: | else: | ||||
msg = "You're doing it wrong." | msg = "You're doing it wrong." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
self.connection.say(data.chan, msg) | |||||
self.say(data.chan, msg) |
@@ -33,8 +33,7 @@ class Command(BaseCommand): | |||||
def process(self, data): | def process(self, data): | ||||
if data.host not in self.config.irc["permissions"]["owners"]: | if data.host not in self.config.irc["permissions"]["owners"]: | ||||
msg = "you must be a bot owner to use this command." | |||||
self.connection.reply(data, msg) | |||||
self.reply(data, "you must be a bot owner to use this command.") | |||||
return | return | ||||
if data.command == "quit": | if data.command == "quit": | ||||
self.do_quit(data) | self.do_quit(data) | ||||
@@ -46,7 +45,7 @@ class Command(BaseCommand): | |||||
def do_quit(self, data): | def do_quit(self, data): | ||||
nick = self.config.irc.frontend["nick"] | nick = self.config.irc.frontend["nick"] | ||||
if not data.args or data.args[0].lower() != nick.lower(): | if not data.args or data.args[0].lower() != nick.lower(): | ||||
self.connection.reply(data, "to confirm this action, the first argument must be my nickname.") | |||||
self.reply(data, "to confirm this action, the first argument must be my nickname.") | |||||
return | return | ||||
if data.args[1:]: | if data.args[1:]: | ||||
msg = " ".join(data.args[1:]) | msg = " ".join(data.args[1:]) | ||||
@@ -66,4 +65,4 @@ class Command(BaseCommand): | |||||
self.logger.info("Reloading IRC commands and bot tasks") | self.logger.info("Reloading IRC commands and bot tasks") | ||||
self.bot.commands.load() | self.bot.commands.load() | ||||
self.bot.tasks.load() | self.bot.tasks.load() | ||||
self.connection.reply(data, "IRC commands and bot tasks reloaded.") | |||||
self.reply(data, "IRC commands and bot tasks reloaded.") |
@@ -30,7 +30,7 @@ class Command(BaseCommand): | |||||
name = "registration" | name = "registration" | ||||
def check(self, data): | def check(self, data): | ||||
commands = ["registration", "age"] | |||||
commands = ["registration", "reg", "age"] | |||||
if data.is_command and data.command in commands: | if data.is_command and data.command in commands: | ||||
return True | return True | ||||
return False | return False | ||||
@@ -49,7 +49,7 @@ class Command(BaseCommand): | |||||
reg = user.registration() | reg = user.registration() | ||||
except wiki.UserNotFoundError: | except wiki.UserNotFoundError: | ||||
msg = "the user \x0302{0}\x0301 does not exist." | msg = "the user \x0302{0}\x0301 does not exist." | ||||
self.connection.reply(data, msg.format(name)) | |||||
self.reply(data, msg.format(name)) | |||||
return | return | ||||
date = time.strftime("%b %d, %Y at %H:%M:%S UTC", reg) | date = time.strftime("%b %d, %Y at %H:%M:%S UTC", reg) | ||||
@@ -64,7 +64,7 @@ class Command(BaseCommand): | |||||
gender = "They're" | gender = "They're" | ||||
msg = "\x0302{0}\x0301 registered on {1}. {2} {3} old." | msg = "\x0302{0}\x0301 registered on {1}. {2} {3} old." | ||||
self.connection.reply(data, msg.format(name, date, gender, age)) | |||||
self.reply(data, msg.format(name, date, gender, age)) | |||||
def get_diff(self, t1, t2): | def get_diff(self, t1, t2): | ||||
parts = {"years": 31536000, "days": 86400, "hours": 3600, | parts = {"years": 31536000, "days": 86400, "hours": 3600, | ||||
@@ -37,19 +37,19 @@ class Command(BaseCommand): | |||||
def process(self, data): | def process(self, data): | ||||
if not data.args: | if not data.args: | ||||
msg = "please specify a time (in seconds) and a message in the following format: !remind <time> <msg>." | msg = "please specify a time (in seconds) and a message in the following format: !remind <time> <msg>." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
try: | try: | ||||
wait = int(data.args[0]) | wait = int(data.args[0]) | ||||
except ValueError: | except ValueError: | ||||
msg = "the time must be given as an integer, in seconds." | msg = "the time must be given as an integer, in seconds." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
message = ' '.join(data.args[1:]) | message = ' '.join(data.args[1:]) | ||||
if not message: | if not message: | ||||
msg = "what message do you want me to give you when time is up?" | msg = "what message do you want me to give you when time is up?" | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
end = time.localtime(time.time() + wait) | end = time.localtime(time.time() + wait) | ||||
@@ -58,7 +58,7 @@ class Command(BaseCommand): | |||||
msg = 'Set reminder for "{0}" in {1} seconds (ends {2}).' | msg = 'Set reminder for "{0}" in {1} seconds (ends {2}).' | ||||
msg = msg.format(message, wait, end_time_with_timezone) | msg = msg.format(message, wait, end_time_with_timezone) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
t_reminder = threading.Thread(target=self.reminder, | t_reminder = threading.Thread(target=self.reminder, | ||||
args=(data, message, wait)) | args=(data, message, wait)) | ||||
@@ -68,4 +68,4 @@ class Command(BaseCommand): | |||||
def reminder(self, data, message, wait): | def reminder(self, data, message, wait): | ||||
time.sleep(wait) | time.sleep(wait) | ||||
self.connection.reply(data, message) | |||||
self.reply(data, message) |
@@ -47,4 +47,4 @@ class Command(BaseCommand): | |||||
conn.close() | conn.close() | ||||
msg = "Replag on \x0302{0}\x0301 is \x02{1}\x0F seconds." | msg = "Replag on \x0302{0}\x0301 is \x02{1}\x0F seconds." | ||||
self.connection.reply(data, msg.format(args["db"], replag)) | |||||
self.reply(data, msg.format(args["db"], replag)) |
@@ -47,7 +47,7 @@ class Command(BaseCommand): | |||||
rights = user.groups() | rights = user.groups() | ||||
except wiki.UserNotFoundError: | except wiki.UserNotFoundError: | ||||
msg = "the user \x0302{0}\x0301 does not exist." | msg = "the user \x0302{0}\x0301 does not exist." | ||||
self.connection.reply(data, msg.format(name)) | |||||
self.reply(data, msg.format(name)) | |||||
return | return | ||||
try: | try: | ||||
@@ -55,4 +55,4 @@ class Command(BaseCommand): | |||||
except ValueError: | except ValueError: | ||||
pass | pass | ||||
msg = "the rights for \x0302{0}\x0301 are {1}." | msg = "the rights for \x0302{0}\x0301 are {1}." | ||||
self.connection.reply(data, msg.format(name, ', '.join(rights))) | |||||
self.reply(data, msg.format(name, ', '.join(rights))) |
@@ -29,8 +29,9 @@ class Command(BaseCommand): | |||||
name = "test" | name = "test" | ||||
def process(self, data): | def process(self, data): | ||||
user = "\x02{0}\x0F".format(data.nick) | |||||
hey = random.randint(0, 1) | hey = random.randint(0, 1) | ||||
if hey: | if hey: | ||||
self.connection.say(data.chan, "Hey \x02%s\x0F!" % data.nick) | |||||
self.say(data.chan, "Hey {0}!".format(user)) | |||||
else: | else: | ||||
self.connection.say(data.chan, "'sup \x02%s\x0F?" % data.nick) | |||||
self.say(data.chan, "'sup {0}?".format(user)) |
@@ -40,7 +40,7 @@ class Command(BaseCommand): | |||||
self.data = data | self.data = data | ||||
if data.host not in self.config.irc["permissions"]["owners"]: | if data.host not in self.config.irc["permissions"]["owners"]: | ||||
msg = "you must be a bot owner to use this command." | msg = "you must be a bot owner to use this command." | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
if not data.args: | if not data.args: | ||||
@@ -48,7 +48,7 @@ class Command(BaseCommand): | |||||
self.do_list() | self.do_list() | ||||
else: | else: | ||||
msg = "no arguments provided. Maybe you wanted '!{0} list', '!{0} start', or '!{0} listall'?" | msg = "no arguments provided. Maybe you wanted '!{0} list', '!{0} start', or '!{0} listall'?" | ||||
self.connection.reply(data, msg.format(data.command)) | |||||
self.reply(data, msg.format(data.command)) | |||||
return | return | ||||
if data.args[0] == "list": | if data.args[0] == "list": | ||||
@@ -62,7 +62,7 @@ class Command(BaseCommand): | |||||
else: # They asked us to do something we don't know | else: # They asked us to do something we don't know | ||||
msg = "unknown argument: \x0303{0}\x0301.".format(data.args[0]) | msg = "unknown argument: \x0303{0}\x0301.".format(data.args[0]) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
def do_list(self): | def do_list(self): | ||||
"""With !tasks list (or abbreviation !tasklist), list all running | """With !tasks list (or abbreviation !tasklist), list all running | ||||
@@ -98,7 +98,7 @@ class Command(BaseCommand): | |||||
msg = "\x02{0}\x0F threads active: {1}, and \x020\x0F task threads." | msg = "\x02{0}\x0F threads active: {1}, and \x020\x0F task threads." | ||||
msg = msg.format(len(threads), ', '.join(normal_threads)) | msg = msg.format(len(threads), ', '.join(normal_threads)) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_listall(self): | def do_listall(self): | ||||
"""With !tasks listall or !tasks all, list all loaded tasks, and report | """With !tasks listall or !tasks all, list all loaded tasks, and report | ||||
@@ -120,7 +120,7 @@ class Command(BaseCommand): | |||||
tasks = ", ".join(tasklist) | tasks = ", ".join(tasklist) | ||||
msg = "{0} tasks loaded: {1}.".format(len(tasklist), tasks) | msg = "{0} tasks loaded: {1}.".format(len(tasklist), tasks) | ||||
self.connection.reply(self.data, msg) | |||||
self.reply(self.data, msg) | |||||
def do_start(self): | def do_start(self): | ||||
"""With !tasks start, start any loaded task by name with or without | """With !tasks start, start any loaded task by name with or without | ||||
@@ -130,23 +130,23 @@ class Command(BaseCommand): | |||||
try: | try: | ||||
task_name = data.args[1] | task_name = data.args[1] | ||||
except IndexError: # No task name given | except IndexError: # No task name given | ||||
self.connection.reply(data, "what task do you want me to start?") | |||||
self.reply(data, "what task do you want me to start?") | |||||
return | return | ||||
try: | try: | ||||
data.parse_kwargs() | data.parse_kwargs() | ||||
except KwargParseException, arg: | except KwargParseException, arg: | ||||
msg = "error parsing argument: \x0303{0}\x0301.".format(arg) | msg = "error parsing argument: \x0303{0}\x0301.".format(arg) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) | |||||
return | return | ||||
if task_name not in self.bot.tasks: | if task_name not in self.bot.tasks: | ||||
# This task does not exist or hasn't been loaded: | # This task does not exist or hasn't been loaded: | ||||
msg = "task could not be found; either it doesn't exist, or it wasn't loaded correctly." | msg = "task could not be found; either it doesn't exist, or it wasn't loaded correctly." | ||||
self.connection.reply(data, msg.format(task_name)) | |||||
self.reply(data, msg.format(task_name)) | |||||
return | return | ||||
data.kwargs["fromIRC"] = True | data.kwargs["fromIRC"] = True | ||||
self.bot.tasks.start(task_name, **data.kwargs) | self.bot.tasks.start(task_name, **data.kwargs) | ||||
msg = "task \x0302{0}\x0301 started.".format(task_name) | msg = "task \x0302{0}\x0301 started.".format(task_name) | ||||
self.connection.reply(data, msg) | |||||
self.reply(data, msg) |
@@ -118,9 +118,9 @@ class IRCConnection(object): | |||||
msg = "PART {0}".format(chan) | msg = "PART {0}".format(chan) | ||||
self._send(msg) | self._send(msg) | ||||
def mode(self, chan, level, msg): | |||||
def mode(self, target, level, msg): | |||||
"""Send a mode message to the server.""" | """Send a mode message to the server.""" | ||||
msg = "MODE {0} {1} {2}".format(chan, level, msg) | |||||
msg = "MODE {0} {1} {2}".format(target, level, msg) | |||||
self._send(msg) | self._send(msg) | ||||
def pong(self, target): | def pong(self, target): | ||||