module.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from logger import Logger
  2. from event import Event
  3. class Module:
  4. def __init__(self, events=None, printer_handle=None, bot=None, say=None):
  5. self.events = events
  6. self.printer = printer_handle
  7. self.bot = bot
  8. self.interests = []
  9. self.say = say
  10. self.cmd = None
  11. self.help = None
  12. mod = Event("__.module__")
  13. mod.define(msg_definition="^\.module ")
  14. mod.subscribe(self)
  15. self.bot.register_event(mod, self)
  16. #for event in events:
  17. # if event._type in self.interests:
  18. # event.subscribe(self)
  19. def handle(self, event):
  20. #if not self.bot.conf.getOwner(self.bot.network) == event.user:
  21. if not self.bot.brain._isAdmin(event.user):
  22. return
  23. if event.msg.startswith(".module load"):
  24. self.bot.logger.write(Logger.INFO, " loading " + event.msg.split()[2] + "...", self.bot.NICK)
  25. retval = self.load(event.msg.split()[2])
  26. if retval == 0:
  27. self.bot.logger.write(Logger.INFO, " loaded " + event.msg.split()[2])
  28. self.bot.brain.notice(event.channel, "loaded " + event.msg.split()[2])
  29. elif retval == 2:
  30. self.bot.logger.write(Logger.INFO, " load failed; " + event.msg.split()[2] + " is already loaded")
  31. self.bot.brain.notice(event.channel, "load failed; " + event.msg.split()[2] + " is already loaded")
  32. else:
  33. self.bot.logger.write(Logger.WARNING, " failed to load " + event.msg.split()[2], self.bot.NICK)
  34. self.bot.brain.notice(event.channel, "failed to load " + event.msg.split()[2])
  35. if event.msg == ".module eventslist":
  36. events_set = set()
  37. for m in self.bot.events_list:
  38. events_set.add(m._type)
  39. message = ""
  40. for s in sorted(events_set):
  41. message += s + ", "
  42. self.say(event.user, message[:-2] + '\n') # needs newline at the end, and we remove the final comma
  43. if event.msg.startswith(".module list"):
  44. # the set prevents a module with multiple events being printed more than once
  45. modules_set = set()
  46. for m in self.bot.events_list:
  47. for s in m.subscribers:
  48. modules_set.add(s.__class__.__name__)
  49. message = ""
  50. for s in sorted(modules_set):
  51. message += s + ", "
  52. self.say(event.user, message[:-2] + '\n') # needs newline at the end, and we remove the final comma
  53. return
  54. if event.msg.startswith(".module unload"):
  55. if self.unload(event.msg.split()[2]):
  56. self.printer("NOTICE " + event.channel + " :unloaded " + event.msg.split()[2] + '\n')
  57. else:
  58. self.printer("NOTICE " + event.channel + " :failed to unload " + event.msg.split()[2] + '\n')
  59. """careful here: XXX - unloading looks it up by class name, and the bot's loading module looks it up by filename
  60. - this can lead to situations where you just reload a module over and over instead of unloading it
  61. because the module name and class name differ """
  62. if event.msg.startswith(".module reload"): # perform both unloading and reloading
  63. # first unload
  64. for m in self.bot.events_list:
  65. for s in m.subscribers:
  66. try:
  67. if event.msg.split()[2].lower() == s.__class__.__name__.lower():
  68. #self.printer("NOTICE " + event.channel + " :unloaded " + event.msg.split()[2] + '\n')
  69. # the events themselves hold onto the subscribing modules, so just remove that one.
  70. m.subscribers.remove(s)
  71. except IndexError:
  72. return
  73. # then load
  74. #self.bot.logger.write(Logger.INFO, " loading " + event.msg.split()[2] + "...")
  75. retval = self.load(event.msg.split()[2])
  76. if retval == 0:
  77. self.bot.logger.write(Logger.INFO, " reloaded " + event.msg.split()[2], self.bot.NICK)
  78. self.bot.brain.notice(event.channel, "reloaded " + event.msg.split()[2])
  79. else:
  80. self.bot.logger.write(Logger.WARNING, " failed to reload " + event.msg.split()[2], self.bot.NICK)
  81. self.bot.brain.notice(event.channel, "failed to reload " + event.msg.split()[2])
  82. def unload(self, modulename):
  83. unloaded_successfully = False
  84. for m in self.bot.events_list:
  85. for s in m.subscribers:
  86. if modulename == s.__class__.__name__.lower():
  87. # the events themselves hold onto the subscribing modules, so just remove that one.
  88. m.subscribers.remove(s)
  89. unloaded_successfully = True
  90. return unloaded_successfully
  91. def load(self, modulename):
  92. # this may seem redundant, but modules may become unloaded in between calls.
  93. modules_set = set()
  94. for m in self.bot.events_list:
  95. for s in m.subscribers:
  96. modules_set.add(s.__class__.__name__.lower())
  97. if modulename in modules_set:
  98. return 2
  99. return self.bot.load_modules(specific=modulename)