mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-28 13:42:37 +01:00
parent
f23cff845c
commit
dab29cfc19
@ -101,19 +101,43 @@ class TestUtils(unittest.TestCase):
|
||||
('+b', '*!*@*.badisp.net')])
|
||||
self.assertEqual(res, '-o+l-nm+kb 9PYAAAAAA 50 hello *!*@*.badisp.net')
|
||||
|
||||
@unittest.skip('Wait, we need to work out the kinks first! (reversing changes of modes with arguments)')
|
||||
def _reverseModes(self, query, expected, target='#test'):
|
||||
res = utils.reverseModes(self.irc, target, query)
|
||||
self.assertEqual(res, expected)
|
||||
|
||||
def testReverseModes(self):
|
||||
f = lambda x: utils.reverseModes(self.irc, '#test', x)
|
||||
test = lambda x, y: self.assertEqual(utils.reverseModes(self.irc, '#test', x), y)
|
||||
# Strings.
|
||||
self.assertEqual(f("+nt-lk"), "-nt+lk")
|
||||
self.assertEqual(f("nt-k"), "-nt+k")
|
||||
self._reverseModes("+mi-lk test", "-mi+lk test")
|
||||
self._reverseModes("mi-k test", "-mi+k test")
|
||||
# Lists.
|
||||
self.assertEqual(f([('+m', None), ('+t', None), ('+l', '3'), ('-o', 'person')]),
|
||||
[('-m', None), ('-t', None), ('-l', '3'), ('+o', 'person')])
|
||||
self._reverseModes([('+m', None), ('+r', None), ('+l', '3'), ('-o', 'person')],
|
||||
{('-m', None), ('-r', None), ('-l', None), ('+o', 'person')})
|
||||
# Sets.
|
||||
self.assertEqual(f({('s', None), ('+o', 'whoever')}), {('-s', None), ('-o', 'whoever')})
|
||||
self._reverseModes({('s', None), ('+o', 'whoever')}, {('-s', None), ('-o', 'whoever')})
|
||||
# Combining modes with an initial + and those without
|
||||
self.assertEqual(f({('s', None), ('+n', None)}), {('-s', None), ('-n', None)})
|
||||
self._reverseModes({('s', None), ('+R', None)}, {('-s', None), ('-R', None)})
|
||||
|
||||
def testReverseModesUser(self):
|
||||
self._reverseModes({('+i', None), ('l', 'asfasd')}, {('-i', None), ('-l', 'asfasd')},
|
||||
target=self.irc.pseudoclient.uid)
|
||||
|
||||
def testReverseModesExisting(self):
|
||||
utils.applyModes(self.irc, '#test', [('+m', None), ('+l', '50'), ('+k', 'supersecret'),
|
||||
('+o', '9PYAAAAAA')])
|
||||
|
||||
self._reverseModes({('+i', None), ('+l', '3')}, {('-i', None), ('+l', '50')})
|
||||
self._reverseModes('-n', '+n')
|
||||
self._reverseModes('-l', '+l 50')
|
||||
self._reverseModes('+k derp', '+k supersecret')
|
||||
self._reverseModes('-mk *', '+mk supersecret')
|
||||
|
||||
# Existing modes are ignored.
|
||||
self._reverseModes([('+t', None)], set())
|
||||
self._reverseModes('+n', '+')
|
||||
self._reverseModes('+oo GLolol 9PYAAAAAA', '-o GLolol')
|
||||
self._reverseModes('+o 9PYAAAAAA', '+')
|
||||
self._reverseModes('+vvvvM test abcde atat abcd', '-vvvvM test abcde atat abcd')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
79
utils.py
79
utils.py
@ -326,10 +326,20 @@ def joinModes(modes):
|
||||
modelist += ' %s' % ' '.join(args)
|
||||
return modelist
|
||||
|
||||
def reverseModes(irc, target, modes):
|
||||
"""<mode string/mode list>
|
||||
def _flip(mode):
|
||||
"""Flips a mode character."""
|
||||
# Make it a list first, strings don't support item assignment
|
||||
mode = list(mode)
|
||||
if mode[0] == '-': # Query is something like "-n"
|
||||
mode[0] = '+' # Change it to "+n"
|
||||
elif mode[0] == '+':
|
||||
mode[0] = '-'
|
||||
else: # No prefix given, assume +
|
||||
mode.insert(0, '-')
|
||||
return ''.join(mode)
|
||||
|
||||
Reverses/Inverts the mode string or mode list given.
|
||||
def reverseModes(irc, target, modes):
|
||||
"""Reverses/Inverts the mode string or mode list given.
|
||||
|
||||
"+nt-lk" => "-nt+lk"
|
||||
"nt-k" => "-nt+k"
|
||||
@ -338,21 +348,56 @@ def reverseModes(irc, target, modes):
|
||||
[('s', None), ('+n', None)] => [('-s', None), ('-n', None)]
|
||||
"""
|
||||
origtype = type(modes)
|
||||
# Operate on joined modestrings only; it's easier.
|
||||
if origtype != str:
|
||||
modes = joinModes(modes)
|
||||
# Swap the +'s and -'s by replacing one with a dummy character, and then changing it back.
|
||||
assert '\x00' not in modes, 'NUL cannot be in the mode list (it is a reserved character)!'
|
||||
if not modes.startswith(('+', '-')):
|
||||
modes = '+' + modes
|
||||
newmodes = modes.replace('+', '\x00')
|
||||
newmodes = newmodes.replace('-', '+')
|
||||
newmodes = newmodes.replace('\x00', '-')
|
||||
if origtype != str:
|
||||
# If the original query isn't a string, send back the parseModes() output.
|
||||
return parseModes(irc, target, newmodes.split(" "))
|
||||
# If the query is a string, we have to parse it first.
|
||||
if origtype == str:
|
||||
modes = parseModes(irc, target, modes.split(" "))
|
||||
# Get the current mode list first.
|
||||
if isChannel(target):
|
||||
oldmodes = irc.channels[target].modes.copy()
|
||||
possible_modes = irc.cmodes.copy()
|
||||
# For channels, this also includes the list of prefix modes.
|
||||
possible_modes['*A'] += ''.join(irc.prefixmodes)
|
||||
for name, userlist in irc.channels[target].prefixmodes.items():
|
||||
try:
|
||||
oldmodes.update([(irc.cmodes[name[:-1]], u) for u in userlist])
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
return newmodes
|
||||
oldmodes = irc.users[target].modes
|
||||
possible_modes = irc.umodes
|
||||
newmodes = []
|
||||
for char, arg in modes:
|
||||
# Mode types:
|
||||
# A = Mode that adds or removes a nick or address to a list. 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.
|
||||
# D = Mode that changes a setting and never has a parameter.
|
||||
mchar = char[-1]
|
||||
if mchar in possible_modes['*B'] + possible_modes['*C']:
|
||||
# We need to find the current mode list, so we can reset arguments
|
||||
# for modes that have arguments. For example, setting +l 30 on a channel
|
||||
# that had +l 50 set should give "+l 30", not "-l".
|
||||
oldarg = [m for m in oldmodes if m[0] == mchar]
|
||||
if oldarg: # Old mode argument for this mode existed, use that.
|
||||
oldarg = oldarg[0]
|
||||
mpair = ('+%s' % oldarg[0], oldarg[1])
|
||||
else: # Not found, flip the mode then.
|
||||
# Mode takes no arguments when unsetting.
|
||||
if mchar in possible_modes['*C'] and char[0] != '-':
|
||||
arg = None
|
||||
mpair = (_flip(char), arg)
|
||||
else:
|
||||
mpair = (_flip(char), arg)
|
||||
if char[0] != '-' and (mchar, arg) in oldmodes:
|
||||
# Mode is already set.
|
||||
continue
|
||||
newmodes.append(mpair)
|
||||
|
||||
if origtype == str:
|
||||
# If the original query is a string, send it back as a string.
|
||||
return joinModes(newmodes)
|
||||
else:
|
||||
return set(newmodes)
|
||||
|
||||
def isInternalClient(irc, numeric):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user