A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 line
2.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # A module to manage IRC commands.
  3. import os
  4. import traceback
  5. commands = []
  6. def load_commands(connection):
  7. """load all valid command classes from irc/commmands/ into the commands variable"""
  8. files = os.listdir(os.path.join("irc", "commands")) # get all files in irc/commands/
  9. files.sort() # alphabetically sort list of files
  10. for f in files:
  11. if f.startswith("_") or not f.endswith(".py"): # ignore non-python files or files beginning with "_"
  12. continue
  13. module = f[:-3] # strip .py from end
  14. try:
  15. exec "from irc.commands import %s" % module
  16. except: # importing the file failed for some reason...
  17. print "Couldn't load file %s:" % f
  18. traceback.print_exc()
  19. continue
  20. process_module(connection, eval(module)) # 'module' is a string, so get the actual object for processing by eval-ing it
  21. pretty_cmnds = map(lambda c: c.__class__.__name__, commands)
  22. print "Found %s command classes: %s." % (len(commands), ', '.join(pretty_cmnds))
  23. def process_module(connection, module):
  24. """go through all objects in a module and add valid command classes to the commands variable"""
  25. global commands
  26. objects = dir(module)
  27. for this_obj in objects: # go through everything in the file
  28. obj = eval("module.%s" % this_obj) # this_obj is a string, so get the actual object corresponding to that string
  29. try:
  30. bases = obj.__bases__
  31. except AttributeError: # object isn't a valid class, so ignore it
  32. continue
  33. for base in bases:
  34. if base.__name__ == "BaseCommand": # this inherits BaseCommand, so it must be a command class
  35. command = obj(connection) # initialize a new command object
  36. commands.append(command)
  37. print "Added command class %s from %s..." % (this_obj, module.__name__)
  38. continue
  39. def get_commands():
  40. """get our commands"""
  41. return commands
  42. def check(hook, data):
  43. """given an event on IRC, check if there's anything we can respond to by calling each command class"""
  44. data.parse_args() # parse command arguments into data.command and data.args
  45. for command in commands:
  46. if hook in command.get_hooks():
  47. if command.check(data):
  48. try:
  49. command.process(data)
  50. except:
  51. print "Error executing command '{}':".format(data.command)
  52. traceback.print_exc() # catch exceptions and print them
  53. break