long list of changes to allow modular Module reloads: server as module variable, class appends self to module list, unregister_handlers method which must be overridden, reload method which does the magic to create the a new object of the re-read class. drop use of the main rehash and reload_modules, and don't pass rehash around anymore. load initial objects 'the old way' again. feature modules change for compatability and implementation of all of the above changes
This commit is contained in:
parent
b5062171f9
commit
57090fdda4
34
Module.py
34
Module.py
|
@ -14,7 +14,9 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import inspect
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
from irclib import irclib
|
from irclib import irclib
|
||||||
|
|
||||||
|
@ -31,12 +33,14 @@ class Module(object):
|
||||||
# modules to call do and see if anything can handle text they may have seen (such
|
# modules to call do and see if anything can handle text they may have seen (such
|
||||||
# as in recursive commands).
|
# as in recursive commands).
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.server = server
|
||||||
self.modlist = modlist
|
self.modlist = modlist
|
||||||
self.register_handlers(server)
|
self.register_handlers(server)
|
||||||
# Should do some error handling here.
|
|
||||||
self.rehash = rehash # Is there another way to call the rehash function in dr.botzo?
|
# add self to the object list
|
||||||
|
modlist.append(self)
|
||||||
|
|
||||||
# print what was loaded, for debugging
|
# print what was loaded, for debugging
|
||||||
print("loaded " + self.__class__.__name__)
|
print("loaded " + self.__class__.__name__)
|
||||||
|
@ -53,6 +57,15 @@ class Module(object):
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
print "looks like someone forgot to implement register_handlers!"
|
print "looks like someone forgot to implement register_handlers!"
|
||||||
|
|
||||||
|
# This is called by reload, to remove the soon-to-be old object from the server
|
||||||
|
# global handlers (or whatever has been added via register_handlers). Classes
|
||||||
|
# inheriting from Module should implement this, e.g.:
|
||||||
|
#
|
||||||
|
# server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
print "looks like someone forgot to implement unregister_handlers!"
|
||||||
|
|
||||||
# Does some variable setup and initial sanity checking before calling Module.do,
|
# Does some variable setup and initial sanity checking before calling Module.do,
|
||||||
# which should be implemented by subclasses and what can be ultimately responsible
|
# which should be implemented by subclasses and what can be ultimately responsible
|
||||||
# for the work. Of course, you are free to reimplement on_pubmsg on your own too.
|
# for the work. Of course, you are free to reimplement on_pubmsg on your own too.
|
||||||
|
@ -82,6 +95,9 @@ class Module(object):
|
||||||
if replypath is not None:
|
if replypath is not None:
|
||||||
what = self.try_recursion(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
what = self.try_recursion(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
|
# try reloading
|
||||||
|
self.reload(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
# Does some variable setup and initial sanity checking before calling Module.do,
|
# Does some variable setup and initial sanity checking before calling Module.do,
|
||||||
|
@ -106,6 +122,18 @@ class Module(object):
|
||||||
|
|
||||||
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
|
# If the command given was to reload, reload this module.
|
||||||
|
|
||||||
|
def reload(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
|
whats = what.split(' ')
|
||||||
|
if whats[0] == 'reload' and admin_unlocked:
|
||||||
|
reload(sys.modules[self.__module__])
|
||||||
|
for name, obj in inspect.getmembers(sys.modules[self.__module__]):
|
||||||
|
if inspect.isclass(obj) and str(obj).find(self.__module__) > 0:
|
||||||
|
self.modlist.remove(self)
|
||||||
|
self.unregister_handlers()
|
||||||
|
obj(self.config, self.server, self.modlist)
|
||||||
|
|
||||||
# Upon seeing a line intended for this module, see if there are subcommands
|
# Upon seeing a line intended for this module, see if there are subcommands
|
||||||
# that we should do what is basically a text replacement on. The intent is to
|
# that we should do what is basically a text replacement on. The intent is to
|
||||||
# allow things like the following:
|
# allow things like the following:
|
||||||
|
|
53
dr.botzo.py
53
dr.botzo.py
|
@ -39,45 +39,6 @@ class DrBotIRC(irclib.IRC):
|
||||||
self.connections.append(c)
|
self.connections.append(c)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
# This finds all the currently loaded modules that start with "modules" (as all
|
|
||||||
# the bot modules are currently in a subfolder called modules) and calls
|
|
||||||
# reload() on them. This will only work if the folder name doesn't change.
|
|
||||||
|
|
||||||
def rehash():
|
|
||||||
myre = re.compile('modules')
|
|
||||||
for i in sys.modules:
|
|
||||||
currMod = sys.modules[i]
|
|
||||||
if currMod is not None and myre.search(i):
|
|
||||||
reload(currMod)
|
|
||||||
|
|
||||||
# Remove the pubmsg and privmsg handlers from the irclib object.
|
|
||||||
# If we don't do this we will see phantom messages
|
|
||||||
for obj in modObjs:
|
|
||||||
server.remove_global_handler('pubmsg', obj.on_pubmsg)
|
|
||||||
server.remove_global_handler('privmsg', obj.on_privmsg)
|
|
||||||
|
|
||||||
reload_modules(moduleList)
|
|
||||||
|
|
||||||
# Create the actual module objects, which will readd the handlers we removed
|
|
||||||
# earlier, and add them to the modObjs list, which we can use during the
|
|
||||||
# next rehash to remove the handlers.
|
|
||||||
|
|
||||||
def reload_modules(moduleList):
|
|
||||||
for mod in moduleList:
|
|
||||||
cls = globals()[mod]
|
|
||||||
|
|
||||||
# Importing the names imports a module since the file name and class
|
|
||||||
# name are the same. Look for the class definition in each module
|
|
||||||
# with the same name and create that object.
|
|
||||||
|
|
||||||
if inspect.ismodule(cls):
|
|
||||||
for name, obj in inspect.getmembers(cls):
|
|
||||||
if inspect.isclass(obj) and re.search(mod, obj.__name__):
|
|
||||||
modObjs.append(obj(config, server, modlist, rehash))
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
modObjs.append(cls(config, server, modlist, rehash))
|
|
||||||
|
|
||||||
# read config file
|
# read config file
|
||||||
|
|
||||||
config = ConfigParser({'debug': 'false'})
|
config = ConfigParser({'debug': 'false'})
|
||||||
|
@ -104,14 +65,12 @@ irclib.DEBUG = config.getboolean('IRC', 'debug')
|
||||||
irc = DrBotIRC()
|
irc = DrBotIRC()
|
||||||
server = irc.server().connect(botserver, botport, botnick, botircname)
|
server = irc.server().connect(botserver, botport, botnick, botircname)
|
||||||
|
|
||||||
reload_modules(moduleList)
|
count = Countdown.Countdown(config, server, modlist)
|
||||||
|
dice = Dice.Dice(config, server, modlist)
|
||||||
#count = Countdown(config, server, modlist)
|
fact = FactFile.FactFile(config, server, modlist)
|
||||||
#dice = Dice(config, server, modlist)
|
admin = IrcAdmin.IrcAdmin(config, server, modlist)
|
||||||
#fact = FactFile(config, server, modlist)
|
gt = GoogleTranslate.GoogleTranslate(config, server, modlist)
|
||||||
#admin = IrcAdmin(config, server, modlist)
|
seen = Seen.Seen(config, server, modlist)
|
||||||
#gt = GoogleTranslate(config, server, modlist)
|
|
||||||
#seen = Seen(config, server, modlist)
|
|
||||||
|
|
||||||
# loop forever
|
# loop forever
|
||||||
irc.process_forever()
|
irc.process_forever()
|
||||||
|
|
|
@ -24,14 +24,18 @@ from Module import Module
|
||||||
|
|
||||||
class Countdown(Module):
|
class Countdown(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(Countdown, self).__init__(config, server, modlist, rehash)
|
super(Countdown, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
whats = what.split(' ')
|
whats = what.split(' ')
|
||||||
if whats[0] == 'countdown' and len(whats) >= 2:
|
if whats[0] == 'countdown' and len(whats) >= 2:
|
||||||
|
|
|
@ -25,14 +25,18 @@ from Module import Module
|
||||||
|
|
||||||
class Dice(Module):
|
class Dice(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(Dice, self).__init__(config, server, modlist, rehash)
|
super(Dice, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
overallroll = what
|
overallroll = what
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,18 @@ from Module import Module
|
||||||
|
|
||||||
class FactFile(Module):
|
class FactFile(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(FactFile, self).__init__(config, server, modlist, rehash)
|
super(FactFile, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
whats = what.split(' ')
|
whats = what.split(' ')
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -27,14 +27,18 @@ from Module import Module
|
||||||
|
|
||||||
class GoogleTranslate(Module):
|
class GoogleTranslate(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(GoogleTranslate, self).__init__(config, server, modlist, rehash)
|
super(GoogleTranslate, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
whats = what.split(' ')
|
whats = what.split(' ')
|
||||||
if whats[0] == 'translate' and len(whats) >= 4:
|
if whats[0] == 'translate' and len(whats) >= 4:
|
||||||
|
|
|
@ -24,8 +24,8 @@ from Module import Module
|
||||||
|
|
||||||
class IrcAdmin(Module):
|
class IrcAdmin(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(IrcAdmin, self).__init__(config, server, modlist, rehash)
|
super(IrcAdmin, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
|
@ -33,6 +33,11 @@ class IrcAdmin(Module):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('welcome', self.on_connect)
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
def on_connect(self, connection, event):
|
def on_connect(self, connection, event):
|
||||||
"""handler for when the bot has connected to IRC
|
"""handler for when the bot has connected to IRC
|
||||||
"""
|
"""
|
||||||
|
@ -62,17 +67,6 @@ class IrcAdmin(Module):
|
||||||
self.sub_autojoin_manipulate(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.sub_autojoin_manipulate(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
self.sub_save_config(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.sub_save_config(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
self.sub_change_nick(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.sub_change_nick(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
self.sub_rehash(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
|
||||||
|
|
||||||
def sub_rehash(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
|
||||||
whats = what.split(' ')
|
|
||||||
if whats[0] == 'rehash' and admin_unlocked:
|
|
||||||
self.rehash()
|
|
||||||
replystr = 'rehashed modules'
|
|
||||||
if replypath is None:
|
|
||||||
return replystr
|
|
||||||
else:
|
|
||||||
connection.privmsg(replypath, replystr)
|
|
||||||
|
|
||||||
def sub_join_channel(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def sub_join_channel(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
whats = what.split(' ')
|
whats = what.split(' ')
|
||||||
|
|
|
@ -28,14 +28,18 @@ from Module import Module
|
||||||
|
|
||||||
class Seen(Module):
|
class Seen(Module):
|
||||||
|
|
||||||
def __init__(self, config, server, modlist, rehash):
|
def __init__(self, config, server, modlist):
|
||||||
super(Seen, self).__init__(config, server, modlist, rehash)
|
super(Seen, self).__init__(config, server, modlist)
|
||||||
modlist.append(self)
|
modlist.append(self)
|
||||||
|
|
||||||
def register_handlers(self, server):
|
def register_handlers(self, server):
|
||||||
server.add_global_handler('pubmsg', self.on_pubmsg)
|
server.add_global_handler('pubmsg', self.on_pubmsg)
|
||||||
server.add_global_handler('privmsg', self.on_privmsg)
|
server.add_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
|
def unregister_handlers(self):
|
||||||
|
self.server.remove_global_handler('pubmsg', self.on_pubmsg)
|
||||||
|
self.server.remove_global_handler('privmsg', self.on_privmsg)
|
||||||
|
|
||||||
# Overriding the default because we need stuff to occur before the addressed
|
# Overriding the default because we need stuff to occur before the addressed
|
||||||
# and so on checks.
|
# and so on checks.
|
||||||
|
|
||||||
|
@ -70,6 +74,9 @@ class Seen(Module):
|
||||||
if replypath is not None:
|
if replypath is not None:
|
||||||
what = self.try_recursion(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
what = self.try_recursion(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
|
# try reloading
|
||||||
|
self.reload(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
self.do(connection, event, nick, userhost, replypath, what, admin_unlocked)
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked):
|
||||||
|
|
Loading…
Reference in New Issue