# dr.botzo - a pluggable IRC bot written in Python # Copyright (C) 2010 Brian S. Stephan # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from ConfigParser import ConfigParser, NoSectionError, NoOptionError from datetime import datetime import os import random import re import sys import inspect from urllib2 import urlopen from urllib import urlencode from dateutil.parser import * from dateutil.relativedelta import * from dateutil.tz import * from irclib import irclib from modules import * modlist = [] moduleList = [ "Countdown", "Dice", "IrcAdmin", "GoogleTranslate", "Seen", "FactFile" ] modObjs = [] class DrBotServerConnection(irclib.ServerConnection): def privmsg(self, target, text): # Send a PRIVMSG command. # TODO: length limiting or splitting self.send_raw("PRIVMSG %s :%s" % (target, text)) class DrBotIRC(irclib.IRC): def server(self): c = DrBotServerConnection(self) self.connections.append(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 config = ConfigParser({'debug': 'false'}) config.read([os.path.expanduser('~/.dr.botzo.cfg'), 'dr.botzo.cfg']) # load necessary options try: # load connection info botserver = config.get('IRC', 'server') botport = config.getint('IRC', 'port') botnick = config.get('IRC', 'nick') botircname = config.get('IRC', 'name') except NoSectionError as e: sys.exit("Aborted due to error with necessary configuration: " + str(e)) except NoOptionError as e: sys.exit("Aborted due to error with necessary configuration: " + str(e)) # load additional options irclib.DEBUG = config.getboolean('IRC', 'debug') # start up the IRC bot # create IRC and server objects and connect irc = DrBotIRC() server = irc.server().connect(botserver, botport, botnick, botircname) reload_modules(moduleList) #count = Countdown(config, server, modlist) #dice = Dice(config, server, modlist) #fact = FactFile(config, server, modlist) #admin = IrcAdmin(config, server, modlist) #gt = GoogleTranslate(config, server, modlist) #seen = Seen(config, server, modlist) # loop forever irc.process_forever() # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on;