From 39a4d226200583d3a7327b717515dae693b9adf6 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 9 Aug 2011 02:03:01 -0400 Subject: [PATCH] task loading and running both work now, including the schedule and !tasks command\nbot restructuring should be complete - woo! --- bot/classes/base_task.py | 2 +- bot/commands/__init__.py | 2 +- bot/commands/threads.py | 4 +-- bot/tasks/__init__.py | 67 +++++++++++++++++++++++++-------------------- bot/tasks/afc_catdelink.py | 4 +-- bot/tasks/afc_copyvios.py | 4 +-- bot/tasks/afc_dailycats.py | 4 +-- bot/tasks/afc_statistics.py | 7 +++-- bot/tasks/afc_undated.py | 4 +-- bot/tasks/blptag.py | 4 +-- bot/tasks/feed_dailycats.py | 4 +-- bot/tasks/wrongmime.py | 4 +-- bot/watcher.py | 4 +-- 13 files changed, 62 insertions(+), 52 deletions(-) diff --git a/bot/classes/base_task.py b/bot/classes/base_task.py index 278a77d..fcffa00 100644 --- a/bot/classes/base_task.py +++ b/bot/classes/base_task.py @@ -2,7 +2,7 @@ class BaseTask(object): """A base class for bot tasks that edit Wikipedia.""" - task_name = None + name = None def __init__(self): """Constructor for new tasks. diff --git a/bot/commands/__init__.py b/bot/commands/__init__.py index 7cb27be..aad4936 100644 --- a/bot/commands/__init__.py +++ b/bot/commands/__init__.py @@ -67,7 +67,7 @@ def load(connection): except AttributeError: pass # The file is doesn't contain a command, so just move on - msg = "Found {0} command classes: {1}." + msg = "Found {0} commands: {1}." print msg.format(len(_commands), ", ".join(_commands.keys())) def get_all(): diff --git a/bot/commands/threads.py b/bot/commands/threads.py index cf6b18f..263dd6d 100644 --- a/bot/commands/threads.py +++ b/bot/commands/threads.py @@ -126,8 +126,8 @@ class Command(BaseCommand): self.connection.reply(data, msg) return - # This task does not exist or hasn't been loaded: - if task_name not in tasks._tasks.keys(): + if task_name not in tasks.get_all().keys(): + # This task does not exist or hasn't been loaded: msg = "task could not be found; either bot/tasks/{0}.py doesn't exist, or it wasn't loaded correctly." self.connection.reply(data, msg.format(task_name)) return diff --git a/bot/tasks/__init__.py b/bot/tasks/__init__.py index d19292c..64f4f01 100644 --- a/bot/tasks/__init__.py +++ b/bot/tasks/__init__.py @@ -7,39 +7,43 @@ This package provides the wiki bot "tasks" EarwigBot runs. Here in __init__, you can find some functions used to load and run these tasks. """ +import os +import sys +import threading import time import traceback -import threading -import os +from classes import BaseTask import config __all__ = ["load", "schedule", "start", "get_all"] +# Base directory when searching for tasks: +base_dir = os.path.join(config.root_dir, "bot", "tasks") + # Store loaded tasks as a dict where the key is the task name and the value is # an instance of the task class: _tasks = {} -def _load_task(f): - """Look in a given file for the task class.""" +def _load_task(filename): + """Try to load a specific task from a module, identified by file name.""" global _tasks - module = f[:-3] # strip .py from end + # Strip .py from the end of the filename and join with our package name: + name = ".".join(("tasks", filename[:-3])) try: - exec "from wiki.tasks import %s as m" % module - except: # importing the file failed for some reason... - print "Couldn't load task file %s:" % f - traceback.print_exc() - return - try: - task_class = m.Task + __import__(name) except: - print "Couldn't find or get task class in file %s:" % f + print "Couldn't load file {0}:".format(filename) traceback.print_exc() return - task_name = task_class.task_name - _tasks[task_name] = task_class() - print "Added task %s from bot/tasks/%s..." % (task_name, f) + + task = sys.modules[name].Task() + if not isinstance(task, BaseTask): + return + + _tasks[task.name] = task + print "Added task {0}...".format(task.name) def _wrapper(task, **kwargs): """Wrapper for task classes: run the task and catch any errors.""" @@ -47,28 +51,31 @@ def _wrapper(task, **kwargs): task.run(**kwargs) except: error = "Task '{0}' raised an exception and had to stop:" - print error.format(task.task_name) + print error.format(task.name) traceback.print_exc() else: - print "Task '{0}' finished without error.".format(task.task_name) + print "Task '{0}' finished without error.".format(task.name) def load(): - """Load all valid task classes from bot/tasks/, and add them to the _tasks - variable.""" - files = os.listdir(os.path.join("bot", "tasks")) - files.sort() # alphabetically sort all files in wiki/tasks/ - for f in files: - if not os.path.isfile(os.path.join("bot", "tasks", f)): - continue # ignore non-files - if f.startswith("_") or not f.endswith(".py"): - continue # ignore non-python files or files beginning with an _ - load_class_from_file(f) - print "Found %s tasks: %s." % (len(_tasks), ', '.join(_tasks.keys())) + """Load all valid tasks from bot/tasks/, into the _tasks variable.""" + files = os.listdir(base_dir) + files.sort() + + for filename in files: + if filename.startswith("_") or not filename.endswith(".py"): + continue + try: + _load_task(filename) + except AttributeError: + pass # The file is doesn't contain a task, so just move on + + print "Found {0} tasks: {1}.".format(len(_tasks), ', '.join(_tasks.keys())) def schedule(now=time.gmtime()): """Start all tasks that are supposed to be run at a given time.""" + # Get list of tasks to run this turn: tasks = config.schedule(now.tm_min, now.tm_hour, now.tm_mday, now.tm_mon, - now.tm_wday) # get list of tasks to run this turn + now.tm_wday) for task in tasks: if isinstance(task, list): # they've specified kwargs diff --git a/bot/tasks/afc_catdelink.py b/bot/tasks/afc_catdelink.py index 5ad71fd..a3b11f4 100644 --- a/bot/tasks/afc_catdelink.py +++ b/bot/tasks/afc_catdelink.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to delink mainspace categories in declined [[WP:AFC]] submissions.""" - task_name = "afc_catdelink" + name = "afc_catdelink" def __init__(self): pass diff --git a/bot/tasks/afc_copyvios.py b/bot/tasks/afc_copyvios.py index 93153df..4443cf1 100644 --- a/bot/tasks/afc_copyvios.py +++ b/bot/tasks/afc_copyvios.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to check newly-edited [[WP:AFC]] submissions for copyright violations.""" - task_name = "afc_copyvios" + name = "afc_copyvios" def __init__(self): pass diff --git a/bot/tasks/afc_dailycats.py b/bot/tasks/afc_dailycats.py index 2a7c2d9..a00fc4a 100644 --- a/bot/tasks/afc_dailycats.py +++ b/bot/tasks/afc_dailycats.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """ A task to create daily categories for [[WP:AFC]].""" - task_name = "afc_dailycats" + name = "afc_dailycats" def __init__(self): pass diff --git a/bot/tasks/afc_statistics.py b/bot/tasks/afc_statistics.py index 830afc0..2a6ae44 100644 --- a/bot/tasks/afc_statistics.py +++ b/bot/tasks/afc_statistics.py @@ -1,14 +1,17 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +import time + +from classes import BaseTask class Task(BaseTask): """A task to generate statistics for [[WP:AFC]] and save them to [[Template:AFC_statistics]].""" - task_name = "afc_statistics" + name = "afc_statistics" def __init__(self): pass def run(self, **kwargs): + time.sleep(5) print kwargs diff --git a/bot/tasks/afc_undated.py b/bot/tasks/afc_undated.py index ad6124a..dbad88c 100644 --- a/bot/tasks/afc_undated.py +++ b/bot/tasks/afc_undated.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to clear [[Category:Undated AfC submissions]].""" - task_name = "afc_undated" + name = "afc_undated" def __init__(self): pass diff --git a/bot/tasks/blptag.py b/bot/tasks/blptag.py index 916c79b..fed72a8 100644 --- a/bot/tasks/blptag.py +++ b/bot/tasks/blptag.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to add |blp=yes to {{WPB}} or {{WPBS}} when it is used along with {{WP Biography}}.""" - task_name = "blptag" + name = "blptag" def __init__(self): pass diff --git a/bot/tasks/feed_dailycats.py b/bot/tasks/feed_dailycats.py index 6d3cb40..24be9ee 100644 --- a/bot/tasks/feed_dailycats.py +++ b/bot/tasks/feed_dailycats.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to create daily categories for [[WP:FEED]].""" - task_name = "feed_dailycats" + name = "feed_dailycats" def __init__(self): pass diff --git a/bot/tasks/wrongmime.py b/bot/tasks/wrongmime.py index aa56228..69ac042 100644 --- a/bot/tasks/wrongmime.py +++ b/bot/tasks/wrongmime.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from wiki.base_task import BaseTask +from classes import BaseTask class Task(BaseTask): """A task to tag files whose extensions do not agree with their MIME type.""" - task_name = "wrongmime" + name = "wrongmime" def __init__(self): pass diff --git a/bot/watcher.py b/bot/watcher.py index 9153d9a..551e7df 100644 --- a/bot/watcher.py +++ b/bot/watcher.py @@ -48,9 +48,9 @@ def main(connection, f_conn=None): read_buffer = lines.pop() for line in lines: - _process_message(line) + _process_message(connection, line) -def _process_message(line): +def _process_message(connection, line): """Process a single message from IRC.""" line = line.strip().split()