From 94d09da44acbc90233ca4fb9cf12b62154dd3415 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Mon, 6 Aug 2012 20:36:10 +0200 Subject: [PATCH] Alias: Save and restore aliases with dots in them. --- plugins/Alias/__init__.py | 2 +- plugins/Alias/config.py | 1 + plugins/Alias/plugin.py | 76 ++++++++++++++++++++++++++++++++++++--- plugins/Alias/test.py | 32 +++++++++++++++++ 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/plugins/Alias/__init__.py b/plugins/Alias/__init__.py index 7c8a62ca9..92beaaaef 100644 --- a/plugins/Alias/__init__.py +++ b/plugins/Alias/__init__.py @@ -49,7 +49,7 @@ import plugin reload(plugin) # In case we're being reloaded. # 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! -from plugin import findBiggestDollar, AliasError # for the tests. +from plugin import findBiggestDollar, AliasError, escapeAlias, unescapeAlias # for the tests. if world.testing: import test diff --git a/plugins/Alias/config.py b/plugins/Alias/config.py index 4d37ed6a5..036ddcfdd 100644 --- a/plugins/Alias/config.py +++ b/plugins/Alias/config.py @@ -42,5 +42,6 @@ def configure(advanced): Alias = conf.registerPlugin('Alias') conf.registerGroup(Alias, 'aliases') +conf.registerGroup(Alias, 'escapedaliases') # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/Alias/plugin.py b/plugins/Alias/plugin.py index e4a6b310f..ee31aaeaf 100644 --- a/plugins/Alias/plugin.py +++ b/plugins/Alias/plugin.py @@ -103,6 +103,54 @@ def findBiggestAt(alias): else: return 0 +def escapeAlias(alias): + """Encodes [a-z0-9.]+ into [a-z][a-z0-9]. + Format: aa(d)+.""" + 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): original = alias biggestDollar = findBiggestDollar(original) @@ -175,6 +223,7 @@ class Alias(callbacks.Plugin): self.aliases = {} # XXX This should go. aliases should be a space separate list, etc. group = conf.supybot.plugins.Alias.aliases + group2 = conf.supybot.plugins.Alias.escapedaliases for (name, alias) in registry._cache.iteritems(): name = name.lower() if name.startswith('supybot.plugins.alias.aliases.'): @@ -184,11 +233,24 @@ class Alias(callbacks.Plugin): conf.registerGlobalValue(group, name, registry.String('', '')) conf.registerGlobalValue(group.get(name), 'locked', 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): name = name.lower() # Just in case. command = value() locked = value.locked() 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(): try: self.addAlias(irc, alias, command, locked) @@ -267,12 +329,18 @@ class Alias(callbacks.Plugin): f = new.instancemethod(f, self, Alias) except RecursiveAlias: raise AliasError, 'You can\'t define a recursive alias.' - aliasGroup = self.registryValue('aliases', value=False) + if '.' 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: # We gotta remove it so its value gets updated. - aliasGroup.unregister(name) - conf.registerGlobalValue(aliasGroup, name, registry.String(alias, '')) - conf.registerGlobalValue(aliasGroup.get(name), 'locked', + aliasGroup.unregister(confname) + conf.registerGlobalValue(aliasGroup, confname, + registry.String(alias, '')) + conf.registerGlobalValue(aliasGroup.get(confname), 'locked', registry.Boolean(lock, '')) self.aliases[name] = [alias, lock, f] diff --git a/plugins/Alias/test.py b/plugins/Alias/test.py index 57649dfa6..8d8327d11 100644 --- a/plugins/Alias/test.py +++ b/plugins/Alias/test.py @@ -29,7 +29,9 @@ from supybot.test import * +import supybot.conf as conf import supybot.plugin as plugin +import supybot.registry as registry Alias = plugin.loadPluginModule('Alias') @@ -124,6 +126,36 @@ class AliasTestCase(ChannelPluginTestCase): self.assertNotError('alias add exo echo') 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: