| @@ -71,6 +71,8 @@ class BaseCommand(object): | |||||
| Given a Data() instance, return True if we should respond to this | Given a Data() instance, return True if we should respond to this | ||||
| activity, or False if we should ignore it or it doesn't apply to us. | activity, or False if we should ignore it or it doesn't apply to us. | ||||
| Be aware that since this is called for each message sent on IRC, it | |||||
| should not be cheap to execute and unlikely to throw exceptions. | |||||
| Most commands return True if data.command == self.name, otherwise they | Most commands return True if data.command == self.name, otherwise they | ||||
| return False. This is the default behavior of check(); you need only | return False. This is the default behavior of check(); you need only | ||||
| @@ -97,6 +99,10 @@ class CommandManager(object): | |||||
| self._commands = {} | self._commands = {} | ||||
| self._command_access_lock = Lock() | self._command_access_lock = Lock() | ||||
| def __iter__(self): | |||||
| for name in self._commands: | |||||
| yield name | |||||
| def _load_command(self, name, path): | def _load_command(self, name, path): | ||||
| """Load a specific command from a module, identified by name and path. | """Load a specific command from a module, identified by name and path. | ||||
| @@ -148,10 +154,6 @@ class CommandManager(object): | |||||
| commands = ", ".join(self._commands.keys()) | commands = ", ".join(self._commands.keys()) | ||||
| self.logger.info(msg.format(len(self._commands), commands)) | self.logger.info(msg.format(len(self._commands), commands)) | ||||
| def get_all(self): | |||||
| """Return our dict of all loaded commands.""" | |||||
| return self._commands | |||||
| def check(self, hook, data): | def check(self, hook, data): | ||||
| """Given an IRC event, check if there's anything we can respond to.""" | """Given an IRC event, check if there's anything we can respond to.""" | ||||
| with self._command_access_lock: | with self._command_access_lock: | ||||
| @@ -164,3 +166,10 @@ class CommandManager(object): | |||||
| e = "Error executing command '{0}':" | e = "Error executing command '{0}':" | ||||
| self.logger.exception(e.format(data.command)) | self.logger.exception(e.format(data.command)) | ||||
| break | break | ||||
| def get(self, command_name): | |||||
| """Return the class instance associated with a certain command name. | |||||
| Will raise KeyError if the command is not found. | |||||
| """ | |||||
| return self._command[command_name] | |||||
| @@ -30,7 +30,6 @@ class Command(BaseCommand): | |||||
| name = "help" | name = "help" | ||||
| def process(self, data): | def process(self, data): | ||||
| self.cmnds = self.bot.commands.get_all() | |||||
| if not data.args: | if not data.args: | ||||
| self.do_main_help(data) | self.do_main_help(data) | ||||
| else: | else: | ||||
| @@ -39,7 +38,7 @@ class Command(BaseCommand): | |||||
| def do_main_help(self, data): | def do_main_help(self, data): | ||||
| """Give the user a general help message with a list of all commands.""" | """Give the user a general help message with a list of all commands.""" | ||||
| 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.cmnds.keys()) | |||||
| 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.connection.reply(data, msg) | ||||
| @@ -53,13 +52,14 @@ class Command(BaseCommand): | |||||
| dummy.command = command.lower() | dummy.command = command.lower() | ||||
| dummy.is_command = True | dummy.is_command = True | ||||
| for cmnd in self.cmnds.values(): | |||||
| for cmnd_name in self.bot.commands: | |||||
| cmnd = self.bot.commands.get(cmnd_name) | |||||
| if not cmnd.check(dummy): | if not cmnd.check(dummy): | ||||
| continue | continue | ||||
| if cmnd.__doc__: | if cmnd.__doc__: | ||||
| doc = cmnd.__doc__.replace("\n", "") | doc = cmnd.__doc__.replace("\n", "") | ||||
| doc = re.sub("\s\s+", " ", doc) | doc = re.sub("\s\s+", " ", doc) | ||||
| msg = "info for command \x0303{0}\x0301: \"{1}\"" | |||||
| msg = "help for command \x0303{0}\x0301: \"{1}\"" | |||||
| self.connection.reply(data, msg.format(command, doc)) | self.connection.reply(data, msg.format(command, doc)) | ||||
| return | return | ||||
| break | break | ||||
| @@ -103,13 +103,9 @@ class Command(BaseCommand): | |||||
| 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 | ||||
| whether they are currently running or idle.""" | whether they are currently running or idle.""" | ||||
| all_tasks = self.bot.tasks.get_all().keys() | |||||
| threads = threading.enumerate() | threads = threading.enumerate() | ||||
| tasklist = [] | tasklist = [] | ||||
| all_tasks.sort() | |||||
| for task in all_tasks: | |||||
| for task in sorted(self.bot.tasks): | |||||
| threadlist = [t for t in threads if t.name.startswith(task)] | threadlist = [t for t in threads if t.name.startswith(task)] | ||||
| ids = [str(t.ident) for t in threadlist] | ids = [str(t.ident) for t in threadlist] | ||||
| if not ids: | if not ids: | ||||
| @@ -144,9 +140,9 @@ class Command(BaseCommand): | |||||
| self.connection.reply(data, msg) | self.connection.reply(data, msg) | ||||
| return | return | ||||
| if task_name not in self.bot.tasks.get_all().keys(): | |||||
| 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 tasks/{0}.py 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.connection.reply(data, msg.format(task_name)) | ||||
| return | return | ||||
| @@ -139,6 +139,10 @@ class TaskManager(object): | |||||
| self._tasks = {} | self._tasks = {} | ||||
| self._task_access_lock = Lock() | self._task_access_lock = Lock() | ||||
| def __iter__(self): | |||||
| for name in self._tasks: | |||||
| yield name | |||||
| def _wrapper(self, task, **kwargs): | def _wrapper(self, task, **kwargs): | ||||
| """Wrapper for task classes: run the task and catch any errors.""" | """Wrapper for task classes: run the task and catch any errors.""" | ||||
| try: | try: | ||||
| @@ -239,7 +243,3 @@ class TaskManager(object): | |||||
| Will raise KeyError if the task is not found. | Will raise KeyError if the task is not found. | ||||
| """ | """ | ||||
| return self._tasks[task_name] | return self._tasks[task_name] | ||||
| def get_all(self): | |||||
| """Return our dict of all loaded tasks.""" | |||||
| return self._tasks | |||||