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.

71 lines
2.6 KiB

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