mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 01:09:22 +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():
|
||||
def __init__(self, nick, ts, uid, ident='null', host='null',
|
||||
realname='PyLink dummy client', realhost='null',
|
||||
@ -37,13 +39,16 @@ class IrcChannel():
|
||||
def __init__(self):
|
||||
self.users = set()
|
||||
self.modes = set()
|
||||
'''
|
||||
self.ops = []
|
||||
self.halfops = []
|
||||
self.voices = []
|
||||
'''
|
||||
self.prefixmodes = {'ops': set(), 'halfops': set(), 'voices': set(),
|
||||
'owners': set(), 'admins': set()}
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.__dict__)
|
||||
|
||||
def removeuser(self, target):
|
||||
for s in self.prefixmodes.values():
|
||||
s.discard(target)
|
||||
self.users.discard(target)
|
||||
|
||||
class ProtocolError(Exception):
|
||||
pass
|
||||
|
@ -73,11 +73,8 @@ def removeClient(irc, numeric):
|
||||
|
||||
Removes a client from our internal databases, regardless
|
||||
of whether it's one of our pseudoclients or not."""
|
||||
for k, v in copy(irc.channels).items():
|
||||
irc.channels[k].users.discard(numeric)
|
||||
if not irc.channels[k].users:
|
||||
# Clear empty channels
|
||||
del irc.channels[k]
|
||||
for v in irc.channels.values():
|
||||
v.removeuser(source)
|
||||
sid = numeric[:3]
|
||||
print('Removing client %s from 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):
|
||||
channel = args[0].lower()
|
||||
# We should only get PART commands for channels that exist, right??
|
||||
irc.channels[channel].users.remove(source)
|
||||
if not irc.channels[channel].users:
|
||||
del irc.channels[channel]
|
||||
irc.channels[channel].removeuser(source)
|
||||
try:
|
||||
reason = args[1]
|
||||
except IndexError:
|
||||
@ -209,24 +204,12 @@ def handle_fjoin(irc, servernumeric, command, args):
|
||||
userlist = args[-1].split()
|
||||
ts = args[1]
|
||||
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 = []
|
||||
for user in userlist:
|
||||
modeprefix, user = user.split(',', 1)
|
||||
namelist.append(user)
|
||||
'''
|
||||
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)
|
||||
'''
|
||||
utils.applyModes(irc, channel, [('+%s' % mode, user) for mode in modeprefix])
|
||||
irc.channels[channel].users.add(user)
|
||||
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]
|
||||
realname = args[-1]
|
||||
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))
|
||||
irc.users[uid].modes = utils.applyModes(irc.users[uid].modes, parsedmodes)
|
||||
utils.applyModes(irc, uid, parsedmodes)
|
||||
irc.servers[numeric].users.append(uid)
|
||||
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
|
||||
channel = args[0].lower()
|
||||
modes = args[2:]
|
||||
changedmodes = utils.parseModes(irc, modes)
|
||||
irc.channels[channel].modes = utils.applyModes(irc.channels[channel].modes, changedmodes)
|
||||
changedmodes = utils.parseModes(irc, channel, modes)
|
||||
utils.applyModes(irc, channel, changedmodes)
|
||||
return {'target': channel, 'modes': changedmodes}
|
||||
|
||||
def handle_mode(irc, numeric, command, args):
|
||||
@ -294,8 +277,8 @@ def handle_mode(irc, numeric, command, args):
|
||||
# <- :70MAAAAAA MODE 70MAAAAAA -i+xc
|
||||
target = args[0]
|
||||
modestrings = args[1:]
|
||||
changedmodes = utils.parseModes(irc, modestrings, usermodes=True)
|
||||
irc.users[numeric].modes = utils.applyModes(irc.users[numeric].modes, changedmodes)
|
||||
changedmodes = utils.parseModes(irc, numeric, modestrings)
|
||||
utils.applyModes(irc, numeric, changedmodes)
|
||||
return {'target': target, 'modes': changedmodes}
|
||||
|
||||
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('.') \
|
||||
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.
|
||||
['+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.
|
||||
# C = Mode that changes a setting and only has a parameter when set.
|
||||
# D = Mode that changes a setting and never has a parameter.
|
||||
print(args)
|
||||
usermodes = not isChannel(target)
|
||||
modestring = args[0]
|
||||
if not modestring:
|
||||
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:
|
||||
# We're setting a prefix mode on someone (e.g. +o user1)
|
||||
print('%s: prefixmode.' % mode)
|
||||
# TODO: handle this properly (issue #16).
|
||||
continue
|
||||
arg = args.pop(0)
|
||||
elif prefix == '+' and mode in supported_modes['*C']:
|
||||
# Only has parameter when setting.
|
||||
print('%s: Only has parameter when setting.' % mode)
|
||||
@ -126,11 +125,37 @@ def parseModes(irc, args, usermodes=False):
|
||||
res.append((prefix + mode, arg))
|
||||
return res
|
||||
|
||||
def applyModes(modelist, changedmodes):
|
||||
modelist = modelist.copy()
|
||||
def applyModes(irc, target, changedmodes):
|
||||
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('Changedmodes: %r' % 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] == '+':
|
||||
# We're adding a mode
|
||||
modelist.add(mode)
|
||||
@ -141,7 +166,6 @@ def applyModes(modelist, changedmodes):
|
||||
modelist.discard(mode)
|
||||
print('Removing mode %r' % str(mode))
|
||||
print('Final modelist: %s' % modelist)
|
||||
return modelist
|
||||
|
||||
def joinModes(modes):
|
||||
modelist = ''
|
||||
|
Loading…
Reference in New Issue
Block a user