Config: Add commands 'reset channel' and 'reset network'.

They allow reseting a channel-specific or network-specific value
back to their parent value, and will follow it when it changes.
This commit is contained in:
Valentin Lorentz 2020-05-16 10:15:31 +02:00
parent 1b4205f1ac
commit 27f4386279
2 changed files with 216 additions and 10 deletions

View File

@ -105,6 +105,15 @@ def isReadOnly(name):
else: else:
return False return False
def checkCanSetValue(irc, msg, group):
if isReadOnly(group._name):
irc.error(_("This configuration variable is not writeable "
"via IRC. To change it you have to: 1) use the 'flush' command 2) edit "
"the config file 3) use the 'config reload' command."), Raise=True)
capability = getCapability(irc, group._name)
if not ircdb.checkCapability(msg.prefix, capability):
irc.errorNoCapability(capability, Raise=True)
def _reload(): def _reload():
ircdb.users.reload() ircdb.users.reload()
ircdb.ignores.reload() ircdb.ignores.reload()
@ -283,16 +292,9 @@ class Config(callbacks.Plugin):
'available in this group.'), Raise=True) 'available in this group.'), Raise=True)
def _setValue(self, irc, msg, group, value): def _setValue(self, irc, msg, group, value):
if isReadOnly(group._name): checkCanSetValue(irc, msg, group)
irc.error(_("This configuration variable is not writeable " # I think callCommand catches exceptions here. Should it?
"via IRC. To change it you have to: 1) use the 'flush' command 2) edit " group.set(value)
"the config file 3) use the 'config reload' command."), Raise=True)
capability = getCapability(irc, group._name)
if ircdb.checkCapability(msg.prefix, capability):
# I think callCommand catches exceptions here. Should it?
group.set(value)
else:
irc.errorNoCapability(capability, Raise=True)
@internationalizeDocstring @internationalizeDocstring
def channel(self, irc, msg, args, network, channels, group, value): def channel(self, irc, msg, args, network, channels, group, value):
@ -470,6 +472,52 @@ class Config(callbacks.Plugin):
irc.replySuccess() irc.replySuccess()
setdefault = wrap(setdefault, ['settableConfigVar']) setdefault = wrap(setdefault, ['settableConfigVar'])
class reset(callbacks.Commands):
@internationalizeDocstring
def channel(self, irc, msg, args, network, channel, group):
"""[<network>] [<channel>] <name>
Resets the channel-specific value of variable <name>, so that
it will match the network-specific value (or the global one
if the latter isn't set).
<network> and <channel> default to the current network and
channel.
"""
if network != '*':
# reset group.:network.#channel
netgroup = group.get(':' + network.network)
changroup = netgroup.get(channel)
checkCanSetValue(irc, msg, changroup)
changroup._setValue(netgroup.value, inherited=True)
# reset group.#channel
changroup = group.get(channel)
checkCanSetValue(irc, msg, changroup)
changroup._setValue(group.value, inherited=True)
irc.replySuccess()
channel = wrap(channel, [
optional(first(('literal', '*'), 'networkIrc')),
'channel', 'settableConfigVar'])
@internationalizeDocstring
def network(self, irc, msg, args, network, group):
"""[<network>] [<channel>] <name>
Resets the network-specific value of variable <name>, so that
it will match the global.
<network> defaults to the current network and
channel.
"""
# reset group.#channel
changroup = group.get(':' + network.network)
checkCanSetValue(irc, msg, changroup)
changroup._setValue(group.value, inherited=True)
irc.replySuccess()
network = wrap(network, ['networkIrc', 'settableConfigVar'])
Class = Config Class = Config
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -195,6 +195,13 @@ class ConfigTestCase(ChannelPluginTestCase):
'Global: 0; #test @ test: 1') 'Global: 0; #test @ test: 1')
def testChannel(self): def testChannel(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^', self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.') 'The operation succeeded.')
self.assertResponse('config channel reply.whenAddressedBy.strings @', self.assertResponse('config channel reply.whenAddressedBy.strings @',
@ -279,6 +286,157 @@ class ConfigTestCase(ChannelPluginTestCase):
# Inherit from #5, which set for #testchan1 on all nets # Inherit from #5, which set for #testchan1 on all nets
self.assertResponse('config channel testnet3 #testchan1 reply.whenAddressedBy.strings', ':') self.assertResponse('config channel testnet3 #testchan1 reply.whenAddressedBy.strings', ':')
def testChannelInheritance(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings @',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: @; #test @ test: @')
self.assertResponse('config channel reply.whenAddressedBy.strings', '@')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config channel reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: @; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child keeps its value
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
def testResetChannel(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config channel reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Reset child
self.assertResponse('config reset channel reply.whenAddressedBy.strings',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: .')
self.assertResponse('config channel reply.whenAddressedBy.strings', '.')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
def testResetNetwork(self):
try:
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config network reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config network reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: $')
self.assertResponse('config network reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Reset child
self.assertResponse('config reset network reply.whenAddressedBy.strings',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config network reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: .')
self.assertResponse('config network reply.whenAddressedBy.strings', '.')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: