2003-03-12 07:26:59 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
###
|
|
|
|
# Copyright (c) 2002, Jeremiah Fincher
|
|
|
|
# All rights reserved.
|
|
|
|
#
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
# modification, are permitted provided that the following conditions are met:
|
|
|
|
#
|
|
|
|
# * Redistributions of source code must retain the above copyright notice,
|
|
|
|
# this list of conditions, and the following disclaimer.
|
|
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
# this list of conditions, and the following disclaimer in the
|
|
|
|
# documentation and/or other materials provided with the distribution.
|
|
|
|
# * Neither the name of the author of this software nor the name of
|
|
|
|
# contributors to this software may be used to endorse or promote products
|
|
|
|
# derived from this software without specific prior written consent.
|
|
|
|
#
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
###
|
|
|
|
|
|
|
|
"""
|
|
|
|
Contains various drivers (network, file, and otherwise) for using IRC objects.
|
|
|
|
"""
|
|
|
|
|
2003-11-25 09:38:19 +01:00
|
|
|
__revision__ = "$Id$"
|
|
|
|
|
2003-10-05 14:47:19 +02:00
|
|
|
import fix
|
2003-03-12 07:26:59 +01:00
|
|
|
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
|
2003-11-26 19:21:12 +01:00
|
|
|
import log
|
2003-04-20 01:52:34 +02:00
|
|
|
import conf
|
2003-03-12 07:26:59 +01:00
|
|
|
import ansi
|
|
|
|
import ircmsgs
|
|
|
|
|
|
|
|
_drivers = {}
|
|
|
|
_deadDrivers = []
|
|
|
|
_newDrivers = []
|
|
|
|
|
|
|
|
class IrcDriver(object):
|
2003-10-04 13:47:21 +02:00
|
|
|
"""Base class for drivers."""
|
2003-03-12 07:26:59 +01:00
|
|
|
def __init__(self):
|
|
|
|
_newDrivers.append((self.name(), self))
|
|
|
|
if not hasattr(self, 'irc'):
|
|
|
|
self.irc = None # This is to satisfy PyChecker.
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def die(self):
|
|
|
|
# The end of any overrided die method should be
|
2004-01-01 21:12:40 +01:00
|
|
|
# "super(Class, self).die()", in order to make
|
2003-03-12 07:26:59 +01:00
|
|
|
# sure this (and anything else later added) is done.
|
|
|
|
_deadDrivers.append(self.name())
|
|
|
|
|
2004-01-01 21:12:40 +01:00
|
|
|
def reconnect(self, wait=False):
|
2003-04-21 06:32:42 +02:00
|
|
|
raise NotImplementedError
|
|
|
|
|
2003-03-12 07:26:59 +01:00
|
|
|
def name(self):
|
2003-09-03 13:06:02 +02:00
|
|
|
return repr(self)
|
2003-03-12 07:26:59 +01:00
|
|
|
|
|
|
|
def empty():
|
2003-10-04 13:47:21 +02:00
|
|
|
"""Returns whether or not the driver loop is empty."""
|
2003-03-12 07:26:59 +01:00
|
|
|
return (len(_drivers) + len(_newDrivers)) == 0
|
|
|
|
|
|
|
|
def add(name, driver):
|
2003-10-04 13:47:21 +02:00
|
|
|
"""Adds a given driver the loop with the given name."""
|
2003-03-12 07:26:59 +01:00
|
|
|
_newDrivers.append((name, driver))
|
|
|
|
|
|
|
|
def remove(name):
|
2003-10-04 13:47:21 +02:00
|
|
|
"""Removes the driver with the given name from the loop."""
|
2003-03-12 07:26:59 +01:00
|
|
|
_deadDrivers.append(name)
|
|
|
|
|
|
|
|
def run():
|
2003-10-04 13:47:21 +02:00
|
|
|
"""Runs the whole driver loop."""
|
2003-03-12 07:26:59 +01:00
|
|
|
for (name, driver) in _drivers.iteritems():
|
|
|
|
try:
|
|
|
|
if name not in _deadDrivers:
|
|
|
|
driver.run()
|
|
|
|
except:
|
2003-11-26 19:21:12 +01:00
|
|
|
log.exception('Uncaught exception in in drivers.run:')
|
2003-03-12 07:26:59 +01:00
|
|
|
_deadDrivers.append(name)
|
|
|
|
for name in _deadDrivers:
|
|
|
|
try:
|
2004-01-20 17:07:03 +01:00
|
|
|
driver = _drivers[name]
|
2004-02-12 07:50:26 +01:00
|
|
|
if hasattr(driver, 'irc') and driver.irc is not None:
|
|
|
|
# The Schedule driver has no irc object, or it's None.
|
|
|
|
driver.irc.driver = None
|
2004-01-20 17:07:03 +01:00
|
|
|
driver.irc = None
|
2003-03-12 07:26:59 +01:00
|
|
|
del _drivers[name]
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
while _newDrivers:
|
2003-10-04 13:47:21 +02:00
|
|
|
(name, driver) = _newDrivers.pop()
|
|
|
|
if name in _drivers:
|
|
|
|
_drivers[name].die()
|
|
|
|
del _drivers[name]
|
|
|
|
_drivers[name] = driver
|
2003-04-20 01:52:34 +02:00
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
def newDriver(server, irc, moduleName=None):
|
|
|
|
"""Returns a new driver for the given server using the irc given and using
|
|
|
|
conf.supybot.driverModule to determine what driver to pick."""
|
|
|
|
if moduleName is None:
|
|
|
|
moduleName = conf.supybot.drivers.module()
|
2004-04-30 04:13:42 +02:00
|
|
|
if moduleName == 'default':
|
|
|
|
try:
|
|
|
|
import twistedDrivers
|
|
|
|
moduleName = 'twistedDrivers'
|
|
|
|
except ImportError:
|
|
|
|
del sys.modules['twistedDrivers']
|
|
|
|
moduleName = 'socketDrivers'
|
2003-04-20 01:52:34 +02:00
|
|
|
driver = __import__(moduleName).Driver(server, irc)
|
|
|
|
irc.driver = driver
|
|
|
|
return driver
|
|
|
|
|
2003-03-24 09:41:19 +01:00
|
|
|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|