Brian S. Stephan
52b740a52c
the reasoning behind this is that we may want to load one object but have it connect to multiple servers. this allows that.
131 lines
4.3 KiB
Python
131 lines
4.3 KiB
Python
"""
|
|
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 <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
|
|
import os
|
|
import re
|
|
import socket
|
|
import sys
|
|
import inspect
|
|
|
|
from extlib import irclib
|
|
|
|
from modules import *
|
|
|
|
modlist = []
|
|
moduleList = [ "Countdown", "Dice", "IrcAdmin", "GoogleTranslate", "Seen", "FactFile" ]
|
|
modObjs = []
|
|
|
|
class DrBotServerConnection(irclib.ServerConnection):
|
|
"""Subclass irclib's ServerConnection, in order to expand privmsg."""
|
|
|
|
def privmsg(self, target, text):
|
|
"""Send a PRIVMSG command."""
|
|
splitter = "..."
|
|
|
|
# split messages that are too long. Max length is 512.
|
|
# TODO: this does not properly handle when the hostname has been
|
|
# masked by the ircd
|
|
space = 512 - len('\r\n') - len('PRIVMSG ') - len(' :') - len(target) - len(self.nickname) - len('!') - len(self.username) - len('@') - len(socket.getfqdn())
|
|
splitspace = space - (len(splitter) + 1)
|
|
|
|
if len(text) > space:
|
|
times = 1
|
|
|
|
while len(text) > splitspace:
|
|
splitpos = text.rfind(' ', 0, splitspace)
|
|
splittext = text[0:splitpos] + ' ' + splitter
|
|
text = splitter + ' ' + text[splitpos+1:]
|
|
self.send_raw("PRIVMSG %s :%s" % (target, unicode(splittext).encode('utf-8')))
|
|
|
|
times = times + 1
|
|
if times >= 4:
|
|
return
|
|
|
|
# done splitting
|
|
try:
|
|
text = unicode(text).encode('utf-8')
|
|
except UnicodeDecodeError: pass
|
|
self.send_raw("PRIVMSG %s :%s" % (target, text))
|
|
else:
|
|
try:
|
|
text = unicode(text).encode('utf-8')
|
|
except UnicodeDecodeError: pass
|
|
self.send_raw("PRIVMSG %s :%s" % (target, text))
|
|
|
|
class DrBotIRC(irclib.IRC):
|
|
"""Subclass irclib's IRC, in order to create a DrBotServerConnection."""
|
|
|
|
def server(self):
|
|
c = DrBotServerConnection(self)
|
|
self.connections.append(c)
|
|
return c
|
|
|
|
# check argv
|
|
if len(sys.argv) != 2:
|
|
sys.exit("Needs one argument, the config filename")
|
|
|
|
# read config file
|
|
|
|
config = ConfigParser({'debug': 'false'})
|
|
#config.read([os.path.expanduser('~/.dr.botzo.cfg'), 'dr.botzo.cfg'])
|
|
config.read(os.path.expanduser(sys.argv[1]))
|
|
|
|
# load necessary options
|
|
try:
|
|
# load connection info
|
|
botserver = config.get('dr.botzo', 'server')
|
|
botport = config.getint('dr.botzo', 'port')
|
|
botnick = config.get('dr.botzo', 'nick')
|
|
botpass = config.get('dr.botzo', 'pass')
|
|
botuser = config.get('dr.botzo', 'user')
|
|
botircname = config.get('dr.botzo', '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('dr.botzo', 'debug')
|
|
|
|
# start up the IRC bot
|
|
|
|
# create IRC and server objects and connect
|
|
irc = DrBotIRC()
|
|
server = irc.server().connect(botserver, botport, botnick, botpass, botuser, botircname)
|
|
|
|
# load features
|
|
try:
|
|
cfgmodlist = config.get('dr.botzo', 'module_list')
|
|
|
|
mods = cfgmodlist.split(',')
|
|
for mod in mods:
|
|
# try to load each module
|
|
module = eval(mod + '.' + mod + '(config, server, modlist)')
|
|
module.attach_to_server(server)
|
|
except NoSectionError as e:
|
|
print("You seem to be missing a modules config section, which you probably wanted.")
|
|
except NoOptionError as e:
|
|
print("You seem to be missing a modlist config option, which you probably wanted.")
|
|
|
|
# loop forever
|
|
irc.process_forever()
|
|
|
|
# vi:tabstop=4:expandtab:autoindent
|
|
# kate: indent-mode python;indent-width 4;replace-tabs on;
|