mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-02-06 01:24:05 +01:00
Network plugin for network-related commands.
This commit is contained in:
parent
dfef079480
commit
a9694c1012
@ -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$"
|
||||
__author__ = supybot.authors.jemfinch
|
||||
|
||||
import supybot.plugins as plugins
|
||||
|
||||
import sets
|
||||
import socket
|
||||
import telnetlib
|
||||
import time
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.utils as utils
|
||||
import supybot.world as world
|
||||
import supybot.ircmsgs as ircmsgs
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.privmsgs as privmsgs
|
||||
import supybot.registry as registry
|
||||
import supybot.callbacks as callbacks
|
||||
|
||||
|
||||
class Network(callbacks.Privmsg):
|
||||
threaded = True
|
||||
def dns(self, irc, msg, args):
|
||||
"""<host|ip>
|
||||
_whois = {}
|
||||
def _getIrc(self, network):
|
||||
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)
|
||||
if utils.isIP(host):
|
||||
hostname = socket.getfqdn(host)
|
||||
if hostname == host:
|
||||
irc.reply('Host not found.')
|
||||
(network, server) = privmsgs.getArgs(args, optional=1)
|
||||
try:
|
||||
otherIrc = self._getIrc(network)
|
||||
irc.error('I\'m already connected to %s.' % network, Raise=True)
|
||||
except callbacks.Error:
|
||||
pass
|
||||
if server:
|
||||
if ':' in server:
|
||||
(server, port) = server.split(':')
|
||||
port = int(port)
|
||||
else:
|
||||
irc.reply(hostname)
|
||||
port = 6667
|
||||
serverPort = (server, port)
|
||||
else:
|
||||
try:
|
||||
ip = socket.gethostbyname(host)
|
||||
if ip == '64.94.110.11': # Verisign sucks!
|
||||
irc.reply('Host not found.')
|
||||
else:
|
||||
irc.reply(ip)
|
||||
except socket.error:
|
||||
irc.reply('Host not found.')
|
||||
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
|
||||
Owner = irc.getCallback('Owner')
|
||||
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')
|
||||
|
||||
def disconnect(self, irc, msg, args):
|
||||
"""[<network>] [<quit message>]
|
||||
|
||||
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.
|
||||
"""
|
||||
network = self._getNetwork(irc, args)
|
||||
quitMsg = privmsgs.getArgs(args, required=0, optional=1)
|
||||
if not quitMsg:
|
||||
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
|
||||
else:
|
||||
self._whois[(irc, nick)][-1][msg.command] = msg
|
||||
|
||||
# These are all sent by a WHOIS response.
|
||||
do301 = do311
|
||||
do312 = do311
|
||||
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
|
||||
(replyIrc, replyMsg, d) = self._whois[(irc, loweredNick)]
|
||||
hostmask = '@'.join(d['311'].args[2:4])
|
||||
user = d['311'].args[-1]
|
||||
if '319' in d:
|
||||
channels = d['319'].args[-1].split()
|
||||
ops = []
|
||||
voices = []
|
||||
normal = []
|
||||
halfops = []
|
||||
for channel in channels:
|
||||
if channel.startswith('@'):
|
||||
ops.append(channel[1:])
|
||||
elif channel.startswith('%'):
|
||||
halfops.append(channel[1:])
|
||||
elif channel.startswith('+'):
|
||||
voices.append(channel[1:])
|
||||
else:
|
||||
normal.append(channel)
|
||||
L = []
|
||||
if ops:
|
||||
L.append('is an op on %s' % utils.commaAndify(ops))
|
||||
if halfops:
|
||||
L.append('is a halfop on %s' % utils.commaAndify(halfops))
|
||||
if voices:
|
||||
L.append('is voiced on %s' % utils.commaAndify(voices))
|
||||
if normal:
|
||||
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
|
||||
(replyIrc, replyMsg, d) = self._whois[(irc, loweredNick)]
|
||||
del self._whois[(irc, loweredNick)]
|
||||
s = 'There is no %s on %s.' % (nick, self._getIrcName(irc))
|
||||
replyIrc.reply(s)
|
||||
do401 = do402
|
||||
|
||||
_tlds = sets.Set(['com', 'net', 'edu'])
|
||||
_registrar = ['Sponsoring Registrar', 'Registrar', 'source']
|
||||
_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>
|
||||
"""[<network>] <nick>
|
||||
|
||||
Returns WHOIS information on the registration of <domain>.
|
||||
Returns the WHOIS response <network> gives for <nick>. <network> is
|
||||
only necessary if the network is different than the network the command
|
||||
is sent on.
|
||||
"""
|
||||
domain = privmsgs.getArgs(args)
|
||||
usertld = domain.split('.')[-1]
|
||||
if '.' not in domain:
|
||||
irc.error('<domain> must be in .com, .net, .edu, or .org.')
|
||||
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:
|
||||
server = '%s.whois-servers.net' % usertld
|
||||
search = domain
|
||||
try:
|
||||
t = telnetlib.Telnet(server, 43)
|
||||
except socket.error, e:
|
||||
irc.error(str(e))
|
||||
return
|
||||
t.write(search)
|
||||
t.write('\n')
|
||||
s = t.read_all()
|
||||
(registrar, updated, created, expires, status) = ('', '', '', '', '')
|
||||
for line in s.splitlines():
|
||||
line = line.strip()
|
||||
if not line or ':' not in line:
|
||||
continue
|
||||
if not registrar and any(line.startswith, self._registrar):
|
||||
registrar = ':'.join(line.split(':')[1:]).strip()
|
||||
elif not updated and any(line.startswith, self._updated):
|
||||
s = ':'.join(line.split(':')[1:]).strip()
|
||||
updated = 'updated %s' % s
|
||||
elif not created and any(line.startswith, self._created):
|
||||
s = ':'.join(line.split(':')[1:]).strip()
|
||||
created = 'registered %s' % s
|
||||
elif not expires and any(line.startswith, self._expires):
|
||||
s = ':'.join(line.split(':')[1:]).strip()
|
||||
expires = 'expires %s' % s
|
||||
elif not status and any(line.startswith, self._status):
|
||||
status = ':'.join(line.split(':')[1:]).strip().lower()
|
||||
if not status:
|
||||
status = 'unknown'
|
||||
try:
|
||||
t = telnetlib.Telnet('whois.pir.org', 43)
|
||||
except socket.error, e:
|
||||
irc.error(str(e))
|
||||
return
|
||||
t.write('registrar id ')
|
||||
t.write(registrar)
|
||||
t.write('\n')
|
||||
s = t.read_all()
|
||||
for line in s.splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith('Email'):
|
||||
url = ' <registered at %s>' % line.split('@')[-1]
|
||||
if line == 'Not a valid ID pattern':
|
||||
url = ''
|
||||
try:
|
||||
s = '%s%s is %s; %s.' % (domain, url, status,
|
||||
', '.join(filter(None, [created, updated, expires])))
|
||||
irc.reply(s)
|
||||
except NameError, e:
|
||||
irc.error('I couldn\'t find such a domain.')
|
||||
network = self._getNetwork(irc, args)
|
||||
nick = privmsgs.getArgs(args)
|
||||
if not ircutils.isNick(nick):
|
||||
irc.errorInvalid('nick', nick, Raise=True)
|
||||
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
|
||||
|
@ -132,12 +132,6 @@ class Relay(callbacks.Privmsg):
|
||||
else:
|
||||
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):
|
||||
# We should allow abbreviations at some point.
|
||||
return irc.network
|
||||
@ -193,24 +187,6 @@ class Relay(callbacks.Privmsg):
|
||||
irc.replySuccess()
|
||||
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):
|
||||
"""[<channel>]
|
||||
|
||||
@ -262,37 +238,6 @@ class Relay(callbacks.Privmsg):
|
||||
users.sort()
|
||||
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):
|
||||
"""[<channel>] <nick|hostmask>
|
||||
|
||||
|
59
src/Misc.py
59
src/Misc.py
@ -630,51 +630,43 @@ class Misc(callbacks.Privmsg):
|
||||
text = privmsgs.getArgs(args)
|
||||
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):
|
||||
"""<plugin> [<nickname>]
|
||||
"""<plugin> [<nick>]
|
||||
|
||||
Replies with a list of people who made contributions to a given plugin.
|
||||
If <nickname> is specified, that person's specific contributions will
|
||||
be listed. Note: The <nickname> is the part inside of the parentheses
|
||||
in the people listing
|
||||
If <nick> is specified, that person's specific contributions will
|
||||
be listed. Note: The <nick> is the part inside of the parentheses
|
||||
in the people listing.
|
||||
"""
|
||||
(plugin, nickname) = privmsgs.getArgs(args, required=1, optional=1)
|
||||
nickname = nickname.lower()
|
||||
(plugin, nick) = privmsgs.getArgs(args, required=1, optional=1)
|
||||
nick = nick.lower()
|
||||
def getShortName(authorInfo):
|
||||
"""
|
||||
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__
|
||||
def buildContributorsString(longList):
|
||||
"""
|
||||
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]
|
||||
return utils.commaAndify(outList)
|
||||
L = [getShortName(n) for n in longList]
|
||||
return utils.commaAndify(L)
|
||||
def sortAuthors():
|
||||
"""
|
||||
Sort the list of 'long names' based on the number of contributions
|
||||
associated with each
|
||||
associated with each.
|
||||
"""
|
||||
L = module.__contributors__.items()
|
||||
utils.sortBy(lambda elt: -len(elt[1]), L)
|
||||
nameList = [pair[0] for pair in L]
|
||||
return nameList
|
||||
def negativeSecondElement(x):
|
||||
return -x[1]
|
||||
utils.sortBy(negativeSecondElement, L)
|
||||
return [t[0] for t in L]
|
||||
def buildPeopleString(module):
|
||||
"""
|
||||
Build the list of author + contributors (if any) for the requested
|
||||
plugin
|
||||
plugin.
|
||||
"""
|
||||
head = 'The %s plugin' % plugin
|
||||
author = 'has not been claimed by an author'
|
||||
@ -682,11 +674,11 @@ class Misc(callbacks.Privmsg):
|
||||
contrib = 'has no contributors listed'
|
||||
hasAuthor = False
|
||||
hasContribs = False
|
||||
if getattr(module, '__author__', False):
|
||||
if getattr(module, '__author__', None):
|
||||
author = 'was written by %s' % \
|
||||
utils.mungeEmailForWeb(str(module.__author__))
|
||||
hasAuthor = True
|
||||
if getattr(module, '__contributors__', False):
|
||||
if getattr(module, '__contributors__', None):
|
||||
contribs = sortAuthors()
|
||||
if hasAuthor:
|
||||
try:
|
||||
@ -702,28 +694,31 @@ class Misc(callbacks.Privmsg):
|
||||
contrib = 'has no additional contributors listed'
|
||||
if hasContribs and not hasAuthor:
|
||||
conjunction = 'but'
|
||||
return '%s %s %s %s' % (head, author, conjunction, contrib)
|
||||
return ' '.join([head, author, conjunction, contrib])
|
||||
def buildPersonString(module):
|
||||
"""
|
||||
Build the list of contributions (if any) for the requested person
|
||||
for the requested plugin
|
||||
"""
|
||||
isAuthor = False
|
||||
authorInfo = getattr(supybot.authors, nickname, False)
|
||||
authorInfo = getattr(supybot.authors, nick, None)
|
||||
if not authorInfo:
|
||||
return 'The nickname specified (%s) is not a registered ' \
|
||||
'contributor' % nickname
|
||||
return 'The nick specified (%s) is not a registered ' \
|
||||
'contributor' % nick
|
||||
fullName = utils.mungeEmailForWeb(str(authorInfo))
|
||||
contributions = []
|
||||
if hasattr(module, '__contributors__'):
|
||||
if authorInfo not in module.__contributors__:
|
||||
return 'The %s plugin does not have \'%s\' listed as a ' \
|
||||
'contributor' % (plugin, nickname)
|
||||
'contributor' % (plugin, nick)
|
||||
contributions = module.__contributors__[authorInfo]
|
||||
if getattr(module, '__author__', False) == authorInfo:
|
||||
isAuthor = True
|
||||
# XXX Partition needs moved to utils.
|
||||
splitContribs = fix.partition(lambda s: ' ' in s, contributions)
|
||||
results = []
|
||||
# XXX Assign splitContribs to specific names based on what it means
|
||||
# semantically -- (foo, bar) = partition(...)
|
||||
if splitContribs[1]:
|
||||
results.append(
|
||||
'the %s %s' %(utils.commaAndify(splitContribs[1]),
|
||||
@ -747,7 +742,7 @@ class Misc(callbacks.Privmsg):
|
||||
irc.error('No such plugin %r exists.' % plugin)
|
||||
return
|
||||
module = sys.modules[cb.__class__.__module__]
|
||||
if not nickname:
|
||||
if not nick:
|
||||
irc.reply(buildPeopleString(module))
|
||||
else:
|
||||
irc.reply(buildPersonString(module))
|
||||
|
120
src/Owner.py
120
src/Owner.py
@ -254,13 +254,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
def __lt__(self, other):
|
||||
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):
|
||||
if msg.command == 'PRIVMSG' and not world.testing:
|
||||
if ircutils.strEqual(msg.args[0], irc.nick):
|
||||
@ -277,6 +270,26 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
callbacks.Privmsg._mores.clear()
|
||||
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):
|
||||
self.log.info('Loading plugins.')
|
||||
alwaysLoadSrcPlugins = conf.supybot.plugins.alwaysLoadDefault()
|
||||
@ -696,28 +709,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
else:
|
||||
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):
|
||||
"""{add|remove} <capability>
|
||||
|
||||
@ -824,77 +815,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
irc.errorInvalid('plugin', plugin, Raise=True)
|
||||
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
|
||||
|
||||
|
@ -31,21 +31,14 @@
|
||||
|
||||
from testsupport import *
|
||||
|
||||
if network:
|
||||
class NetworkTestCase(PluginTestCase):
|
||||
plugins = ['Network']
|
||||
def testDns(self):
|
||||
self.assertNotError('dns slashdot.org')
|
||||
self.assertResponse('dns alsdkjfaslkdfjaslkdfj.com',
|
||||
'Host not found.')
|
||||
plugins = ['Network', 'Utilities']
|
||||
def testNetworks(self):
|
||||
self.assertNotError('networks')
|
||||
|
||||
def testWhois(self):
|
||||
self.assertNotError('network whois ohio-state.edu')
|
||||
self.assertError('network whois www.ohio-state.edu')
|
||||
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')
|
||||
def testCommand(self):
|
||||
self.assertResponse('network command %s echo 1' % self.irc.network,
|
||||
'1')
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||
|
Loading…
Reference in New Issue
Block a user