Parcourir la source

Misc additions, cleanup, and fixes, including:

* Support for starting commands using the bot's name
* Moved _wrap_check and _wrap_process to the CommandManager
* Removed extra sortkey in afc_statistics
tags/v0.1^2
Ben Kurtovic il y a 12 ans
Parent
révision
b3c0869db2
8 fichiers modifiés avec 62 ajouts et 48 suppressions
  1. +0
    -16
      earwigbot/commands/__init__.py
  2. +16
    -3
      earwigbot/commands/help.py
  3. +5
    -4
      earwigbot/commands/quit.py
  4. +1
    -1
      earwigbot/commands/threads.py
  5. +19
    -10
      earwigbot/irc/data.py
  6. +1
    -1
      earwigbot/irc/frontend.py
  7. +18
    -2
      earwigbot/managers.py
  8. +2
    -11
      earwigbot/tasks/afc_statistics.py

+ 0
- 16
earwigbot/commands/__init__.py Voir le fichier

@@ -67,22 +67,6 @@ class BaseCommand(object):
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):
"""Check whether this command should be called, catching errors."""
try:
return self.check(data)
except Exception:
e = "Error checking command '{0}' with data: {1}:"
self.logger.exception(e.format(self.name, data))

def _wrap_process(self, data):
"""process() the message, catching and reporting any errors."""
try:
self.process(data)
except Exception:
e = "Error executing command '{0}':"
self.logger.exception(e.format(data.command))

def check(self, data):
"""Return whether this command should be called in response to 'data'.



+ 16
- 3
earwigbot/commands/help.py Voir le fichier

@@ -29,11 +29,21 @@ class Command(BaseCommand):
"""Displays help information."""
name = "help"

def check(self, data):
if data.is_command:
if data.command == "help":
return True
if not data.command and data.trigger == data.my_nick:
return True
return False

def process(self, data):
if not data.args:
self.do_main_help(data)
else:
if not data.command:
self.do_hello(data)
if data.args:
self.do_command_help(data)
else:
self.do_main_help(data)

def do_main_help(self, data):
"""Give the user a general help message with a list of all commands."""
@@ -66,3 +76,6 @@ class Command(BaseCommand):

msg = "sorry, no help for \x0303{0}\x0301.".format(command)
self.reply(data, msg)

def do_hello(self, data):
self.say(data.chan, "Yes, {0}?".format(data.nick))

+ 5
- 4
earwigbot/commands/quit.py Voir le fichier

@@ -43,12 +43,13 @@ class Command(BaseCommand):
self.do_reload(data)

def do_quit(self, data):
nick = self.config.irc.frontend["nick"]
if not data.args or data.args[0].lower() != nick.lower():
args = data.args
nick = self.config.irc.frontend["nick"].lower()
if data.trigger != nick and (not args or args[0].lower() != nick):
self.reply(data, "to confirm this action, the first argument must be my nickname.")
return
if data.args[1:]:
msg = " ".join(data.args[1:])
if args[1:]:
msg = " ".join(args[1:])
self.bot.stop("Stopped by {0}: {1}".format(data.nick, msg))
else:
self.bot.stop("Stopped by {0}".format(data.nick))


+ 1
- 1
earwigbot/commands/threads.py Voir le fichier

@@ -119,7 +119,7 @@ class Command(BaseCommand):

tasks = ", ".join(tasklist)

msg = "{0} tasks loaded: {1}.".format(len(tasklist), tasks)
msg = "\x02{0}\x0F tasks loaded: {1}.".format(len(tasklist), tasks)
self.reply(self.data, msg)

def do_start(self):


+ 19
- 10
earwigbot/irc/data.py Voir le fichier

@@ -33,8 +33,9 @@ class KwargParseException(Exception):
class Data(object):
"""Store data from an individual line received on IRC."""
def __init__(self, line):
def __init__(self, bot, line):
self.line = line
self.my_nick = bot.config.irc["frontend"]["nick"].lower()
self.chan = self.nick = self.ident = self.host = self.msg = ""

def parse_args(self):
@@ -46,20 +47,28 @@ class Data(object):

# Isolate command arguments:
self.args = args[1:]
self.is_command = False # is this message a command?
self.is_command = False # Is this message a command?
self.trigger = None # What triggered this command? (!, ., or our nick)

try:
self.command = args[0]
self.command = args[0].lower()
except IndexError:
self.command = None
return

try:
if self.command.startswith('!') or self.command.startswith('.'):
self.is_command = True
self.command = self.command[1:] # Strip the '!' or '.'
self.command = self.command.lower()
except AttributeError:
pass
if self.command.startswith("!") or self.command.startswith("."):
# e.g. "!command arg1 arg2"
self.is_command = True
self.trigger = self.command[0]
self.command = self.command[1:] # Strip the "!" or "."
elif self.command.startswith(self.my_nick):
# e.g. "EarwigBot, command arg1 arg2"
self.is_command = True
self.trigger = self.my_nick
try:
self.command = self.args.pop(0).lower()
except IndexError:
self.command = ""

def parse_kwargs(self):
"""Parse keyword arguments embedded in self.args.


+ 1
- 1
earwigbot/irc/frontend.py Voir le fichier

@@ -51,7 +51,7 @@ class Frontend(IRCConnection):
def _process_message(self, line):
"""Process a single message from IRC."""
line = line.strip().split()
data = Data(line) # New Data instance to store info about this line
data = Data(self.bot, line)

if line[1] == "JOIN":
data.nick, data.ident, data.host = self.sender_regex.findall(line[0])[0]


+ 18
- 2
earwigbot/managers.py Voir le fichier

@@ -147,13 +147,29 @@ class CommandManager(_ResourceManager):
base = super(CommandManager, self)
base.__init__(bot, "commands", "Command", BaseCommand)

def _wrap_check(self, command, data):
"""Check whether a command should be called, catching errors."""
try:
return command.check(data)
except Exception:
e = "Error checking command '{0}' with data: {1}:"
self.logger.exception(e.format(command.name, data))

def _wrap_process(self, command, data):
"""process() the message, catching and reporting any errors."""
try:
command.process(data)
except Exception:
e = "Error executing command '{0}':"
self.logger.exception(e.format(data.command))

def check(self, hook, data):
"""Given an IRC event, check if there's anything we can respond to."""
self.lock.acquire()
for command in self._resources.itervalues():
if hook in command.hooks and command._wrap_check(data):
if hook in command.hooks and self._wrap_check(command, data):
self.lock.release()
command._wrap_process(data)
self._wrap_process(command, data)
return
self.lock.release()



+ 2
- 11
earwigbot/tasks/afc_statistics.py Voir le fichier

@@ -165,11 +165,9 @@ class Task(BaseTask):
table, where keys are column names and values are their cell contents.
"""
row = "{0}|s={page_status}|t={page_title}|h={page_short}|z={page_size}|"
row += "sr={page_special_user}|sh={page_special_hidden}|sd={page_special_time}|si={page_special_oldid}|"
row += "mr={page_modify_user}|mh={page_modify_hidden}|md={page_modify_time}|mi={page_modify_oldid}"
row += "sr={page_special_user}|sd={page_special_time}|si={page_special_oldid}|"
row += "mr={page_modify_user}|md={page_modify_time}|mi={page_modify_oldid}"

page["page_special_hidden"] = self.format_hidden(page["page_special_time"])
page["page_modify_hidden"] = self.format_hidden(page["page_modify_time"])
page["page_special_time"] = self.format_time(page["page_special_time"])
page["page_modify_time"] = self.format_time(page["page_modify_time"])

@@ -182,13 +180,6 @@ class Task(BaseTask):
"""Format a datetime into the standard MediaWiki timestamp format."""
return dt.strftime("%H:%M, %d %b %Y")

def format_hidden(self, dt):
"""Convert a datetime into seconds since the epoch.

This is used by the template as a hidden sortkey.
"""
return int((dt - datetime(1970, 1, 1)).total_seconds())

def sync(self, **kwargs):
"""Synchronize our local statistics database with the site.



Chargement…
Annuler
Enregistrer