A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

91 Zeilen
2.7 KiB

  1. # -*- coding: utf-8 -*-
  2. """
  3. EarwigBot's IRC Command Manager
  4. This package provides the IRC "commands" used by the bot's front-end component.
  5. In __init__, you can find some functions used to load and run these commands.
  6. """
  7. import os
  8. import sys
  9. import traceback
  10. from classes import BaseCommand
  11. import config
  12. __all__ = ["load", "get_all", "check"]
  13. # Base directory when searching for commands:
  14. base_dir = os.path.join(config.root_dir, "bot", "commands")
  15. # Store commands in a dict, where the key is the command's name and the value
  16. # is an instance of the command's class:
  17. _commands = {}
  18. def _load_command(connection, filename):
  19. """Try to load a specific command from a module, identified by file name.
  20. Given a Connection object and a filename, we'll first try to import it,
  21. and if that works, make an instance of the 'Command' class inside (assuming
  22. it is an instance of BaseCommand), add it to _commands, and report the
  23. addition to the user. Any problems along the way will either be ignored or
  24. reported.
  25. """
  26. global _commands
  27. # Strip .py from the end of the filename and join with our package name:
  28. name = ".".join(("commands", filename[:-3]))
  29. try:
  30. __import__(name)
  31. except:
  32. print "Couldn't load file {0}:".format(filename)
  33. traceback.print_exc()
  34. return
  35. command = sys.modules[name].Command(connection)
  36. if not isinstance(command, BaseCommand):
  37. return
  38. _commands[command.name] = command
  39. print "Added command {0}...".format(command.name)
  40. def load(connection):
  41. """Load all valid commands into the _commands global variable.
  42. `connection` is a Connection object that is given to each command's
  43. constructor.
  44. """
  45. files = os.listdir(base_dir)
  46. files.sort()
  47. for filename in files:
  48. if filename.startswith("_") or not filename.endswith(".py"):
  49. continue
  50. try:
  51. _load_command(connection, filename)
  52. except AttributeError:
  53. pass # The file is doesn't contain a command, so just move on
  54. msg = "Found {0} command classes: {1}."
  55. print msg.format(len(_commands), ", ".join(_commands.keys()))
  56. def get_all():
  57. """Return our dict of all loaded commands."""
  58. return _commands
  59. def check(hook, data):
  60. """Given an event on IRC, check if there's anything we can respond to."""
  61. # Parse command arguments into data.command and data.args:
  62. data.parse_args()
  63. for command in _commands.values():
  64. if hook in command.hooks:
  65. if command.check(data):
  66. try:
  67. command.process(data)
  68. except:
  69. print "Error executing command '{0}':".format(data.command)
  70. traceback.print_exc()
  71. break