3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-12-24 11:42:51 +01:00

classes: sort code, move nickToUid, clientToServer, isInternalClient, isInternalServer into the Irc class

The following BREAKING changes are made:
utils.nickToUid(irc, nick) -> irc.nickToUid(nick)
utils.isInternalClient(irc, uid) -> irc.isInternalClient(uid)
utils.isInternalServer(irc, uid) -> irc.isInternalServer(uid)
utils.clientToServer(irc, uid) -> utils.getServer(uid)
This commit is contained in:
James Lu 2015-12-31 17:28:47 -08:00
parent 8fb76f96ff
commit eac934c237
12 changed files with 189 additions and 187 deletions

View File

@ -248,44 +248,6 @@ class Irc():
log.info('(%s) Stopping connect loop (autoconnect value %r is < 1).', self.name, autoconnect) log.info('(%s) Stopping connect loop (autoconnect value %r is < 1).', self.name, autoconnect)
return return
def callCommand(self, source, text):
"""
Calls a PyLink bot command. source is the caller's UID, and text is the
full, unparsed text of the message.
"""
cmd_args = text.strip().split(' ')
cmd = cmd_args[0].lower()
cmd_args = cmd_args[1:]
if cmd not in world.commands:
self.msg(self.called_by or source, 'Error: Unknown command %r.' % cmd)
log.info('(%s) Received unknown command %r from %s', self.name, cmd, utils.getHostmask(self, source))
return
log.info('(%s) Calling command %r for %s', self.name, cmd, utils.getHostmask(self, source))
for func in world.commands[cmd]:
try:
func(self, source, cmd_args)
except utils.NotAuthenticatedError:
self.msg(self.called_by or source, 'Error: You are not authorized to perform this operation.')
except Exception as e:
log.exception('Unhandled exception caught in command %r', cmd)
self.msg(self.called_by or source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e)))
def msg(self, target, text, notice=False, source=None):
"""Handy function to send messages/notices to clients. Source
is optional, and defaults to the main PyLink client if not specified."""
source = source or self.pseudoclient.uid
if notice:
self.proto.noticeClient(source, target, text)
cmd = 'PYLINK_SELF_NOTICE'
else:
self.proto.messageClient(source, target, text)
cmd = 'PYLINK_SELF_PRIVMSG'
self.callHooks([source, cmd, {'target': target, 'text': text}])
def reply(self, text, notice=False, source=None):
"""Replies to the last caller in the right context (channel or PM)."""
self.msg(self.called_by, text, notice=notice, source=source)
def _disconnect(self): def _disconnect(self):
"""Handle disconnects from the remote server.""" """Handle disconnects from the remote server."""
self.connected.clear() self.connected.clear()
@ -435,6 +397,71 @@ class Irc():
def __repr__(self): def __repr__(self):
return "<classes.Irc object for %r>" % self.name return "<classes.Irc object for %r>" % self.name
### Utility functions
def callCommand(self, source, text):
"""
Calls a PyLink bot command. source is the caller's UID, and text is the
full, unparsed text of the message.
"""
cmd_args = text.strip().split(' ')
cmd = cmd_args[0].lower()
cmd_args = cmd_args[1:]
if cmd not in world.commands:
self.msg(self.called_by or source, 'Error: Unknown command %r.' % cmd)
log.info('(%s) Received unknown command %r from %s', self.name, cmd, utils.getHostmask(self, source))
return
log.info('(%s) Calling command %r for %s', self.name, cmd, utils.getHostmask(self, source))
for func in world.commands[cmd]:
try:
func(self, source, cmd_args)
except utils.NotAuthenticatedError:
self.msg(self.called_by or source, 'Error: You are not authorized to perform this operation.')
except Exception as e:
log.exception('Unhandled exception caught in command %r', cmd)
self.msg(self.called_by or source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e)))
def msg(self, target, text, notice=False, source=None):
"""Handy function to send messages/notices to clients. Source
is optional, and defaults to the main PyLink client if not specified."""
source = source or self.pseudoclient.uid
if notice:
self.proto.noticeClient(source, target, text)
cmd = 'PYLINK_SELF_NOTICE'
else:
self.proto.messageClient(source, target, text)
cmd = 'PYLINK_SELF_PRIVMSG'
self.callHooks([source, cmd, {'target': target, 'text': text}])
def reply(self, text, notice=False, source=None):
"""Replies to the last caller in the right context (channel or PM)."""
self.msg(self.called_by, text, notice=notice, source=source)
def nickToUid(self, nick):
"""Looks up the UID of a user with the given nick, if one is present."""
nick = utils.toLower(self, nick)
for k, v in self.users.copy().items():
if utils.toLower(self, v.nick) == nick:
return k
def isInternalClient(self, numeric):
"""
Checks whether the given numeric is a PyLink Client,
returning the SID of the server it's on if so.
"""
for sid in self.servers:
if self.servers[sid].internal and numeric in self.servers[sid].users:
return sid
def isInternalServer(self, sid):
"""Returns whether the given SID is an internal PyLink server."""
return (sid in self.servers and self.servers[sid].internal)
def getServer(self, numeric):
"""Finds the SID of the server a user is on."""
for server in self.servers:
if numeric in self.servers[server].users:
return server
class IrcUser(): class IrcUser():
"""PyLink IRC user class.""" """PyLink IRC user class."""
def __init__(self, nick, ts, uid, ident='null', host='null', def __init__(self, nick, ts, uid, ident='null', host='null',
@ -511,60 +538,8 @@ class IrcChannel():
"""Returns a deep copy of the channel object.""" """Returns a deep copy of the channel object."""
return deepcopy(self) return deepcopy(self)
### FakeIRC classes, used for test cases
class FakeIRC(Irc):
"""Fake IRC object used for unit tests."""
def connect(self):
self.messages = []
self.hookargs = []
self.hookmsgs = []
self.socket = None
self.initVars()
self.spawnMain()
self.connected = threading.Event()
self.connected.set()
def run(self, data):
"""Queues a message to the fake IRC server."""
log.debug('<- ' + data)
hook_args = self.proto.handle_events(data)
if hook_args is not None:
self.hookmsgs.append(hook_args)
self.callHooks(hook_args)
def send(self, data):
self.messages.append(data)
log.debug('-> ' + data)
def takeMsgs(self):
"""Returns a list of messages sent by the protocol module since
the last takeMsgs() call, so we can track what has been sent."""
msgs = self.messages
self.messages = []
return msgs
def takeCommands(self, msgs):
"""Returns a list of commands parsed from the output of takeMsgs()."""
sidprefix = ':' + self.sid
commands = []
for m in msgs:
args = m.split()
if m.startswith(sidprefix):
commands.append(args[1])
else:
commands.append(args[0])
return commands
def takeHooks(self):
"""Returns a list of hook arguments sent by the protocol module since
the last takeHooks() call."""
hookmsgs = self.hookmsgs
self.hookmsgs = []
return hookmsgs
class Protocol(): class Protocol():
# TODO: Future state-keeping things will go here """Base Protocol module class for PyLink."""
def __init__(self, irc): def __init__(self, irc):
self.irc = irc self.irc = irc
self.casemapping = 'rfc1459' self.casemapping = 'rfc1459'
@ -626,6 +601,58 @@ class Protocol():
for p in self.irc.channels[channel].prefixmodes.values(): for p in self.irc.channels[channel].prefixmodes.values():
p.clear() p.clear()
### FakeIRC classes, used for test cases
class FakeIRC(Irc):
"""Fake IRC object used for unit tests."""
def connect(self):
self.messages = []
self.hookargs = []
self.hookmsgs = []
self.socket = None
self.initVars()
self.spawnMain()
self.connected = threading.Event()
self.connected.set()
def run(self, data):
"""Queues a message to the fake IRC server."""
log.debug('<- ' + data)
hook_args = self.proto.handle_events(data)
if hook_args is not None:
self.hookmsgs.append(hook_args)
self.callHooks(hook_args)
def send(self, data):
self.messages.append(data)
log.debug('-> ' + data)
def takeMsgs(self):
"""Returns a list of messages sent by the protocol module since
the last takeMsgs() call, so we can track what has been sent."""
msgs = self.messages
self.messages = []
return msgs
def takeCommands(self, msgs):
"""Returns a list of commands parsed from the output of takeMsgs()."""
sidprefix = ':' + self.sid
commands = []
for m in msgs:
args = m.split()
if m.startswith(sidprefix):
commands.append(args[1])
else:
commands.append(args[0])
return commands
def takeHooks(self):
"""Returns a list of hook arguments sent by the protocol module since
the last takeHooks() call."""
hookmsgs = self.hookmsgs
self.hookmsgs = []
return hookmsgs
class FakeProto(Protocol): class FakeProto(Protocol):
"""Dummy protocol module for testing purposes.""" """Dummy protocol module for testing purposes."""
def handle_events(self, data): def handle_events(self, data):

View File

@ -25,7 +25,7 @@ utils.add_hook(handle_kick, 'KICK')
def handle_commands(irc, source, command, args): def handle_commands(irc, source, command, args):
"""Handle commands sent to the PyLink client (PRIVMSG).""" """Handle commands sent to the PyLink client (PRIVMSG)."""
if args['target'] == irc.pseudoclient.uid and not utils.isInternalClient(irc, source): if args['target'] == irc.pseudoclient.uid and not irc.isInternalClient(source):
irc.called_by = source irc.called_by = source
irc.callCommand(source, args['text']) irc.callCommand(source, args['text'])
@ -40,7 +40,7 @@ def handle_whois(irc, source, command, args):
'doesn\'t exist in irc.users!', irc.name, target, source) 'doesn\'t exist in irc.users!', irc.name, target, source)
return return
f = irc.proto.numericServer f = irc.proto.numericServer
server = utils.clientToServer(irc, target) or irc.sid server = irc.getServer(target) or irc.sid
nick = user.nick nick = user.nick
sourceisOper = ('o', None) in irc.users[source].modes sourceisOper = ('o', None) in irc.users[source].modes
# https://www.alien.net.au/irc/irc2numerics.html # https://www.alien.net.au/irc/irc2numerics.html
@ -125,7 +125,7 @@ def handle_mode(irc, source, command, args):
modes = args['modes'] modes = args['modes']
# If the sender is not a PyLink client, and the target IS a protected # If the sender is not a PyLink client, and the target IS a protected
# client, revert any forced deoper attempts. # client, revert any forced deoper attempts.
if utils.isInternalClient(irc, target) and not utils.isInternalClient(irc, source): if irc.isInternalClient(target) and not irc.isInternalClient(source):
if ('-o', None) in modes and (target == irc.pseudoclient.uid or not utils.isManipulatableClient(irc, target)): if ('-o', None) in modes and (target == irc.pseudoclient.uid or not utils.isManipulatableClient(irc, target)):
irc.proto.modeServer(irc.sid, target, {('+o', None)}) irc.proto.modeServer(irc.sid, target, {('+o', None)})
utils.add_hook(handle_mode, 'MODE') utils.add_hook(handle_mode, 'MODE')

View File

@ -35,10 +35,10 @@ def quit(irc, source, args):
except IndexError: except IndexError:
irc.reply("Error: Not enough arguments. Needs 1-2: nick, reason (optional).") irc.reply("Error: Not enough arguments. Needs 1-2: nick, reason (optional).")
return return
if irc.pseudoclient.uid == utils.nickToUid(irc, nick): if irc.pseudoclient.uid == irc.nickToUid(nick):
irc.reply("Error: Cannot quit the main PyLink PseudoClient!") irc.reply("Error: Cannot quit the main PyLink PseudoClient!")
return return
u = utils.nickToUid(irc, nick) u = irc.nickToUid(nick)
quitmsg = ' '.join(args[1:]) or 'Client Quit' quitmsg = ' '.join(args[1:]) or 'Client Quit'
if not utils.isManipulatableClient(irc, u): if not utils.isManipulatableClient(irc, u):
irc.reply("Error: Cannot force quit a protected PyLink services client.") irc.reply("Error: Cannot force quit a protected PyLink services client.")
@ -59,7 +59,7 @@ def joinclient(irc, source, args):
except IndexError: except IndexError:
irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.") irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.")
return return
u = utils.nickToUid(irc, nick) u = irc.nickToUid(nick)
if not utils.isManipulatableClient(irc, u): if not utils.isManipulatableClient(irc, u):
irc.reply("Error: Cannot force join a protected PyLink services client.") irc.reply("Error: Cannot force join a protected PyLink services client.")
return return
@ -85,7 +85,7 @@ def nick(irc, source, args):
except IndexError: except IndexError:
irc.reply("Error: Not enough arguments. Needs 2: nick, newnick.") irc.reply("Error: Not enough arguments. Needs 2: nick, newnick.")
return return
u = utils.nickToUid(irc, nick) u = irc.nickToUid(nick)
if newnick in ('0', u): if newnick in ('0', u):
newnick = u newnick = u
elif not utils.isNick(newnick): elif not utils.isNick(newnick):
@ -110,7 +110,7 @@ def part(irc, source, args):
except IndexError: except IndexError:
irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.") irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.")
return return
u = utils.nickToUid(irc, nick) u = irc.nickToUid(nick)
if not utils.isManipulatableClient(irc, u): if not utils.isManipulatableClient(irc, u):
irc.reply("Error: Cannot force part a protected PyLink services client.") irc.reply("Error: Cannot force part a protected PyLink services client.")
return return
@ -132,12 +132,12 @@ def msg(irc, source, args):
except IndexError: except IndexError:
irc.reply('Error: Not enough arguments. Needs 3: source nick, target, text.') irc.reply('Error: Not enough arguments. Needs 3: source nick, target, text.')
return return
sourceuid = utils.nickToUid(irc, msgsource) sourceuid = irc.nickToUid(msgsource)
if not sourceuid: if not sourceuid:
irc.reply('Error: Unknown user %r.' % msgsource) irc.reply('Error: Unknown user %r.' % msgsource)
return return
if not utils.isChannel(target): if not utils.isChannel(target):
real_target = utils.nickToUid(irc, target) real_target = irc.nickToUid(target)
if real_target is None: if real_target is None:
irc.reply('Error: Unknown user %r.' % target) irc.reply('Error: Unknown user %r.' % target)
return return

View File

@ -26,14 +26,14 @@ def kick(irc, source, args):
return return
# Convert the source and target nicks to UIDs. # Convert the source and target nicks to UIDs.
u = utils.nickToUid(irc, sourcenick) or sourcenick u = irc.nickToUid(sourcenick) or sourcenick
targetu = utils.nickToUid(irc, target) targetu = irc.nickToUid(target)
if channel not in irc.channels: # KICK only works on channels that exist. if channel not in irc.channels: # KICK only works on channels that exist.
irc.reply("Error: Unknown channel %r." % channel) irc.reply("Error: Unknown channel %r." % channel)
return return
if utils.isInternalServer(irc, u): if irc.isInternalServer(u):
# Send kick from server if the given kicker is a SID # Send kick from server if the given kicker is a SID
irc.proto.kickServer(u, channel, targetu, reason) irc.proto.kickServer(u, channel, targetu, reason)
elif u not in irc.users: elif u not in irc.users:

View File

@ -79,7 +79,7 @@ def showuser(irc, source, args):
except IndexError: except IndexError:
irc.reply("Error: Not enough arguments. Needs 1: nick.") irc.reply("Error: Not enough arguments. Needs 1: nick.")
return return
u = utils.nickToUid(irc, target) or target u = irc.nickToUid(target) or target
# Only show private info if the person is calling 'showuser' on themselves, # Only show private info if the person is calling 'showuser' on themselves,
# or is an oper. # or is an oper.
verbose = utils.isOper(irc, source) or u == source verbose = utils.isOper(irc, source) or u == source
@ -91,7 +91,8 @@ def showuser(irc, source, args):
userobj = irc.users[u] userobj = irc.users[u]
f('Information on user \x02%s\x02 (%s@%s): %s' % (userobj.nick, userobj.ident, f('Information on user \x02%s\x02 (%s@%s): %s' % (userobj.nick, userobj.ident,
userobj.host, userobj.realname)) userobj.host, userobj.realname))
sid = utils.clientToServer(irc, u)
sid = irc.getServer(u)
serverobj = irc.servers[sid] serverobj = irc.servers[sid]
ts = userobj.ts ts = userobj.ts
f('\x02Home server\x02: %s (%s); \x02Signon time:\x02 %s (%s)' % \ f('\x02Home server\x02: %s (%s); \x02Signon time:\x02 %s (%s)' % \

View File

@ -38,7 +38,7 @@ def handle_fantasy(irc, source, command, args):
# message loops). # message loops).
if utils.isChannel(channel) and text.startswith(prefix) and \ if utils.isChannel(channel) and text.startswith(prefix) and \
irc.pseudoclient.uid in irc.channels[channel].users and not \ irc.pseudoclient.uid in irc.channels[channel].users and not \
utils.isInternalClient(irc, source): irc.isInternalClient(source):
# Cut off the length of the prefix from the text. # Cut off the length of the prefix from the text.
text = text[len(prefix):] text = text[len(prefix):]

View File

@ -111,7 +111,7 @@ def normalizeNick(irc, netname, nick, separator=None, uid=''):
# somecutoffnick/net would otherwise be erroneous NICK'ed to somecutoffnic//net, # somecutoffnick/net would otherwise be erroneous NICK'ed to somecutoffnic//net,
# even though there would be no collision because the old and new nicks are from # even though there would be no collision because the old and new nicks are from
# the same client. # the same client.
while utils.nickToUid(irc, nick) and utils.nickToUid(irc, nick) != uid: while irc.nickToUid(nick) and irc.nickToUid(nick) != uid:
new_sep = separator + separator[-1] new_sep = separator + separator[-1]
log.debug('(%s) normalizeNick: nick %r is in use; using %r as new_sep.', irc.name, nick, new_sep) log.debug('(%s) normalizeNick: nick %r is in use; using %r as new_sep.', irc.name, nick, new_sep)
nick = normalizeNick(irc, netname, orig_nick, separator=new_sep) nick = normalizeNick(irc, netname, orig_nick, separator=new_sep)
@ -429,8 +429,8 @@ def checkClaim(irc, channel, sender, chanobj=None):
return (not relay) or irc.name == relay[0] or not db[relay]['claim'] or \ return (not relay) or irc.name == relay[0] or not db[relay]['claim'] or \
irc.name in db[relay]['claim'] or \ irc.name in db[relay]['claim'] or \
any([mode in sender_modes for mode in ('y', 'q', 'a', 'o', 'h')]) \ any([mode in sender_modes for mode in ('y', 'q', 'a', 'o', 'h')]) \
or utils.isInternalClient(irc, sender) or \ or irc.isInternalClient(sender) or \
utils.isInternalServer(irc, sender) irc.isInternalServer(sender)
def getSupportedUmodes(irc, remoteirc, modes): def getSupportedUmodes(irc, remoteirc, modes):
"""Given a list of user modes, filters out all of those not supported by the """Given a list of user modes, filters out all of those not supported by the
@ -713,7 +713,7 @@ def handle_messages(irc, numeric, command, args):
notice = (command in ('NOTICE', 'PYLINK_SELF_NOTICE')) notice = (command in ('NOTICE', 'PYLINK_SELF_NOTICE'))
target = args['target'] target = args['target']
text = args['text'] text = args['text']
if utils.isInternalClient(irc, numeric) and utils.isInternalClient(irc, target): if irc.isInternalClient(numeric) and irc.isInternalClient(target):
# Drop attempted PMs between internal clients (this shouldn't happen, # Drop attempted PMs between internal clients (this shouldn't happen,
# but whatever). # but whatever).
return return
@ -1351,7 +1351,7 @@ def showuser(irc, source, args):
# No errors here; showuser from the commands plugin already does this # No errors here; showuser from the commands plugin already does this
# for us. # for us.
return return
u = utils.nickToUid(irc, target) u = irc.nickToUid(target)
if u: if u:
try: try:
userpair = getOrigUser(irc, u) or (irc.name, u) userpair = getOrigUser(irc, u) or (irc.name, u)

View File

@ -40,7 +40,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
Note: No nick collision / valid nickname checks are done here; it is Note: No nick collision / valid nickname checks are done here; it is
up to plugins to make sure they don't introduce anything invalid.""" up to plugins to make sure they don't introduce anything invalid."""
server = server or self.irc.sid server = server or self.irc.sid
if not utils.isInternalServer(self.irc, server): if not self.irc.isInternalServer(server):
raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server) raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server)
# Create an UIDGenerator instance for every SID, so that each gets # Create an UIDGenerator instance for every SID, so that each gets
# distinct values. # distinct values.
@ -68,7 +68,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
# so what we're actually doing here is sending FJOIN from the server, # so what we're actually doing here is sending FJOIN from the server,
# on behalf of the clients that are joining. # on behalf of the clients that are joining.
channel = utils.toLower(self.irc, channel) channel = utils.toLower(self.irc, channel)
server = utils.isInternalClient(self.irc, client) server = self.irc.isInternalClient(client)
if not server: if not server:
log.error('(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) log.error('(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel)
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
@ -176,7 +176,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
Sends mode changes from a PyLink client. <modes> should be Sends mode changes from a PyLink client. <modes> should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
@ -185,7 +185,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
Sends mode changes from a PyLink server. <list of modes> should be Sends mode changes from a PyLink server. <list of modes> should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
@ -194,24 +194,24 @@ class InspIRCdProtocol(TS6BaseProtocol):
# We only need to call removeClient here if the target is one of our # We only need to call removeClient here if the target is one of our
# clients, since any remote servers will send a QUIT from # clients, since any remote servers will send a QUIT from
# their target if the command succeeds. # their target if the command succeeds.
if utils.isInternalClient(self.irc, target): if self.irc.isInternalClient(target):
self.removeClient(target) self.removeClient(target)
def killServer(self, numeric, target, reason): def killServer(self, numeric, target, reason):
"""Sends a kill from a PyLink server.""" """Sends a kill from a PyLink server."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
self._sendKill(numeric, target, reason) self._sendKill(numeric, target, reason)
def killClient(self, numeric, target, reason): def killClient(self, numeric, target, reason):
"""Sends a kill from a PyLink client.""" """Sends a kill from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._sendKill(numeric, target, reason) self._sendKill(numeric, target, reason)
def topicServer(self, numeric, target, text): def topicServer(self, numeric, target, text):
"""Sends a topic change from a PyLink server. This is usually used on burst.""" """Sends a topic change from a PyLink server. This is usually used on burst."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
ts = int(time.time()) ts = int(time.time())
servername = self.irc.servers[numeric].name servername = self.irc.servers[numeric].name
@ -221,13 +221,13 @@ class InspIRCdProtocol(TS6BaseProtocol):
def inviteClient(self, numeric, target, channel): def inviteClient(self, numeric, target, channel):
"""Sends an INVITE from a PyLink client..""" """Sends an INVITE from a PyLink client.."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'INVITE %s %s' % (target, channel)) self._send(numeric, 'INVITE %s %s' % (target, channel))
def knockClient(self, numeric, target, text): def knockClient(self, numeric, target, text):
"""Sends a KNOCK from a PyLink client.""" """Sends a KNOCK from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'ENCAP * KNOCK %s :%s' % (target, text)) self._send(numeric, 'ENCAP * KNOCK %s :%s' % (target, text))
@ -239,7 +239,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
raise NotImplementedError("Changing field %r of a client is " raise NotImplementedError("Changing field %r of a client is "
"unsupported by this protocol." % field) "unsupported by this protocol." % field)
if utils.isInternalClient(self.irc, target): if self.irc.isInternalClient(target):
# It is one of our clients, use FIDENT/HOST/NAME. # It is one of our clients, use FIDENT/HOST/NAME.
if field == 'IDENT': if field == 'IDENT':
self.irc.users[target].ident = text self.irc.users[target].ident = text
@ -321,7 +321,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
for server in self.irc.servers.values(): for server in self.irc.servers.values():
if name == server.name: if name == server.name:
raise ValueError('A server named %r already exists!' % name) raise ValueError('A server named %r already exists!' % name)
if not utils.isInternalServer(self.irc, uplink): if not self.irc.isInternalServer(uplink):
raise ValueError('Server %r is not a PyLink internal PseudoServer!' % uplink) raise ValueError('Server %r is not a PyLink internal PseudoServer!' % uplink)
if not utils.isServerName(name): if not utils.isServerName(name):
raise ValueError('Invalid server name %r' % name) raise ValueError('Invalid server name %r' % name)
@ -446,7 +446,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
"""Handles incoming PING commands, so we don't time out.""" """Handles incoming PING commands, so we don't time out."""
# <- :70M PING 70M 0AL # <- :70M PING 70M 0AL
# -> :0AL PONG 0AL 70M # -> :0AL PONG 0AL 70M
if utils.isInternalServer(self.irc, args[1]): if self.irc.isInternalServer(args[1]):
self._send(args[1], 'PONG %s %s' % (args[1], source)) self._send(args[1], 'PONG %s %s' % (args[1], source))
def handle_pong(self, source, command, args): def handle_pong(self, source, command, args):
@ -650,7 +650,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
# SQUIT, in order to be consistent with other IRCds which make SQUITs # SQUIT, in order to be consistent with other IRCds which make SQUITs
# implicit. # implicit.
target = self._getSid(args[0]) target = self._getSid(args[0])
if utils.isInternalServer(self.irc, target): if self.irc.isInternalServer(target):
# The target has to be one of our servers in order to work... # The target has to be one of our servers in order to work...
uplink = self.irc.servers[target].uplink uplink = self.irc.servers[target].uplink
reason = 'Requested by %s' % utils.getHostmask(self.irc, numeric) reason = 'Requested by %s' % utils.getHostmask(self.irc, numeric)

View File

@ -33,7 +33,7 @@ class TS6Protocol(TS6BaseProtocol):
Note: No nick collision / valid nickname checks are done here; it is Note: No nick collision / valid nickname checks are done here; it is
up to plugins to make sure they don't introduce anything invalid.""" up to plugins to make sure they don't introduce anything invalid."""
server = server or self.irc.sid server = server or self.irc.sid
if not utils.isInternalServer(self.irc, server): if not self.irc.isInternalServer(server):
raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server) raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server)
# Create an UIDGenerator instance for every SID, so that each gets # Create an UIDGenerator instance for every SID, so that each gets
# distinct values. # distinct values.
@ -61,7 +61,7 @@ class TS6Protocol(TS6BaseProtocol):
channel = utils.toLower(self.irc, channel) channel = utils.toLower(self.irc, channel)
# JOIN: # JOIN:
# parameters: channelTS, channel, '+' (a plus sign) # parameters: channelTS, channel, '+' (a plus sign)
if not utils.isInternalClient(self.irc, client): if not self.irc.isInternalClient(client):
log.error('(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) log.error('(%s) Error trying to join client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel)
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(client, "JOIN {ts} {channel} +".format(ts=self.irc.channels[channel].ts, channel=channel)) self._send(client, "JOIN {ts} {channel} +".format(ts=self.irc.channels[channel].ts, channel=channel))
@ -156,7 +156,7 @@ class TS6Protocol(TS6BaseProtocol):
Sends mode changes from a PyLink client. <modes> should be Sends mode changes from a PyLink client. <modes> should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
@ -165,13 +165,13 @@ class TS6Protocol(TS6BaseProtocol):
Sends mode changes from a PyLink server. <list of modes> should be Sends mode changes from a PyLink server. <list of modes> should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
def killServer(self, numeric, target, reason): def killServer(self, numeric, target, reason):
"""Sends a kill from a PyLink server.""" """Sends a kill from a PyLink server."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
# KILL: # KILL:
# parameters: target user, path # parameters: target user, path
@ -186,7 +186,7 @@ class TS6Protocol(TS6BaseProtocol):
def killClient(self, numeric, target, reason): def killClient(self, numeric, target, reason):
"""Sends a kill from a PyLink client.""" """Sends a kill from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
assert target in self.irc.users, "Unknown target %r for killClient!" % target assert target in self.irc.users, "Unknown target %r for killClient!" % target
self._send(numeric, 'KILL %s :Killed (%s)' % (target, reason)) self._send(numeric, 'KILL %s :Killed (%s)' % (target, reason))
@ -194,7 +194,7 @@ class TS6Protocol(TS6BaseProtocol):
def topicServer(self, numeric, target, text): def topicServer(self, numeric, target, text):
"""Sends a topic change from a PyLink server. This is usually used on burst.""" """Sends a topic change from a PyLink server. This is usually used on burst."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
# TB # TB
# capab: TB # capab: TB
@ -209,7 +209,7 @@ class TS6Protocol(TS6BaseProtocol):
def inviteClient(self, numeric, target, channel): def inviteClient(self, numeric, target, channel):
"""Sends an INVITE from a PyLink client..""" """Sends an INVITE from a PyLink client.."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'INVITE %s %s %s' % (target, channel, self.irc.channels[channel].ts)) self._send(numeric, 'INVITE %s %s %s' % (target, channel, self.irc.channels[channel].ts))
@ -219,7 +219,7 @@ class TS6Protocol(TS6BaseProtocol):
log.debug('(%s) knockClient: Dropping KNOCK to %r since the IRCd ' log.debug('(%s) knockClient: Dropping KNOCK to %r since the IRCd '
'doesn\'t support it.', self.irc.name, target) 'doesn\'t support it.', self.irc.name, target)
return return
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
# No text value is supported here; drop it. # No text value is supported here; drop it.
self._send(numeric, 'KNOCK %s' % target) self._send(numeric, 'KNOCK %s' % target)
@ -230,7 +230,7 @@ class TS6Protocol(TS6BaseProtocol):
if field == 'HOST': if field == 'HOST':
self.irc.users[target].host = text self.irc.users[target].host = text
self._send(self.irc.sid, 'CHGHOST %s :%s' % (target, text)) self._send(self.irc.sid, 'CHGHOST %s :%s' % (target, text))
if not utils.isInternalClient(self.irc, target): if not self.irc.isInternalClient(target):
# If the target isn't one of our clients, send hook payload # If the target isn't one of our clients, send hook payload
# for other plugins to listen to. # for other plugins to listen to.
self.irc.callHooks([self.irc.sid, 'CHGHOST', self.irc.callHooks([self.irc.sid, 'CHGHOST',
@ -443,7 +443,7 @@ class TS6Protocol(TS6BaseProtocol):
destination = args[1] destination = args[1]
except IndexError: except IndexError:
destination = self.irc.sid destination = self.irc.sid
if utils.isInternalServer(self.irc, destination): if self.irc.isInternalServer(destination):
self._send(destination, 'PONG %s %s' % (destination, source)) self._send(destination, 'PONG %s %s' % (destination, source))
def handle_pong(self, source, command, args): def handle_pong(self, source, command, args):

View File

@ -54,19 +54,19 @@ class TS6BaseProtocol(Protocol):
def kickClient(self, numeric, channel, target, reason=None): def kickClient(self, numeric, channel, target, reason=None):
"""Sends a kick from a PyLink client.""" """Sends a kick from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._sendKick(numeric, channel, target, reason=reason) self._sendKick(numeric, channel, target, reason=reason)
def kickServer(self, numeric, channel, target, reason=None): def kickServer(self, numeric, channel, target, reason=None):
"""Sends a kick from a PyLink server.""" """Sends a kick from a PyLink server."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink PseudoServer exists.') raise LookupError('No such PyLink PseudoServer exists.')
self._sendKick(numeric, channel, target, reason=reason) self._sendKick(numeric, channel, target, reason=reason)
def nickClient(self, numeric, newnick): def nickClient(self, numeric, newnick):
"""Changes the nick of a PyLink client.""" """Changes the nick of a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'NICK %s %s' % (newnick, int(time.time()))) self._send(numeric, 'NICK %s %s' % (newnick, int(time.time())))
self.irc.users[numeric].nick = newnick self.irc.users[numeric].nick = newnick
@ -74,7 +74,7 @@ class TS6BaseProtocol(Protocol):
def partClient(self, client, channel, reason=None): def partClient(self, client, channel, reason=None):
"""Sends a part from a PyLink client.""" """Sends a part from a PyLink client."""
channel = utils.toLower(self.irc, channel) channel = utils.toLower(self.irc, channel)
if not utils.isInternalClient(self.irc, client): if not self.irc.isInternalClient(client):
log.error('(%s) Error trying to part client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel) log.error('(%s) Error trying to part client %r to %r (no such pseudoclient exists)', self.irc.name, client, channel)
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
msg = "PART %s" % channel msg = "PART %s" % channel
@ -85,7 +85,7 @@ class TS6BaseProtocol(Protocol):
def quitClient(self, numeric, reason): def quitClient(self, numeric, reason):
"""Quits a PyLink client.""" """Quits a PyLink client."""
if utils.isInternalClient(self.irc, numeric): if self.irc.isInternalClient(numeric):
self._send(numeric, "QUIT :%s" % reason) self._send(numeric, "QUIT :%s" % reason)
self.removeClient(numeric) self.removeClient(numeric)
else: else:
@ -93,19 +93,19 @@ class TS6BaseProtocol(Protocol):
def messageClient(self, numeric, target, text): def messageClient(self, numeric, target, text):
"""Sends a PRIVMSG from a PyLink client.""" """Sends a PRIVMSG from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'PRIVMSG %s :%s' % (target, text)) self._send(numeric, 'PRIVMSG %s :%s' % (target, text))
def noticeClient(self, numeric, target, text): def noticeClient(self, numeric, target, text):
"""Sends a NOTICE from a PyLink client.""" """Sends a NOTICE from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'NOTICE %s :%s' % (target, text)) self._send(numeric, 'NOTICE %s :%s' % (target, text))
def topicClient(self, numeric, target, text): def topicClient(self, numeric, target, text):
"""Sends a TOPIC change from a PyLink client.""" """Sends a TOPIC change from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
self._send(numeric, 'TOPIC %s :%s' % (target, text)) self._send(numeric, 'TOPIC %s :%s' % (target, text))
self.irc.channels[target].topic = text self.irc.channels[target].topic = text
@ -133,7 +133,7 @@ class TS6BaseProtocol(Protocol):
for server in self.irc.servers.values(): for server in self.irc.servers.values():
if name == server.name: if name == server.name:
raise ValueError('A server named %r already exists!' % name) raise ValueError('A server named %r already exists!' % name)
if not utils.isInternalServer(self.irc, uplink): if not self.irc.isInternalServer(uplink):
raise ValueError('Server %r is not a PyLink internal PseudoServer!' % uplink) raise ValueError('Server %r is not a PyLink internal PseudoServer!' % uplink)
if not utils.isServerName(name): if not utils.isServerName(name):
raise ValueError('Invalid server name %r' % name) raise ValueError('Invalid server name %r' % name)

View File

@ -58,7 +58,7 @@ class UnrealProtocol(TS6BaseProtocol):
Note: No nick collision / valid nickname checks are done here; it is Note: No nick collision / valid nickname checks are done here; it is
up to plugins to make sure they don't introduce anything invalid.""" up to plugins to make sure they don't introduce anything invalid."""
server = server or self.irc.sid server = server or self.irc.sid
if not utils.isInternalServer(self.irc, server): if not self.irc.isInternalServer(server):
raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server) raise ValueError('Server %r is not a PyLink internal PseudoServer!' % server)
# Unreal 3.4 uses TS6-style UIDs. They don't start from AAAAAA like other IRCd's # Unreal 3.4 uses TS6-style UIDs. They don't start from AAAAAA like other IRCd's
# do, but we can do that fine... # do, but we can do that fine...
@ -107,7 +107,7 @@ class UnrealProtocol(TS6BaseProtocol):
def joinClient(self, client, channel): def joinClient(self, client, channel):
"""Joins a PyLink client to a channel.""" """Joins a PyLink client to a channel."""
channel = utils.toLower(self.irc, channel) channel = utils.toLower(self.irc, channel)
if not utils.isInternalClient(self.irc, client): if not self.irc.isInternalClient(client):
raise LookupError('No such PyLink client exists.') raise LookupError('No such PyLink client exists.')
self._send(client, "JOIN %s" % channel) self._send(client, "JOIN %s" % channel)
self.irc.channels[channel].users.add(client) self.irc.channels[channel].users.add(client)
@ -179,7 +179,7 @@ class UnrealProtocol(TS6BaseProtocol):
def killServer(self, numeric, target, reason): def killServer(self, numeric, target, reason):
"""Sends a kill from a PyLink server.""" """Sends a kill from a PyLink server."""
# <- :GL KILL 38QAAAAAA :hidden-1C620195!GL (test) # <- :GL KILL 38QAAAAAA :hidden-1C620195!GL (test)
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink server exists.') raise LookupError('No such PyLink server exists.')
assert target in self.irc.users, "Unknown target %r for killServer!" % target assert target in self.irc.users, "Unknown target %r for killServer!" % target
@ -189,7 +189,7 @@ class UnrealProtocol(TS6BaseProtocol):
def killClient(self, numeric, target, reason): def killClient(self, numeric, target, reason):
"""Sends a kill from a PyLink client.""" """Sends a kill from a PyLink client."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink client exists.') raise LookupError('No such PyLink client exists.')
assert target in self.irc.users, "Unknown target %r for killClient!" % target assert target in self.irc.users, "Unknown target %r for killClient!" % target
self._send(numeric, 'KILL %s :%s!PyLink (%s)' % (target, self.irc.serverdata['hostname'], reason)) self._send(numeric, 'KILL %s :%s!PyLink (%s)' % (target, self.irc.serverdata['hostname'], reason))
@ -209,7 +209,7 @@ class UnrealProtocol(TS6BaseProtocol):
# is through UMODE2, which sets the modes on the caller. # is through UMODE2, which sets the modes on the caller.
# U:Lines can use SVSMODE/SVS2MODE, but I won't expect people to # U:Lines can use SVSMODE/SVS2MODE, but I won't expect people to
# U:Line a PyLink daemon... # U:Line a PyLink daemon...
if not utils.isInternalClient(self.irc, target): if not self.irc.isInternalClient(target):
raise ProtocolError('Cannot force mode change on external clients!') raise ProtocolError('Cannot force mode change on external clients!')
self._send(target, 'UMODE2 %s' % joinedmodes) self._send(target, 'UMODE2 %s' % joinedmodes)
@ -218,7 +218,7 @@ class UnrealProtocol(TS6BaseProtocol):
Sends mode changes from a PyLink client. The mode list should be Sends mode changes from a PyLink client. The mode list should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink client exists.') raise LookupError('No such PyLink client exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
@ -227,13 +227,13 @@ class UnrealProtocol(TS6BaseProtocol):
Sends mode changes from a PyLink server. The mode list should be Sends mode changes from a PyLink server. The mode list should be
a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output. a list of (mode, arg) tuples, i.e. the format of utils.parseModes() output.
""" """
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink server exists.') raise LookupError('No such PyLink server exists.')
self._sendModes(numeric, target, modes, ts=ts) self._sendModes(numeric, target, modes, ts=ts)
def topicServer(self, numeric, target, text): def topicServer(self, numeric, target, text):
"""Sends a TOPIC change from a PyLink server.""" """Sends a TOPIC change from a PyLink server."""
if not utils.isInternalServer(self.irc, numeric): if not self.irc.isInternalServer(numeric):
raise LookupError('No such PyLink server exists.') raise LookupError('No such PyLink server exists.')
self._send(numeric, 'TOPIC %s :%s' % (target, text)) self._send(numeric, 'TOPIC %s :%s' % (target, text))
self.irc.channels[target].topic = text self.irc.channels[target].topic = text
@ -247,7 +247,7 @@ class UnrealProtocol(TS6BaseProtocol):
raise NotImplementedError("Changing field %r of a client is " raise NotImplementedError("Changing field %r of a client is "
"unsupported by this protocol." % field) "unsupported by this protocol." % field)
if utils.isInternalClient(self.irc, target): if self.irc.isInternalClient(target):
# It is one of our clients, use SETIDENT/HOST/NAME. # It is one of our clients, use SETIDENT/HOST/NAME.
if field == 'IDENT': if field == 'IDENT':
self.irc.users[target].ident = text self.irc.users[target].ident = text
@ -284,7 +284,7 @@ class UnrealProtocol(TS6BaseProtocol):
def inviteClient(self, numeric, target, channel): def inviteClient(self, numeric, target, channel):
"""Sends an INVITE from a PyLink client..""" """Sends an INVITE from a PyLink client.."""
if not utils.isInternalClient(self.irc, numeric): if not self.irc.isInternalClient(numeric):
raise LookupError('No such PyLink client exists.') raise LookupError('No such PyLink client exists.')
self._send(numeric, 'INVITE %s %s' % (target, channel)) self._send(numeric, 'INVITE %s %s' % (target, channel))
@ -294,7 +294,7 @@ class UnrealProtocol(TS6BaseProtocol):
# sent to all ops in a channel. # sent to all ops in a channel.
# <- :unreal.midnight.vpn NOTICE @#test :[Knock] by GL|!gl@hidden-1C620195 (test) # <- :unreal.midnight.vpn NOTICE @#test :[Knock] by GL|!gl@hidden-1C620195 (test)
assert utils.isChannel(target), "Can only knock on channels!" assert utils.isChannel(target), "Can only knock on channels!"
sender = utils.clientToServer(self.irc, numeric) sender = self.irc.getServer(numeric)
s = '[Knock] by %s (%s)' % (utils.getHostmask(self.irc, numeric), text) s = '[Knock] by %s (%s)' % (utils.getHostmask(self.irc, numeric), text)
self._send(sender, 'NOTICE @%s :%s' % (target, s)) self._send(sender, 'NOTICE @%s :%s' % (target, s))
@ -487,9 +487,9 @@ class UnrealProtocol(TS6BaseProtocol):
self.irc.connected.set() self.irc.connected.set()
def _getNick(self, target): def _getNick(self, target):
"""Converts a nick argument to its matching UID. This differs from utils.nickToUid() """Converts a nick argument to its matching UID. This differs from irc.nickToUid()
in that it returns the original text instead of None, if no matching nick is found.""" in that it returns the original text instead of None, if no matching nick is found."""
target = utils.nickToUid(self.irc, target) or target target = self.irc.nickToUid(target) or target
if target not in self.irc.users and not utils.isChannel(target): if target not in self.irc.users and not utils.isChannel(target):
log.debug("(%s) Possible desync? Got command target %s, who " log.debug("(%s) Possible desync? Got command target %s, who "
"isn't in our user list!", self.irc.name, target) "isn't in our user list!", self.irc.name, target)

View File

@ -158,19 +158,6 @@ def toLower(irc, text):
text = text.replace('~', '^') text = text.replace('~', '^')
return text.lower() return text.lower()
def nickToUid(irc, nick):
"""Returns the UID of a user named nick, if present."""
nick = toLower(irc, nick)
for k, v in irc.users.copy().items():
if toLower(irc, v.nick) == nick:
return k
def clientToServer(irc, numeric):
"""Finds the SID of the server a user is on."""
for server in irc.servers:
if numeric in irc.servers[server].users:
return server
_nickregex = r'^[A-Za-z\|\\_\[\]\{\}\^\`][A-Z0-9a-z\-\|\\_\[\]\{\}\^\`]*$' _nickregex = r'^[A-Za-z\|\\_\[\]\{\}\^\`][A-Z0-9a-z\-\|\\_\[\]\{\}\^\`]*$'
def isNick(s, nicklen=None): def isNick(s, nicklen=None):
"""Returns whether the string given is a valid nick.""" """Returns whether the string given is a valid nick."""
@ -252,7 +239,7 @@ def parseModes(irc, target, args):
arg = args.pop(0) arg = args.pop(0)
# Convert nicks to UIDs implicitly; most IRCds will want # Convert nicks to UIDs implicitly; most IRCds will want
# this already. # this already.
arg = nickToUid(irc, arg) or arg arg = irc.nickToUid(arg) or arg
if arg not in irc.users: # Target doesn't exist, skip it. if arg not in irc.users: # Target doesn't exist, skip it.
log.debug('(%s) Skipping setting mode "%s %s"; the ' log.debug('(%s) Skipping setting mode "%s %s"; the '
'target doesn\'t seem to exist!', irc.name, 'target doesn\'t seem to exist!', irc.name,
@ -467,19 +454,6 @@ def reverseModes(irc, target, modes, oldobj=None):
else: else:
return set(newmodes) return set(newmodes)
def isInternalClient(irc, numeric):
"""
Checks whether the given numeric is a PyLink Client,
returning the SID of the server it's on if so.
"""
for sid in irc.servers:
if irc.servers[sid].internal and numeric in irc.servers[sid].users:
return sid
def isInternalServer(irc, sid):
"""Returns whether the given SID is an internal PyLink server."""
return (sid in irc.servers and irc.servers[sid].internal)
def isOper(irc, uid, allowAuthed=True, allowOper=True): def isOper(irc, uid, allowAuthed=True, allowOper=True):
""" """
Returns whether the given user has operator status on PyLink. This can be achieved Returns whether the given user has operator status on PyLink. This can be achieved
@ -514,7 +488,7 @@ def isManipulatableClient(irc, uid):
set True to prevent interactions with opers (like mode changes) from set True to prevent interactions with opers (like mode changes) from
causing desyncs. causing desyncs.
""" """
return isInternalClient(irc, uid) and irc.users[uid].manipulatable return irc.isInternalClient(uid) and irc.users[uid].manipulatable
def getHostmask(irc, user): def getHostmask(irc, user):
"""Returns the hostmask of the given user, if present.""" """Returns the hostmask of the given user, if present."""