Alias: Save and restore aliases with dots in them.

This commit is contained in:
Valentin Lorentz 2012-08-06 20:36:10 +02:00
parent e3d170d9fe
commit 94d09da44a
4 changed files with 106 additions and 5 deletions

View File

@ -49,7 +49,7 @@ import plugin
reload(plugin) # In case we're being reloaded. reload(plugin) # In case we're being reloaded.
# Add more reloads here if you add third-party modules and want them to be # Add more reloads here if you add third-party modules and want them to be
# reloaded when this plugin is reloaded. Don't forget to import them as well! # reloaded when this plugin is reloaded. Don't forget to import them as well!
from plugin import findBiggestDollar, AliasError # for the tests. from plugin import findBiggestDollar, AliasError, escapeAlias, unescapeAlias # for the tests.
if world.testing: if world.testing:
import test import test

View File

@ -42,5 +42,6 @@ def configure(advanced):
Alias = conf.registerPlugin('Alias') Alias = conf.registerPlugin('Alias')
conf.registerGroup(Alias, 'aliases') conf.registerGroup(Alias, 'aliases')
conf.registerGroup(Alias, 'escapedaliases')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -103,6 +103,54 @@ def findBiggestAt(alias):
else: else:
return 0 return 0
def escapeAlias(alias):
"""Encodes [a-z0-9.]+ into [a-z][a-z0-9].
Format: a<number of escaped chars>a(<index>d)+<word without dots>."""
prefix = ''
new_alias = ''
prefixes = 0
for index, char in enumerate(alias):
if char == '.':
prefix += '%sd' % index
prefixes += 1
else:
new_alias += char
pre_prefix = 'a%ia' % prefixes
return pre_prefix + prefix + new_alias
def unescapeAlias(alias):
alias = alias[1:] # Strip the leading 'a'
escaped_nb = ''
while alias[0] in '0123456789':
escaped_nb += alias[0]
alias = alias[1:]
alias = alias[1:]
escaped_nb = int(escaped_nb)
escaped_chars = []
while alias[0] in '0123456789':
current_group = ''
while alias[0] in '0123456789':
current_group += alias[0]
alias = alias[1:]
if alias[0] == 'd':
char = '.'
else:
char = alias[0]
alias = alias[1:]
escaped_chars.append((int(current_group), char))
if len(escaped_chars) == escaped_nb:
break
new_alias = ''
index = 0
for char in alias:
if escaped_chars and index == escaped_chars[0][0]:
new_alias += escaped_chars[0][1]
escaped_chars.pop(0)
index += 1
new_alias += char
index += 1
return new_alias
def makeNewAlias(name, alias): def makeNewAlias(name, alias):
original = alias original = alias
biggestDollar = findBiggestDollar(original) biggestDollar = findBiggestDollar(original)
@ -175,6 +223,7 @@ class Alias(callbacks.Plugin):
self.aliases = {} self.aliases = {}
# 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
for (name, alias) in registry._cache.iteritems(): for (name, alias) in registry._cache.iteritems():
name = name.lower() name = name.lower()
if name.startswith('supybot.plugins.alias.aliases.'): if name.startswith('supybot.plugins.alias.aliases.'):
@ -184,11 +233,24 @@ class Alias(callbacks.Plugin):
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.'):
name = name[len('supybot.plugins.alias.escapedaliases.'):]
if '.' in name:
continue
conf.registerGlobalValue(group2, name,
registry.String('', ''))
conf.registerGlobalValue(group2.get(name),
'locked', registry.Boolean(False, ''))
for (name, value) in group.getValues(fullNames=False): for (name, value) in group.getValues(fullNames=False):
name = name.lower() # Just in case. name = name.lower() # Just in case.
command = value() command = value()
locked = value.locked() locked = value.locked()
self.aliases[name] = [command, locked, None] self.aliases[name] = [command, locked, None]
for (name, value) in group2.getValues(fullNames=False):
name = name.lower() # Just in case.
command = value()
locked = value.locked()
self.aliases[unescapeAlias(name)] = [command, locked, None]
for (alias, (command, locked, _)) in self.aliases.items(): for (alias, (command, locked, _)) in self.aliases.items():
try: try:
self.addAlias(irc, alias, command, locked) self.addAlias(irc, alias, command, locked)
@ -267,12 +329,18 @@ class Alias(callbacks.Plugin):
f = new.instancemethod(f, self, Alias) f = new.instancemethod(f, self, Alias)
except RecursiveAlias: except RecursiveAlias:
raise AliasError, 'You can\'t define a recursive alias.' raise AliasError, 'You can\'t define a recursive alias.'
if '.' in name:
aliasGroup = self.registryValue('escapedaliases', value=False)
confname = escapeAlias(name)
else:
aliasGroup = self.registryValue('aliases', value=False) 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(name) aliasGroup.unregister(confname)
conf.registerGlobalValue(aliasGroup, name, registry.String(alias, '')) conf.registerGlobalValue(aliasGroup, confname,
conf.registerGlobalValue(aliasGroup.get(name), 'locked', registry.String(alias, ''))
conf.registerGlobalValue(aliasGroup.get(confname), 'locked',
registry.Boolean(lock, '')) registry.Boolean(lock, ''))
self.aliases[name] = [alias, lock, f] self.aliases[name] = [alias, lock, f]

View File

@ -29,7 +29,9 @@
from supybot.test import * from supybot.test import *
import supybot.conf as conf
import supybot.plugin as plugin import supybot.plugin as plugin
import supybot.registry as registry
Alias = plugin.loadPluginModule('Alias') Alias = plugin.loadPluginModule('Alias')
@ -124,6 +126,36 @@ class AliasTestCase(ChannelPluginTestCase):
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')
class EscapedAliasTestCase(ChannelPluginTestCase):
plugins = ('Alias', 'Utilities')
def setUp(self):
registry._cache.update(
{'supybot.plugins.Alias.escapedaliases.a1a3dfoobar': 'echo baz',
'supybot.plugins.Alias.escapedaliases.a1a3dfoobar.locked': 'False'})
super(EscapedAliasTestCase, self).setUp()
def testReadDatabase(self):
self.assertResponse('foo.bar', 'baz')
def testAdd(self):
self.assertNotError('alias add spam.egg echo hi')
self.assertResponse('spam.egg', 'hi')
def testWriteDatabase(self):
self.assertNotError('alias add fooo.spam echo egg')
self.assertResponse('fooo.spam', 'egg')
self.failUnless(hasattr(conf.supybot.plugins.Alias.escapedaliases,
'a1a4dfooospam'))
self.assertEqual(conf.supybot.plugins.Alias.escapedaliases.a1a4dfooospam(),
'echo egg')
self.assertNotError('alias add foo.spam.egg echo supybot')
self.assertResponse('foo.spam.egg', 'supybot')
self.failUnless(hasattr(conf.supybot.plugins.Alias.escapedaliases,
'a2a3d8dfoospamegg'))
self.assertEqual(conf.supybot.plugins.Alias.escapedaliases.a2a3d8dfoospamegg(),
'echo supybot')
self.assertEqual(Alias.unescapeAlias('a2a3d8dfoospamegg'),
'foo.spam.egg')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: