|
@@ -8,53 +8,67 @@ In __init__, you can find some functions used to load and run these commands. |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
import os |
|
|
import os |
|
|
|
|
|
import sys |
|
|
import traceback |
|
|
import traceback |
|
|
|
|
|
|
|
|
|
|
|
from classes import BaseCommand |
|
|
|
|
|
import config |
|
|
|
|
|
|
|
|
__all__ = ["load", "get_all", "check"] |
|
|
__all__ = ["load", "get_all", "check"] |
|
|
|
|
|
|
|
|
|
|
|
# Base directory when searching for commands: |
|
|
|
|
|
base_dir = os.path.join(config.root_dir, "bot", "commands") |
|
|
|
|
|
|
|
|
# Store commands in a dict, where the key is the command's name and the value |
|
|
# Store commands in a dict, where the key is the command's name and the value |
|
|
# is an instance of the command's class: |
|
|
# is an instance of the command's class: |
|
|
_commands = {} |
|
|
_commands = {} |
|
|
|
|
|
|
|
|
def _load_class_from_file(connection, module): |
|
|
|
|
|
"""Add.""" |
|
|
|
|
|
global commands |
|
|
|
|
|
objects = dir(module) |
|
|
|
|
|
|
|
|
def _load_command(connection, filename): |
|
|
|
|
|
"""Try to load a specific command from a module, identified by file name. |
|
|
|
|
|
|
|
|
for this_obj in objects: # go through everything in the file |
|
|
|
|
|
obj = eval("module.%s" % this_obj) # this_obj is a string, so get the actual object corresponding to that string |
|
|
|
|
|
|
|
|
Given a Connection object and a filename, we'll first try to import it, |
|
|
|
|
|
and if that works, make an instance of the 'Command' class inside (assuming |
|
|
|
|
|
it is an instance of BaseCommand), add it to _commands, and report the |
|
|
|
|
|
addition to the user. Any problems along the way will either be ignored or |
|
|
|
|
|
reported. |
|
|
|
|
|
""" |
|
|
|
|
|
global _commands |
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
bases = obj.__bases__ |
|
|
|
|
|
except AttributeError: # object isn't a valid class, so ignore it |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
# Strip .py from the end of the filename and join with our package name: |
|
|
|
|
|
name = ".".join(("commands", filename[:-3])) |
|
|
|
|
|
try: |
|
|
|
|
|
__import__(name) |
|
|
|
|
|
except: |
|
|
|
|
|
print "Couldn't load file {0}:".format(filename) |
|
|
|
|
|
traceback.print_exc() |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
for base in bases: |
|
|
|
|
|
if base.__name__ == "BaseCommand": # this inherits BaseCommand, so it must be a command class |
|
|
|
|
|
command = obj(connection) # initialize a new command object |
|
|
|
|
|
_commands.append(command) |
|
|
|
|
|
print "Added command class %s from %s..." % (this_obj, module.__name__) |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
command = sys.modules[name].Command(connection) |
|
|
|
|
|
if not isinstance(command, BaseCommand): |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
_commands[command.name] = command |
|
|
|
|
|
print "Added command {0}...".format(command.name) |
|
|
|
|
|
|
|
|
def load(connection): |
|
|
def load(connection): |
|
|
"""Load all valid commands into the _commands global variable.""" |
|
|
|
|
|
files = os.listdir(os.path.join("bot", "commands")) |
|
|
|
|
|
|
|
|
"""Load all valid commands into the _commands global variable. |
|
|
|
|
|
|
|
|
|
|
|
`connection` is a Connection object that is given to each command's |
|
|
|
|
|
constructor. |
|
|
|
|
|
""" |
|
|
|
|
|
files = os.listdir(base_dir) |
|
|
files.sort() |
|
|
files.sort() |
|
|
|
|
|
|
|
|
for f in files: |
|
|
|
|
|
if f.startswith("_") or not f.endswith(".py"): # ignore non-python files or files beginning with "_" |
|
|
|
|
|
|
|
|
for filename in files: |
|
|
|
|
|
if filename.startswith("_") or not filename.endswith(".py"): |
|
|
continue |
|
|
continue |
|
|
module = f[:-3] # strip .py from end |
|
|
|
|
|
try: |
|
|
try: |
|
|
exec "from irc.commands import %s" % module |
|
|
|
|
|
except: # importing the file failed for some reason... |
|
|
|
|
|
print "Couldn't load file %s:" % f |
|
|
|
|
|
traceback.print_exc() |
|
|
|
|
|
continue |
|
|
|
|
|
process_module(connection, eval(module)) # 'module' is a string, so get the actual object for processing by eval-ing it |
|
|
|
|
|
|
|
|
_load_command(connection, filename) |
|
|
|
|
|
except AttributeError: |
|
|
|
|
|
pass # The file is doesn't contain a command, so just move on |
|
|
|
|
|
|
|
|
pretty_cmnds = map(lambda c: c.__class__.__name__, commands) |
|
|
|
|
|
print "Found %s command classes: %s." % (len(commands), ', '.join(pretty_cmnds)) |
|
|
|
|
|
|
|
|
msg = "Found {0} command classes: {1}." |
|
|
|
|
|
print msg.format(len(_commands), ", ".join(_commands.keys())) |
|
|
|
|
|
|
|
|
def get_all(): |
|
|
def get_all(): |
|
|
"""Return our dict of all loaded commands.""" |
|
|
"""Return our dict of all loaded commands.""" |
|
@@ -62,15 +76,15 @@ def get_all(): |
|
|
|
|
|
|
|
|
def check(hook, data): |
|
|
def check(hook, data): |
|
|
"""Given an event on IRC, check if there's anything we can respond to.""" |
|
|
"""Given an event on IRC, check if there's anything we can respond to.""" |
|
|
# parse command arguments into data.command and data.args |
|
|
|
|
|
|
|
|
# Parse command arguments into data.command and data.args: |
|
|
data.parse_args() |
|
|
data.parse_args() |
|
|
|
|
|
|
|
|
for command in _commands: |
|
|
|
|
|
if hook in command.get_hooks(): |
|
|
|
|
|
|
|
|
for command in _commands.values(): |
|
|
|
|
|
if hook in command.hooks: |
|
|
if command.check(data): |
|
|
if command.check(data): |
|
|
try: |
|
|
try: |
|
|
command.process(data) |
|
|
command.process(data) |
|
|
except: |
|
|
except: |
|
|
print "Error executing command '{}':".format(data.command) |
|
|
|
|
|
traceback.print_exc() # catch exceptions and print them |
|
|
|
|
|
|
|
|
print "Error executing command '{0}':".format(data.command) |
|
|
|
|
|
traceback.print_exc() |
|
|
break |
|
|
break |