mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-24 19:52:53 +01:00
Support prefix modes (+qaohv); refactor applyModes to apply in place; add removeuser() to IrcChannel
Closes #16.
This commit is contained in:
parent
d62a413c50
commit
b22f674785
15
classes.py
15
classes.py
@ -1,3 +1,5 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
class IrcUser():
|
class IrcUser():
|
||||||
def __init__(self, nick, ts, uid, ident='null', host='null',
|
def __init__(self, nick, ts, uid, ident='null', host='null',
|
||||||
realname='PyLink dummy client', realhost='null',
|
realname='PyLink dummy client', realhost='null',
|
||||||
@ -37,13 +39,16 @@ class IrcChannel():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.users = set()
|
self.users = set()
|
||||||
self.modes = set()
|
self.modes = set()
|
||||||
'''
|
self.prefixmodes = {'ops': set(), 'halfops': set(), 'voices': set(),
|
||||||
self.ops = []
|
'owners': set(), 'admins': set()}
|
||||||
self.halfops = []
|
|
||||||
self.voices = []
|
|
||||||
'''
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__dict__)
|
return repr(self.__dict__)
|
||||||
|
|
||||||
|
def removeuser(self, target):
|
||||||
|
for s in self.prefixmodes.values():
|
||||||
|
s.discard(target)
|
||||||
|
self.users.discard(target)
|
||||||
|
|
||||||
class ProtocolError(Exception):
|
class ProtocolError(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -73,11 +73,8 @@ def removeClient(irc, numeric):
|
|||||||
|
|
||||||
Removes a client from our internal databases, regardless
|
Removes a client from our internal databases, regardless
|
||||||
of whether it's one of our pseudoclients or not."""
|
of whether it's one of our pseudoclients or not."""
|
||||||
for k, v in copy(irc.channels).items():
|
for v in irc.channels.values():
|
||||||
irc.channels[k].users.discard(numeric)
|
v.removeuser(source)
|
||||||
if not irc.channels[k].users:
|
|
||||||
# Clear empty channels
|
|
||||||
del irc.channels[k]
|
|
||||||
sid = numeric[:3]
|
sid = numeric[:3]
|
||||||
print('Removing client %s from irc.users' % numeric)
|
print('Removing client %s from irc.users' % numeric)
|
||||||
del irc.users[numeric]
|
del irc.users[numeric]
|
||||||
@ -189,9 +186,7 @@ def handle_kick(irc, source, command, args):
|
|||||||
def handle_part(irc, source, command, args):
|
def handle_part(irc, source, command, args):
|
||||||
channel = args[0].lower()
|
channel = args[0].lower()
|
||||||
# We should only get PART commands for channels that exist, right??
|
# We should only get PART commands for channels that exist, right??
|
||||||
irc.channels[channel].users.remove(source)
|
irc.channels[channel].removeuser(source)
|
||||||
if not irc.channels[channel].users:
|
|
||||||
del irc.channels[channel]
|
|
||||||
try:
|
try:
|
||||||
reason = args[1]
|
reason = args[1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -209,24 +204,12 @@ def handle_fjoin(irc, servernumeric, command, args):
|
|||||||
userlist = args[-1].split()
|
userlist = args[-1].split()
|
||||||
ts = args[1]
|
ts = args[1]
|
||||||
modestring = args[2:-1] or args[2]
|
modestring = args[2:-1] or args[2]
|
||||||
irc.channels[channel].modes = utils.applyModes(irc.channels[channel].modes, utils.parseModes(irc, modestring))
|
utils.applyModes(irc, channel, utils.parseModes(irc, channel, modestring))
|
||||||
namelist = []
|
namelist = []
|
||||||
for user in userlist:
|
for user in userlist:
|
||||||
modeprefix, user = user.split(',', 1)
|
modeprefix, user = user.split(',', 1)
|
||||||
namelist.append(user)
|
namelist.append(user)
|
||||||
'''
|
utils.applyModes(irc, channel, [('+%s' % mode, user) for mode in modeprefix])
|
||||||
for mode in modeprefix:
|
|
||||||
# Note that a user can have more than one mode prefix (e.g. they have both +o and +v),
|
|
||||||
# so they would be added to both lists.
|
|
||||||
|
|
||||||
# left to right: m_ojoin, m_operprefix, owner (~/+q), admin (&/+a), and op (!/+o)
|
|
||||||
if mode in 'Yyqao':
|
|
||||||
irc.channels[channel].ops.append(user)
|
|
||||||
if mode == 'h':
|
|
||||||
irc.channels[channel].halfops.append(user)
|
|
||||||
if mode == 'v':
|
|
||||||
irc.channels[channel].voices.append(user)
|
|
||||||
'''
|
|
||||||
irc.channels[channel].users.add(user)
|
irc.channels[channel].users.add(user)
|
||||||
return {'channel': channel, 'users': namelist}
|
return {'channel': channel, 'users': namelist}
|
||||||
|
|
||||||
@ -235,9 +218,9 @@ def handle_uid(irc, numeric, command, args):
|
|||||||
uid, ts, nick, realhost, host, ident, ip = args[0:7]
|
uid, ts, nick, realhost, host, ident, ip = args[0:7]
|
||||||
realname = args[-1]
|
realname = args[-1]
|
||||||
irc.users[uid] = IrcUser(nick, ts, uid, ident, host, realname, realhost, ip)
|
irc.users[uid] = IrcUser(nick, ts, uid, ident, host, realname, realhost, ip)
|
||||||
parsedmodes = utils.parseModes(irc, [args[8], args[9]], usermodes=True)
|
parsedmodes = utils.parseModes(irc, uid, [args[8], args[9]])
|
||||||
print('Applying modes %s for %s' % (parsedmodes, uid))
|
print('Applying modes %s for %s' % (parsedmodes, uid))
|
||||||
irc.users[uid].modes = utils.applyModes(irc.users[uid].modes, parsedmodes)
|
utils.applyModes(irc, uid, parsedmodes)
|
||||||
irc.servers[numeric].users.append(uid)
|
irc.servers[numeric].users.append(uid)
|
||||||
return {'uid': uid, 'ts': ts, 'nick': nick, 'realhost': realhost, 'host': host, 'ident': ident, 'ip': ip}
|
return {'uid': uid, 'ts': ts, 'nick': nick, 'realhost': realhost, 'host': host, 'ident': ident, 'ip': ip}
|
||||||
|
|
||||||
@ -284,8 +267,8 @@ def handle_fmode(irc, numeric, command, args):
|
|||||||
# <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD
|
# <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD
|
||||||
channel = args[0].lower()
|
channel = args[0].lower()
|
||||||
modes = args[2:]
|
modes = args[2:]
|
||||||
changedmodes = utils.parseModes(irc, modes)
|
changedmodes = utils.parseModes(irc, channel, modes)
|
||||||
irc.channels[channel].modes = utils.applyModes(irc.channels[channel].modes, changedmodes)
|
utils.applyModes(irc, channel, changedmodes)
|
||||||
return {'target': channel, 'modes': changedmodes}
|
return {'target': channel, 'modes': changedmodes}
|
||||||
|
|
||||||
def handle_mode(irc, numeric, command, args):
|
def handle_mode(irc, numeric, command, args):
|
||||||
@ -294,8 +277,8 @@ def handle_mode(irc, numeric, command, args):
|
|||||||
# <- :70MAAAAAA MODE 70MAAAAAA -i+xc
|
# <- :70MAAAAAA MODE 70MAAAAAA -i+xc
|
||||||
target = args[0]
|
target = args[0]
|
||||||
modestrings = args[1:]
|
modestrings = args[1:]
|
||||||
changedmodes = utils.parseModes(irc, modestrings, usermodes=True)
|
changedmodes = utils.parseModes(irc, numeric, modestrings)
|
||||||
irc.users[numeric].modes = utils.applyModes(irc.users[numeric].modes, changedmodes)
|
utils.applyModes(irc, numeric, changedmodes)
|
||||||
return {'target': target, 'modes': changedmodes}
|
return {'target': target, 'modes': changedmodes}
|
||||||
|
|
||||||
def handle_squit(irc, numeric, command, args):
|
def handle_squit(irc, numeric, command, args):
|
||||||
|
38
utils.py
38
utils.py
@ -83,7 +83,7 @@ def isServerName(s):
|
|||||||
return _isASCII(s) and '.' in s and not s.startswith('.') \
|
return _isASCII(s) and '.' in s and not s.startswith('.') \
|
||||||
and not s.endswith('.')
|
and not s.endswith('.')
|
||||||
|
|
||||||
def parseModes(irc, args, usermodes=False):
|
def parseModes(irc, target, args):
|
||||||
"""Parses a mode string into a list of (mode, argument) tuples.
|
"""Parses a mode string into a list of (mode, argument) tuples.
|
||||||
['+mitl-o', '3', 'person'] => [('+m', None), ('+i', None), ('+t', None), ('+l', '3'), ('-o', 'person')]
|
['+mitl-o', '3', 'person'] => [('+m', None), ('+i', None), ('+t', None), ('+l', '3'), ('-o', 'person')]
|
||||||
"""
|
"""
|
||||||
@ -92,7 +92,7 @@ def parseModes(irc, args, usermodes=False):
|
|||||||
# B = Mode that changes a setting and always has a parameter.
|
# B = Mode that changes a setting and always has a parameter.
|
||||||
# C = Mode that changes a setting and only has a parameter when set.
|
# C = Mode that changes a setting and only has a parameter when set.
|
||||||
# D = Mode that changes a setting and never has a parameter.
|
# D = Mode that changes a setting and never has a parameter.
|
||||||
print(args)
|
usermodes = not isChannel(target)
|
||||||
modestring = args[0]
|
modestring = args[0]
|
||||||
if not modestring:
|
if not modestring:
|
||||||
return ValueError('No modes supplied in parseModes query: %r' % modes)
|
return ValueError('No modes supplied in parseModes query: %r' % modes)
|
||||||
@ -117,8 +117,7 @@ def parseModes(irc, args, usermodes=False):
|
|||||||
elif mode in irc.prefixmodes and not usermodes:
|
elif mode in irc.prefixmodes and not usermodes:
|
||||||
# We're setting a prefix mode on someone (e.g. +o user1)
|
# We're setting a prefix mode on someone (e.g. +o user1)
|
||||||
print('%s: prefixmode.' % mode)
|
print('%s: prefixmode.' % mode)
|
||||||
# TODO: handle this properly (issue #16).
|
arg = args.pop(0)
|
||||||
continue
|
|
||||||
elif prefix == '+' and mode in supported_modes['*C']:
|
elif prefix == '+' and mode in supported_modes['*C']:
|
||||||
# Only has parameter when setting.
|
# Only has parameter when setting.
|
||||||
print('%s: Only has parameter when setting.' % mode)
|
print('%s: Only has parameter when setting.' % mode)
|
||||||
@ -126,11 +125,37 @@ def parseModes(irc, args, usermodes=False):
|
|||||||
res.append((prefix + mode, arg))
|
res.append((prefix + mode, arg))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def applyModes(modelist, changedmodes):
|
def applyModes(irc, target, changedmodes):
|
||||||
modelist = modelist.copy()
|
usermodes = not isChannel(target)
|
||||||
|
print('usermodes? %s' % usermodes)
|
||||||
|
if usermodes:
|
||||||
|
modelist = irc.users[target].modes
|
||||||
|
else:
|
||||||
|
modelist = irc.channels[target].modes
|
||||||
print('Initial modelist: %s' % modelist)
|
print('Initial modelist: %s' % modelist)
|
||||||
print('Changedmodes: %r' % changedmodes)
|
print('Changedmodes: %r' % changedmodes)
|
||||||
for mode in changedmodes:
|
for mode in changedmodes:
|
||||||
|
if not usermodes:
|
||||||
|
pmode = ''
|
||||||
|
for m in ('owner', 'admin', 'op', 'halfop', 'voice'):
|
||||||
|
if m in irc.cmodes and mode[0][1] == irc.cmodes[m]:
|
||||||
|
pmode = m+'s'
|
||||||
|
print('pmode? %s' % pmode)
|
||||||
|
if pmode:
|
||||||
|
print('pmode == True')
|
||||||
|
print(mode)
|
||||||
|
print(irc.channels[target].prefixmodes)
|
||||||
|
pmodelist = irc.channels[target].prefixmodes[pmode]
|
||||||
|
print(pmodelist)
|
||||||
|
print('Initial pmodelist: %s' % pmodelist)
|
||||||
|
if mode[0][0] == '+':
|
||||||
|
pmodelist.add(mode[1])
|
||||||
|
print('+')
|
||||||
|
else:
|
||||||
|
pmodelist.discard(mode[1])
|
||||||
|
print('-')
|
||||||
|
print('Final pmodelist: %s' % pmodelist)
|
||||||
|
continue
|
||||||
if mode[0][0] == '+':
|
if mode[0][0] == '+':
|
||||||
# We're adding a mode
|
# We're adding a mode
|
||||||
modelist.add(mode)
|
modelist.add(mode)
|
||||||
@ -141,7 +166,6 @@ def applyModes(modelist, changedmodes):
|
|||||||
modelist.discard(mode)
|
modelist.discard(mode)
|
||||||
print('Removing mode %r' % str(mode))
|
print('Removing mode %r' % str(mode))
|
||||||
print('Final modelist: %s' % modelist)
|
print('Final modelist: %s' % modelist)
|
||||||
return modelist
|
|
||||||
|
|
||||||
def joinModes(modes):
|
def joinModes(modes):
|
||||||
modelist = ''
|
modelist = ''
|
||||||
|
Loading…
Reference in New Issue
Block a user