Network plugin for network-related commands.

This commit is contained in:
Jeremy Fincher 2004-09-12 05:46:18 +00:00
parent dfef079480
commit a9694c1012
5 changed files with 275 additions and 293 deletions

View File

@ -30,124 +30,253 @@
### ###
""" """
Various network-related commands. Includes commands for connecting, disconnecting, and reconnecting to multiple
networks, as well as several other utility functions related to IRC networks.
""" """
import supybot
__revision__ = "$Id$" __revision__ = "$Id$"
__author__ = supybot.authors.jemfinch
import supybot.plugins as plugins import supybot.plugins as plugins
import sets import time
import socket
import telnetlib
import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
import supybot.world as world
import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs import supybot.privmsgs as privmsgs
import supybot.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
class Network(callbacks.Privmsg): class Network(callbacks.Privmsg):
threaded = True _whois = {}
def dns(self, irc, msg, args): def _getIrc(self, network):
"""<host|ip> network = network.lower()
for irc in world.ircs:
if irc.network.lower() == network:
return irc
raise callbacks.Error, 'I\'m not currently connected to %s.' % network
Returns the ip of <host> or the reverse DNS hostname of <ip>. def _getNetwork(self, irc, args):
try:
self._getIrc(args[0])
return args.pop(0)
except (callbacks.Error, IndexError):
return irc.network
def connect(self, irc, msg, args):
"""<network> [<host[:port]>]
Connects to another network at <host:port>. If port is not provided, it
defaults to 6667, the default port for IRC.
""" """
host = privmsgs.getArgs(args) (network, server) = privmsgs.getArgs(args, optional=1)
if utils.isIP(host): try:
hostname = socket.getfqdn(host) otherIrc = self._getIrc(network)
if hostname == host: irc.error('I\'m already connected to %s.' % network, Raise=True)
irc.reply('Host not found.') except callbacks.Error:
pass
if server:
if ':' in server:
(server, port) = server.split(':')
port = int(port)
else: else:
irc.reply(hostname) port = 6667
serverPort = (server, port)
else: else:
try: try:
ip = socket.gethostbyname(host) serverPort = conf.supybot.networks.get(network).servers()[0]
if ip == '64.94.110.11': # Verisign sucks! except (registry.NonExistentRegistryEntry, IndexError):
irc.reply('Host not found.') irc.error('A server must be provided if the network is not '
else: 'already registered.')
irc.reply(ip) return
except socket.error: Owner = irc.getCallback('Owner')
irc.reply('Host not found.') newIrc = Owner._connect(network, serverPort=serverPort)
conf.supybot.networks().add(network)
assert newIrc.callbacks is irc.callbacks, 'callbacks list is different'
irc.replySuccess('Connection to %s initiated.' % network)
connect = privmsgs.checkCapability(connect, 'owner')
_tlds = sets.Set(['com', 'net', 'edu']) def disconnect(self, irc, msg, args):
_registrar = ['Sponsoring Registrar', 'Registrar', 'source'] """[<network>] [<quit message>]
_updated = ['Last Updated On', 'Domain Last Updated Date', 'Updated Date',
'Last Modified', 'changed']
_created = ['Created On', 'Domain Registration Date', 'Creation Date']
_expires = ['Expiration Date', 'Domain Expiration Date']
_status = ['Status', 'Domain Status', 'status']
def whois(self, irc, msg, args):
"""<domain>
Returns WHOIS information on the registration of <domain>. Disconnects from the network represented by the network <network>.
If <quit message> is given, quits the network with the given quit
message. <network> is only necessary if the network is different
from the network the command is sent on.
""" """
domain = privmsgs.getArgs(args) network = self._getNetwork(irc, args)
usertld = domain.split('.')[-1] quitMsg = privmsgs.getArgs(args, required=0, optional=1)
if '.' not in domain: if not quitMsg:
irc.error('<domain> must be in .com, .net, .edu, or .org.') quitMsg = msg.nick
otherIrc = self._getIrc(network)
# replySuccess here, rather than lower, in case we're being
# told to disconnect from the network we received the command on.
irc.replySuccess()
otherIrc.queueMsg(ircmsgs.quit(quitMsg))
otherIrc.die()
conf.supybot.networks().discard(network)
disconnect = privmsgs.checkCapability(disconnect, 'owner')
def reconnect(self, irc, msg, args):
"""[<network>]
Disconnects and then reconnects to <network>. If no network is given,
disconnects and then reconnects to the network the command was given
on.
"""
network = self._getNetwork(irc, args)
badIrc = self._getIrc(network)
try:
badIrc.driver.reconnect()
if badIrc != irc:
# No need to reply if we're reconnecting ourselves.
irc.replySuccess()
except AttributeError: # There's a cleaner way to do this, but I'm lazy.
irc.error('I couldn\'t reconnect. You should restart me instead.')
reconnect = privmsgs.checkCapability(reconnect, 'owner')
def command(self, irc, msg, args):
"""<network> <command> [<arg> ...]
Gives the bot <command> (with its associated <arg>s) on <network>.
"""
if len(args) < 2:
raise callbacks.ArgumentError
network = args.pop(0)
otherIrc = self._getIrc(network)
Owner = irc.getCallback('Owner')
Owner.disambiguate(irc, args)
self.Proxy(otherIrc, msg, args)
command = privmsgs.checkCapability(command, 'admin')
###
# whois command-related stuff.
###
def do311(self, irc, msg):
nick = ircutils.toLower(msg.args[1])
if (irc, nick) not in self._whois:
return return
elif len(domain.split('.')) != 2:
irc.error('<domain> must be a domain, not a hostname.')
return
if usertld in self._tlds:
server = 'rs.internic.net'
search = '=%s' % domain
else: else:
server = '%s.whois-servers.net' % usertld self._whois[(irc, nick)][-1][msg.command] = msg
search = domain
try: # These are all sent by a WHOIS response.
t = telnetlib.Telnet(server, 43) do301 = do311
except socket.error, e: do312 = do311
irc.error(str(e)) do317 = do311
do319 = do311
do320 = do311
def do318(self, irc, msg):
nick = msg.args[1]
loweredNick = ircutils.toLower(nick)
if (irc, loweredNick) not in self._whois:
return return
t.write(search) (replyIrc, replyMsg, d) = self._whois[(irc, loweredNick)]
t.write('\n') hostmask = '@'.join(d['311'].args[2:4])
s = t.read_all() user = d['311'].args[-1]
(registrar, updated, created, expires, status) = ('', '', '', '', '') if '319' in d:
for line in s.splitlines(): channels = d['319'].args[-1].split()
line = line.strip() ops = []
if not line or ':' not in line: voices = []
continue normal = []
if not registrar and any(line.startswith, self._registrar): halfops = []
registrar = ':'.join(line.split(':')[1:]).strip() for channel in channels:
elif not updated and any(line.startswith, self._updated): if channel.startswith('@'):
s = ':'.join(line.split(':')[1:]).strip() ops.append(channel[1:])
updated = 'updated %s' % s elif channel.startswith('%'):
elif not created and any(line.startswith, self._created): halfops.append(channel[1:])
s = ':'.join(line.split(':')[1:]).strip() elif channel.startswith('+'):
created = 'registered %s' % s voices.append(channel[1:])
elif not expires and any(line.startswith, self._expires): else:
s = ':'.join(line.split(':')[1:]).strip() normal.append(channel)
expires = 'expires %s' % s L = []
elif not status and any(line.startswith, self._status): if ops:
status = ':'.join(line.split(':')[1:]).strip().lower() L.append('is an op on %s' % utils.commaAndify(ops))
if not status: if halfops:
status = 'unknown' L.append('is a halfop on %s' % utils.commaAndify(halfops))
try: if voices:
t = telnetlib.Telnet('whois.pir.org', 43) L.append('is voiced on %s' % utils.commaAndify(voices))
except socket.error, e: if normal:
irc.error(str(e)) if L:
L.append('is also on %s' % utils.commaAndify(normal))
else:
L.append('is on %s' % utils.commaAndify(normal))
else:
L = ['isn\'t on any non-secret channels']
channels = utils.commaAndify(L)
if '317' in d:
idle = utils.timeElapsed(d['317'].args[2])
signon = time.strftime(conf.supybot.humanTimestampFormat(),
time.localtime(float(d['317'].args[3])))
else:
idle = '<unknown>'
signon = '<unknown>'
if '312' in d:
server = d['312'].args[2]
else:
server = '<unknown>'
if '301' in d:
away = ' %s is away: %s.' % (nick, d['301'].args[2])
else:
away = ''
if '320' in d:
if d['320'].args[2]:
identify = ' identified'
else:
identify = ''
else:
identify = ''
s = '%s (%s) has been%s on server %s since %s (idle for %s) and ' \
'%s.%s' % (user, hostmask, identify, server, signon, idle,
channels, away)
replyIrc.reply(s)
del self._whois[(irc, loweredNick)]
def do402(self, irc, msg):
nick = msg.args[1]
loweredNick = ircutils.toLower(nick)
if (irc, loweredNick) not in self._whois:
return return
t.write('registrar id ') (replyIrc, replyMsg, d) = self._whois[(irc, loweredNick)]
t.write(registrar) del self._whois[(irc, loweredNick)]
t.write('\n') s = 'There is no %s on %s.' % (nick, self._getIrcName(irc))
s = t.read_all() replyIrc.reply(s)
for line in s.splitlines(): do401 = do402
line = line.strip()
if not line: def whois(self, irc, msg, args):
continue """[<network>] <nick>
if line.startswith('Email'):
url = ' <registered at %s>' % line.split('@')[-1] Returns the WHOIS response <network> gives for <nick>. <network> is
if line == 'Not a valid ID pattern': only necessary if the network is different than the network the command
url = '' is sent on.
try: """
s = '%s%s is %s; %s.' % (domain, url, status, network = self._getNetwork(irc, args)
', '.join(filter(None, [created, updated, expires]))) nick = privmsgs.getArgs(args)
irc.reply(s) if not ircutils.isNick(nick):
except NameError, e: irc.errorInvalid('nick', nick, Raise=True)
irc.error('I couldn\'t find such a domain.') nick = ircutils.toLower(nick)
otherIrc = self._getIrc(network)
# The double nick here is necessary because single-nick WHOIS only works
# if the nick is on the same server (*not* the same network) as the user
# giving the command. Yeah, it made me say wtf too.
otherIrc.queueMsg(ircmsgs.whois(nick, nick))
self._whois[(otherIrc, nick)] = (irc, msg, {})
def networks(self, irc, msg, args):
"""takes no arguments
Returns the networks to which the bot is currently connected.
"""
L = ['%s: %s' % (ircd.network, ircd.server) for ircd in world.ircs]
utils.sortBy(str.lower, L)
irc.reply(utils.commaAndify(L))
Class = Network Class = Network

View File

@ -132,12 +132,6 @@ class Relay(callbacks.Privmsg):
else: else:
return irc.getRealIrc() return irc.getRealIrc()
def _getIrc(self, name):
for irc in world.ircs:
if self._getIrcName(irc) == name:
return irc
raise KeyError, name
def _getIrcName(self, irc): def _getIrcName(self, irc):
# We should allow abbreviations at some point. # We should allow abbreviations at some point.
return irc.network return irc.network
@ -193,24 +187,6 @@ class Relay(callbacks.Privmsg):
irc.replySuccess() irc.replySuccess()
part = privmsgs.checkCapability(part, 'owner') part = privmsgs.checkCapability(part, 'owner')
def command(self, irc, msg, args):
"""<network> <command> [<arg> ...]
Gives the bot <command> (with its associated <arg>s) on <network>.
"""
if len(args) < 2:
raise callbacks.ArgumentError
network = args.pop(0)
try:
otherIrc = self._getIrc(network)
except KeyError:
irc.error('I\'m not currently on the network %r.' % network)
return
Owner = irc.getCallback('Owner')
Owner.disambiguate(irc, args)
self.Proxy(otherIrc, msg, args)
command = privmsgs.checkCapability(command, 'admin')
def nicks(self, irc, msg, args): def nicks(self, irc, msg, args):
"""[<channel>] """[<channel>]
@ -262,37 +238,6 @@ class Relay(callbacks.Privmsg):
users.sort() users.sort()
irc.reply('; '.join(users)) irc.reply('; '.join(users))
def whois(self, irc, msg, args):
"""<nick>@<network>
Returns the WHOIS response <network> gives for <nick>.
"""
nickAtNetwork = privmsgs.getArgs(args)
realIrc = self._getRealIrc(irc)
try:
(nick, network) = nickAtNetwork.split('@', 1)
if not ircutils.isNick(nick):
irc.error('%s is not an IRC nick.' % nick)
return
nick = ircutils.toLower(nick)
except ValueError: # If split doesn't work, we get an unpack error.
if len(world.ircs) == 2:
# If there are only two networks being relayed, we can safely
# pick the *other* one.
nick = ircutils.toLower(nickAtNetwork)
for otherIrc in world.ircs:
if otherIrc != realIrc:
network = self._getIrcName(otherIrc)
else:
raise callbacks.ArgumentError
try:
otherIrc = self._getIrc(network)
except KeyError:
irc.error('I\'m not on that network.')
return
otherIrc.queueMsg(ircmsgs.whois(nick, nick))
self._whois[(otherIrc, nick)] = (irc, msg, {})
def ignore(self, irc, msg, args): def ignore(self, irc, msg, args):
"""[<channel>] <nick|hostmask> """[<channel>] <nick|hostmask>

View File

@ -630,51 +630,43 @@ class Misc(callbacks.Privmsg):
text = privmsgs.getArgs(args) text = privmsgs.getArgs(args)
irc.reply(text, notice=True) irc.reply(text, notice=True)
def networks(self, irc, msg, args):
"""takes no arguments
Returns the networks to which the bot is currently connected.
"""
L = ['%s: %s' % (ircd.network, ircd.server) for ircd in world.ircs]
utils.sortBy(str.lower, L)
irc.reply(utils.commaAndify(L))
def contributors(self, irc, msg, args): def contributors(self, irc, msg, args):
"""<plugin> [<nickname>] """<plugin> [<nick>]
Replies with a list of people who made contributions to a given plugin. Replies with a list of people who made contributions to a given plugin.
If <nickname> is specified, that person's specific contributions will If <nick> is specified, that person's specific contributions will
be listed. Note: The <nickname> is the part inside of the parentheses be listed. Note: The <nick> is the part inside of the parentheses
in the people listing in the people listing.
""" """
(plugin, nickname) = privmsgs.getArgs(args, required=1, optional=1) (plugin, nick) = privmsgs.getArgs(args, required=1, optional=1)
nickname = nickname.lower() nick = nick.lower()
def getShortName(authorInfo): def getShortName(authorInfo):
""" """
Take an Authors object, and return only the name and nick values Take an Authors object, and return only the name and nick values
in the format 'First Last (nickname)' in the format 'First Last (nick)'.
""" """
return '%(name)s (%(nick)s)' % authorInfo.__dict__ return '%(name)s (%(nick)s)' % authorInfo.__dict__
def buildContributorsString(longList): def buildContributorsString(longList):
""" """
Take a list of long names and turn it into : Take a list of long names and turn it into :
shortname[, shortname and shortname] shortname[, shortname and shortname].
""" """
outList = [getShortName(n) for n in longList] L = [getShortName(n) for n in longList]
return utils.commaAndify(outList) return utils.commaAndify(L)
def sortAuthors(): def sortAuthors():
""" """
Sort the list of 'long names' based on the number of contributions Sort the list of 'long names' based on the number of contributions
associated with each associated with each.
""" """
L = module.__contributors__.items() L = module.__contributors__.items()
utils.sortBy(lambda elt: -len(elt[1]), L) def negativeSecondElement(x):
nameList = [pair[0] for pair in L] return -x[1]
return nameList utils.sortBy(negativeSecondElement, L)
return [t[0] for t in L]
def buildPeopleString(module): def buildPeopleString(module):
""" """
Build the list of author + contributors (if any) for the requested Build the list of author + contributors (if any) for the requested
plugin plugin.
""" """
head = 'The %s plugin' % plugin head = 'The %s plugin' % plugin
author = 'has not been claimed by an author' author = 'has not been claimed by an author'
@ -682,11 +674,11 @@ class Misc(callbacks.Privmsg):
contrib = 'has no contributors listed' contrib = 'has no contributors listed'
hasAuthor = False hasAuthor = False
hasContribs = False hasContribs = False
if getattr(module, '__author__', False): if getattr(module, '__author__', None):
author = 'was written by %s' % \ author = 'was written by %s' % \
utils.mungeEmailForWeb(str(module.__author__)) utils.mungeEmailForWeb(str(module.__author__))
hasAuthor = True hasAuthor = True
if getattr(module, '__contributors__', False): if getattr(module, '__contributors__', None):
contribs = sortAuthors() contribs = sortAuthors()
if hasAuthor: if hasAuthor:
try: try:
@ -702,28 +694,31 @@ class Misc(callbacks.Privmsg):
contrib = 'has no additional contributors listed' contrib = 'has no additional contributors listed'
if hasContribs and not hasAuthor: if hasContribs and not hasAuthor:
conjunction = 'but' conjunction = 'but'
return '%s %s %s %s' % (head, author, conjunction, contrib) return ' '.join([head, author, conjunction, contrib])
def buildPersonString(module): def buildPersonString(module):
""" """
Build the list of contributions (if any) for the requested person Build the list of contributions (if any) for the requested person
for the requested plugin for the requested plugin
""" """
isAuthor = False isAuthor = False
authorInfo = getattr(supybot.authors, nickname, False) authorInfo = getattr(supybot.authors, nick, None)
if not authorInfo: if not authorInfo:
return 'The nickname specified (%s) is not a registered ' \ return 'The nick specified (%s) is not a registered ' \
'contributor' % nickname 'contributor' % nick
fullName = utils.mungeEmailForWeb(str(authorInfo)) fullName = utils.mungeEmailForWeb(str(authorInfo))
contributions = [] contributions = []
if hasattr(module, '__contributors__'): if hasattr(module, '__contributors__'):
if authorInfo not in module.__contributors__: if authorInfo not in module.__contributors__:
return 'The %s plugin does not have \'%s\' listed as a ' \ return 'The %s plugin does not have \'%s\' listed as a ' \
'contributor' % (plugin, nickname) 'contributor' % (plugin, nick)
contributions = module.__contributors__[authorInfo] contributions = module.__contributors__[authorInfo]
if getattr(module, '__author__', False) == authorInfo: if getattr(module, '__author__', False) == authorInfo:
isAuthor = True isAuthor = True
# XXX Partition needs moved to utils.
splitContribs = fix.partition(lambda s: ' ' in s, contributions) splitContribs = fix.partition(lambda s: ' ' in s, contributions)
results = [] results = []
# XXX Assign splitContribs to specific names based on what it means
# semantically -- (foo, bar) = partition(...)
if splitContribs[1]: if splitContribs[1]:
results.append( results.append(
'the %s %s' %(utils.commaAndify(splitContribs[1]), 'the %s %s' %(utils.commaAndify(splitContribs[1]),
@ -747,7 +742,7 @@ class Misc(callbacks.Privmsg):
irc.error('No such plugin %r exists.' % plugin) irc.error('No such plugin %r exists.' % plugin)
return return
module = sys.modules[cb.__class__.__module__] module = sys.modules[cb.__class__.__module__]
if not nickname: if not nick:
irc.reply(buildPeopleString(module)) irc.reply(buildPeopleString(module))
else: else:
irc.reply(buildPersonString(module)) irc.reply(buildPersonString(module))

View File

@ -254,13 +254,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
def __lt__(self, other): def __lt__(self, other):
return True # We should always be the first plugin. return True # We should always be the first plugin.
def _getIrc(self, network):
network = network.lower()
for irc in world.ircs:
if irc.network.lower() == network:
return irc
return None
def outFilter(self, irc, msg): def outFilter(self, irc, msg):
if msg.command == 'PRIVMSG' and not world.testing: if msg.command == 'PRIVMSG' and not world.testing:
if ircutils.strEqual(msg.args[0], irc.nick): if ircutils.strEqual(msg.args[0], irc.nick):
@ -277,6 +270,26 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
callbacks.Privmsg._mores.clear() callbacks.Privmsg._mores.clear()
self.__parent.reset() self.__parent.reset()
def _connect(self, network, serverPort=None):
try:
group = conf.supybot.networks.get(network)
(server, port) = group.servers()[0]
except (registry.NonExistentRegistryEntry, IndexError):
if serverPort is None:
raise ValueError, 'connect requires a (server, port) ' \
'if the network is not registered.'
conf.registerNetwork(network)
serverS = '%s:%s' % serverPort
conf.supybot.networks.get(network).servers.append(serverS)
assert conf.supybot.networks.get(network).servers()
self.log.info('Creating new Irc for %s.', network)
newIrc = irclib.Irc(network)
for irc in world.ircs:
if irc != newIrc:
newIrc.state.history = irc.state.history
driver = drivers.newDriver(newIrc)
return newIrc
def do001(self, irc, msg): def do001(self, irc, msg):
self.log.info('Loading plugins.') self.log.info('Loading plugins.')
alwaysLoadSrcPlugins = conf.supybot.plugins.alwaysLoadDefault() alwaysLoadSrcPlugins = conf.supybot.plugins.alwaysLoadDefault()
@ -696,28 +709,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
else: else:
irc.error('There was no plugin %s.' % name) irc.error('There was no plugin %s.' % name)
def reconnect(self, irc, msg, args):
"""[<network>]
Disconnects and then reconnects to <network>. If no network is given,
disconnects and then reconnects to the network the command was given
on.
"""
network = privmsgs.getArgs(args, required=0, optional=1)
if network:
badIrc = self._getIrc(network)
if badIrc is None:
irc.error('I\'m not currently connected on %s.' % network)
return
else:
badIrc = irc
try:
badIrc.driver.reconnect()
if badIrc != irc:
irc.replySuccess()
except AttributeError: # There's a cleaner way to do this, but I'm lazy.
irc.error('I couldn\'t reconnect. You should restart me instead.')
def defaultcapability(self, irc, msg, args): def defaultcapability(self, irc, msg, args):
"""{add|remove} <capability> """{add|remove} <capability>
@ -824,77 +815,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
irc.errorInvalid('plugin', plugin, Raise=True) irc.errorInvalid('plugin', plugin, Raise=True)
self.reload(irc, msg, args) # This makes the replySuccess. self.reload(irc, msg, args) # This makes the replySuccess.
def _connect(self, network, serverPort=None):
try:
group = conf.supybot.networks.get(network)
(server, port) = group.servers()[0]
except (registry.NonExistentRegistryEntry, IndexError):
if serverPort is None:
raise ValueError, 'connect requires a (server, port) ' \
'if the network is not registered.'
conf.registerNetwork(network)
serverS = '%s:%s' % serverPort
conf.supybot.networks.get(network).servers.append(serverS)
assert conf.supybot.networks.get(network).servers()
self.log.info('Creating new Irc for %s.', network)
newIrc = irclib.Irc(network)
for irc in world.ircs:
if irc != newIrc:
newIrc.state.history = irc.state.history
driver = drivers.newDriver(newIrc)
return newIrc
def connect(self, irc, msg, args):
"""<network> [<host[:port]>]
Connects to another network at <host:port>. If port is not provided, it
defaults to 6667, the default port for IRC.
"""
(network, server) = privmsgs.getArgs(args, optional=1)
otherIrc = self._getIrc(network)
if otherIrc is not None:
irc.error('I\'m already connected to %s.' % network)
return
if server:
if ':' in server:
(server, port) = server.split(':')
port = int(port)
else:
port = 6667
serverPort = (server, port)
else:
try:
serverPort = conf.supybot.networks.get(network).servers()[0]
except (registry.NonExistentRegistryEntry, IndexError):
irc.error('A server must be provided if the network is not '
'already registered.')
return
newIrc = self._connect(network, serverPort=serverPort)
conf.supybot.networks().add(network)
assert newIrc.callbacks is irc.callbacks, 'callbacks list is different'
irc.replySuccess('Connection to %s initiated.' % network)
def disconnect(self, irc, msg, args):
"""<network> [<quit message>]
Disconnects and ceases to relay to and from the network represented by
the network <network>. If <quit message> is given, quits the network
with the given quit message.
"""
(network, quitMsg) = privmsgs.getArgs(args, optional=1)
if not quitMsg:
quitMsg = msg.nick
otherIrc = self._getIrc(network)
if otherIrc is not None:
# replySuccess here, rather than lower, in case we're being
# told to disconnect from the network we received the command on.
irc.replySuccess()
otherIrc.queueMsg(ircmsgs.quit(quitMsg))
otherIrc.die()
else:
irc.error('I\'m not connected to %s.' % network, Raise=True)
conf.supybot.networks().discard(network)
Class = Owner Class = Owner

View File

@ -31,21 +31,14 @@
from testsupport import * from testsupport import *
if network: class NetworkTestCase(PluginTestCase):
class NetworkTestCase(PluginTestCase): plugins = ['Network', 'Utilities']
plugins = ['Network'] def testNetworks(self):
def testDns(self): self.assertNotError('networks')
self.assertNotError('dns slashdot.org')
self.assertResponse('dns alsdkjfaslkdfjaslkdfj.com',
'Host not found.')
def testWhois(self): def testCommand(self):
self.assertNotError('network whois ohio-state.edu') self.assertResponse('network command %s echo 1' % self.irc.network,
self.assertError('network whois www.ohio-state.edu') '1')
self.assertNotError('network whois kuro5hin.org')
self.assertError('network whois www.kuro5hin.org')
self.assertNotError('network whois microsoft.com')
self.assertNotError('network whois inria.fr')
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: