mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-02-17 06:00:42 +01:00
commit
64772d42cc
@ -43,5 +43,7 @@ def configure(advanced):
|
|||||||
Alias = conf.registerPlugin('Alias')
|
Alias = conf.registerPlugin('Alias')
|
||||||
conf.registerGroup(Alias, 'aliases')
|
conf.registerGroup(Alias, 'aliases')
|
||||||
conf.registerGroup(Alias, 'escapedaliases')
|
conf.registerGroup(Alias, 'escapedaliases')
|
||||||
|
conf.registerGlobalValue(Alias, 'validName',
|
||||||
|
registry.String(r'^[^\x00-\x20]+$', _("""Regex which alias names must match in order to be valid""")))
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
@ -102,9 +102,12 @@ def findBiggestAt(alias):
|
|||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def needsEscaping(alias):
|
||||||
|
return '.' in alias or '|' in alias
|
||||||
|
|
||||||
def escapeAlias(alias):
|
def escapeAlias(alias):
|
||||||
"""Encodes [a-z0-9.]+ into [a-z][a-z0-9].
|
"""Encodes dots and pipes
|
||||||
Format: a<number of escaped chars>a(<index>d)+<word without dots>."""
|
Format: a<number of escaped chars>a(<index>(d|p))+<word without dots or pipes>."""
|
||||||
prefix = ''
|
prefix = ''
|
||||||
new_alias = ''
|
new_alias = ''
|
||||||
prefixes = 0
|
prefixes = 0
|
||||||
@ -242,19 +245,19 @@ class Alias(callbacks.Plugin):
|
|||||||
# XXX This should go. aliases should be a space separate list, etc.
|
# XXX This should go. aliases should be a space separate list, etc.
|
||||||
group = conf.supybot.plugins.Alias.aliases
|
group = conf.supybot.plugins.Alias.aliases
|
||||||
group2 = conf.supybot.plugins.Alias.escapedaliases
|
group2 = conf.supybot.plugins.Alias.escapedaliases
|
||||||
|
prefixLen = len(registry.split('supybot.plugins.alias.aliases'))
|
||||||
for (name, alias) in registry._cache.items():
|
for (name, alias) in registry._cache.items():
|
||||||
name = name.lower()
|
name = name.lower()
|
||||||
|
nameSplit = registry.split(name)
|
||||||
|
if len(nameSplit) > prefixLen+1:
|
||||||
|
continue
|
||||||
if name.startswith('supybot.plugins.alias.aliases.'):
|
if name.startswith('supybot.plugins.alias.aliases.'):
|
||||||
name = name[len('supybot.plugins.alias.aliases.'):]
|
name = nameSplit[-1]
|
||||||
if '.' in name:
|
|
||||||
continue
|
|
||||||
conf.registerGlobalValue(group, name, registry.String('', ''))
|
conf.registerGlobalValue(group, name, registry.String('', ''))
|
||||||
conf.registerGlobalValue(group.get(name), 'locked',
|
conf.registerGlobalValue(group.get(name), 'locked',
|
||||||
registry.Boolean(False, ''))
|
registry.Boolean(False, ''))
|
||||||
elif name.startswith('supybot.plugins.alias.escapedaliases.'):
|
elif name.startswith('supybot.plugins.alias.escapedaliases.'):
|
||||||
name = name[len('supybot.plugins.alias.escapedaliases.'):]
|
name = nameSplit[-1]
|
||||||
if '.' in name:
|
|
||||||
continue
|
|
||||||
conf.registerGlobalValue(group2, name,
|
conf.registerGlobalValue(group2, name,
|
||||||
registry.String('', ''))
|
registry.String('', ''))
|
||||||
conf.registerGlobalValue(group2.get(name),
|
conf.registerGlobalValue(group2.get(name),
|
||||||
@ -269,7 +272,7 @@ class Alias(callbacks.Plugin):
|
|||||||
command = value()
|
command = value()
|
||||||
locked = value.locked()
|
locked = value.locked()
|
||||||
self.aliases[unescapeAlias(name)] = [command, locked, None]
|
self.aliases[unescapeAlias(name)] = [command, locked, None]
|
||||||
for (alias, (command, locked, _)) in self.aliases.items():
|
for (alias, (command, locked, _)) in self.aliases.copy().items():
|
||||||
try:
|
try:
|
||||||
self.addAlias(irc, alias, command, locked)
|
self.addAlias(irc, alias, command, locked)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -295,6 +298,38 @@ class Alias(callbacks.Plugin):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return self.aliases[command[0]][2]
|
return self.aliases[command[0]][2]
|
||||||
|
|
||||||
|
def aliasRegistryGroup(self, name):
|
||||||
|
if needsEscaping(name):
|
||||||
|
return self.registryValue('escapedaliases', value=False)
|
||||||
|
else:
|
||||||
|
return self.registryValue('aliases', value=False)
|
||||||
|
|
||||||
|
def aliasRegistryNode(self, name):
|
||||||
|
group = self.aliasRegistryGroup(name)
|
||||||
|
if needsEscaping(name):
|
||||||
|
return group.get(escapeAlias(name))
|
||||||
|
else:
|
||||||
|
return group.get(name)
|
||||||
|
|
||||||
|
def aliasRegistryRemove(self, name):
|
||||||
|
group = self.aliasRegistryGroup(name)
|
||||||
|
if needsEscaping(name):
|
||||||
|
group.unregister(escapeAlias(name))
|
||||||
|
else:
|
||||||
|
group.unregister(name)
|
||||||
|
|
||||||
|
|
||||||
|
def setLocked(self, name, value):
|
||||||
|
self.aliases[name][1] = value
|
||||||
|
self.aliasRegistryNode(name).locked.setValue(value)
|
||||||
|
|
||||||
|
def isValidName(self, name):
|
||||||
|
if not re.search(self.registryValue('validName'), name):
|
||||||
|
return False
|
||||||
|
if not registry.isValidRegistryName(name):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def lock(self, irc, msg, args, name):
|
def lock(self, irc, msg, args, name):
|
||||||
"""<alias>
|
"""<alias>
|
||||||
@ -302,8 +337,7 @@ class Alias(callbacks.Plugin):
|
|||||||
Locks an alias so that no one else can change it.
|
Locks an alias so that no one else can change it.
|
||||||
"""
|
"""
|
||||||
if name in self.aliases and self.isCommandMethod(name):
|
if name in self.aliases and self.isCommandMethod(name):
|
||||||
self.aliases[name][1] = True
|
self.setLocked(name, True)
|
||||||
conf.supybot.plugins.Alias.aliases.get(name).locked.setValue(True)
|
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
else:
|
else:
|
||||||
irc.error(_('There is no such alias.'))
|
irc.error(_('There is no such alias.'))
|
||||||
@ -316,20 +350,15 @@ class Alias(callbacks.Plugin):
|
|||||||
Unlocks an alias so that people can define new aliases over it.
|
Unlocks an alias so that people can define new aliases over it.
|
||||||
"""
|
"""
|
||||||
if name in self.aliases and self.isCommandMethod(name):
|
if name in self.aliases and self.isCommandMethod(name):
|
||||||
self.aliases[name][1] = False
|
self.setLocked(name, False)
|
||||||
conf.supybot.plugins.Alias.aliases.get(name).locked.setValue(False)
|
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
else:
|
else:
|
||||||
irc.error(_('There is no such alias.'))
|
irc.error(_('There is no such alias.'))
|
||||||
unlock = wrap(unlock, [('checkCapability', 'admin'), 'commandName'])
|
unlock = wrap(unlock, [('checkCapability', 'admin'), 'commandName'])
|
||||||
|
|
||||||
_validNameRe = re.compile(r'^[a-z.|!?][a-z0-9.|!]*$')
|
|
||||||
def addAlias(self, irc, name, alias, lock=False):
|
def addAlias(self, irc, name, alias, lock=False):
|
||||||
if not self._validNameRe.search(name):
|
if not self.isValidName(name):
|
||||||
raise AliasError('Names can only contain alphanumerical '
|
raise AliasError('Invalid alias name.')
|
||||||
'characters, dots, pipes, and '
|
|
||||||
'exclamation/interrogatin marks '
|
|
||||||
'(and the first character cannot be a number).')
|
|
||||||
realName = callbacks.canonicalName(name)
|
realName = callbacks.canonicalName(name)
|
||||||
if name != realName:
|
if name != realName:
|
||||||
s = format(_('That name isn\'t valid. Try %q instead.'), realName)
|
s = format(_('That name isn\'t valid. Try %q instead.'), realName)
|
||||||
@ -345,15 +374,14 @@ class Alias(callbacks.Plugin):
|
|||||||
raise AliasError(format('Alias %q is locked.', name))
|
raise AliasError(format('Alias %q is locked.', name))
|
||||||
f = makeNewAlias(name, alias)
|
f = makeNewAlias(name, alias)
|
||||||
f = types.MethodType(f, self)
|
f = types.MethodType(f, self)
|
||||||
if '.' in name or '|' in name:
|
|
||||||
aliasGroup = self.registryValue('escapedaliases', value=False)
|
|
||||||
confname = escapeAlias(name)
|
|
||||||
else:
|
|
||||||
aliasGroup = self.registryValue('aliases', value=False)
|
|
||||||
confname = name
|
|
||||||
if name in self.aliases:
|
if name in self.aliases:
|
||||||
# We gotta remove it so its value gets updated.
|
# We gotta remove it so its value gets updated.
|
||||||
aliasGroup.unregister(confname)
|
self.aliasRegistryRemove(name)
|
||||||
|
aliasGroup = self.aliasRegistryGroup(name)
|
||||||
|
if needsEscaping(name):
|
||||||
|
confname = escapeAlias(name)
|
||||||
|
else:
|
||||||
|
confname = name
|
||||||
conf.registerGlobalValue(aliasGroup, confname,
|
conf.registerGlobalValue(aliasGroup, confname,
|
||||||
registry.String(alias, ''))
|
registry.String(alias, ''))
|
||||||
conf.registerGlobalValue(aliasGroup.get(confname), 'locked',
|
conf.registerGlobalValue(aliasGroup.get(confname), 'locked',
|
||||||
@ -365,11 +393,7 @@ class Alias(callbacks.Plugin):
|
|||||||
if name in self.aliases and self.isCommandMethod(name):
|
if name in self.aliases and self.isCommandMethod(name):
|
||||||
if evenIfLocked or not self.aliases[name][1]:
|
if evenIfLocked or not self.aliases[name][1]:
|
||||||
del self.aliases[name]
|
del self.aliases[name]
|
||||||
if '.' in name or '|' in name:
|
self.aliasRegistryRemove(name)
|
||||||
conf.supybot.plugins.Alias.escapedaliases.unregister(
|
|
||||||
escapeAlias(name))
|
|
||||||
else:
|
|
||||||
conf.supybot.plugins.Alias.aliases.unregister(name)
|
|
||||||
else:
|
else:
|
||||||
raise AliasError('That alias is locked.')
|
raise AliasError('That alias is locked.')
|
||||||
else:
|
else:
|
||||||
@ -412,6 +436,36 @@ class Alias(callbacks.Plugin):
|
|||||||
irc.error(str(e))
|
irc.error(str(e))
|
||||||
remove = wrap(remove, ['commandName'])
|
remove = wrap(remove, ['commandName'])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def list(self, irc, msg, args, optlist):
|
||||||
|
"""[--locked|--unlocked]
|
||||||
|
|
||||||
|
Lists alias names of a particular type, defaults to all aliases if no
|
||||||
|
--locked or --unlocked option is given.
|
||||||
|
"""
|
||||||
|
optlist = dict(optlist)
|
||||||
|
if len(optlist)>1:
|
||||||
|
irc.error(_('Cannot specify --locked and --unlocked simultaneously'))
|
||||||
|
return
|
||||||
|
aliases = []
|
||||||
|
for name in self.aliases.keys():
|
||||||
|
if self.isCommandMethod(name):
|
||||||
|
if 'locked' in optlist:
|
||||||
|
if self.aliases[name][1]: aliases.append(name)
|
||||||
|
elif 'unlocked' in optlist:
|
||||||
|
if not self.aliases[name][1]: aliases.append(name)
|
||||||
|
else:
|
||||||
|
aliases.append(name)
|
||||||
|
if aliases:
|
||||||
|
aliases.sort()
|
||||||
|
irc.reply(format('%L', aliases))
|
||||||
|
else:
|
||||||
|
if len(optlist):
|
||||||
|
irc.reply(_('There are no aliases of that type.'))
|
||||||
|
else:
|
||||||
|
irc.reply(_('There are no aliases.'))
|
||||||
|
list = wrap(list, [getopts({'locked':'', 'unlocked':''})])
|
||||||
|
|
||||||
|
|
||||||
Class = Alias
|
Class = Alias
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ from supybot.test import *
|
|||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
import supybot.plugin as plugin
|
import supybot.plugin as plugin
|
||||||
import supybot.registry as registry
|
import supybot.registry as registry
|
||||||
|
from supybot.utils.minisix import u
|
||||||
|
|
||||||
from . import plugin as Alias
|
from . import plugin as Alias
|
||||||
|
|
||||||
@ -112,8 +113,7 @@ class AliasTestCase(ChannelPluginTestCase):
|
|||||||
self.failIf('foobar' in cb.aliases)
|
self.failIf('foobar' in cb.aliases)
|
||||||
self.assertError('foobar')
|
self.assertError('foobar')
|
||||||
|
|
||||||
self.assertRegexp('alias add café ignore', 'Error.*can only contain')
|
self.assertRegexp('alias add abc\x07 ignore', 'Error.*Invalid')
|
||||||
self.assertRegexp('alias add 1abc ignore', 'Error.*can only contain')
|
|
||||||
|
|
||||||
def testOptionalArgs(self):
|
def testOptionalArgs(self):
|
||||||
self.assertNotError('alias add myrepr "repr @1"')
|
self.assertNotError('alias add myrepr "repr @1"')
|
||||||
@ -128,6 +128,13 @@ class AliasTestCase(ChannelPluginTestCase):
|
|||||||
self.assertNotError('alias add myre "echo s/$1/$2/g"')
|
self.assertNotError('alias add myre "echo s/$1/$2/g"')
|
||||||
self.assertResponse('myre foo bar', 's/foo/bar/g')
|
self.assertResponse('myre foo bar', 's/foo/bar/g')
|
||||||
|
|
||||||
|
def testUnicode(self):
|
||||||
|
self.assertNotError(u('alias add \u200b echo foo'))
|
||||||
|
self.assertResponse(u('\u200b'), 'foo')
|
||||||
|
|
||||||
|
self.assertNotError('alias add café echo bar')
|
||||||
|
self.assertResponse('café', 'bar')
|
||||||
|
|
||||||
def testSimpleAliasWithoutArgsImpliesDollarStar(self):
|
def testSimpleAliasWithoutArgsImpliesDollarStar(self):
|
||||||
self.assertNotError('alias add exo echo')
|
self.assertNotError('alias add exo echo')
|
||||||
self.assertResponse('exo foo bar baz', 'foo bar baz')
|
self.assertResponse('exo foo bar baz', 'foo bar baz')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user