mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 13:19:24 +01:00
Merge branch 'network-config' into netconf-and-ircmsgs-channel
This commit is contained in:
commit
81968d9970
@ -151,10 +151,10 @@ class Config(callbacks.Plugin):
|
|||||||
def _list(self, irc, group):
|
def _list(self, irc, group):
|
||||||
L = []
|
L = []
|
||||||
for (vname, v) in group._children.items():
|
for (vname, v) in group._children.items():
|
||||||
if hasattr(group, 'channelValue') and group.channelValue and \
|
if hasattr(group, '_channelValue') and group._channelValue and \
|
||||||
irc.isChannel(vname) and not v._children:
|
irc.isChannel(vname) and not v._children:
|
||||||
continue
|
continue
|
||||||
if hasattr(v, 'channelValue') and v.channelValue:
|
if hasattr(v, '_channelValue') and v._channelValue:
|
||||||
vname = '#' + vname
|
vname = '#' + vname
|
||||||
if v._added and not all(irc.isChannel, v._added):
|
if v._added and not all(irc.isChannel, v._added):
|
||||||
vname = '@' + vname
|
vname = '@' + vname
|
||||||
@ -198,11 +198,20 @@ class Config(callbacks.Plugin):
|
|||||||
irc.reply(_('There were no matching configuration variables.'))
|
irc.reply(_('There were no matching configuration variables.'))
|
||||||
search = wrap(search, ['lowered']) # XXX compose with withoutSpaces?
|
search = wrap(search, ['lowered']) # XXX compose with withoutSpaces?
|
||||||
|
|
||||||
def _getValue(self, irc, msg, group, addChannel=False):
|
def _getValue(self, irc, msg, group, network=None, channel=None, addGlobal=False):
|
||||||
|
global_value = str(group) or ' '
|
||||||
|
group = group.getSpecific(
|
||||||
|
network=network.network, channel=channel, check=None)
|
||||||
value = str(group) or ' '
|
value = str(group) or ' '
|
||||||
if addChannel and irc.isChannel(msg.args[0]) and not irc.nested:
|
if addGlobal and not irc.nested:
|
||||||
s = str(group.get(msg.args[0]))
|
value = _(
|
||||||
value = _('Global: %s; %s: %s') % (value, msg.args[0], s)
|
'Global: %(global_value)s; '
|
||||||
|
'%(channel_name)s @ %(network_name)s: %(channel_value)s') % {
|
||||||
|
'global_value': global_value,
|
||||||
|
'channel_name': msg.args[0],
|
||||||
|
'network_name': irc.network,
|
||||||
|
'channel_value': value,
|
||||||
|
}
|
||||||
if hasattr(group, 'value'):
|
if hasattr(group, 'value'):
|
||||||
if not group._private:
|
if not group._private:
|
||||||
return (value, None)
|
return (value, None)
|
||||||
@ -230,28 +239,44 @@ class Config(callbacks.Plugin):
|
|||||||
irc.errorNoCapability(capability, Raise=True)
|
irc.errorNoCapability(capability, Raise=True)
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def channel(self, irc, msg, args, channels, group, value):
|
def channel(self, irc, msg, args, network, channels, group, value):
|
||||||
"""[<channel>] <name> [<value>]
|
"""[<network>] [<channel>] <name> [<value>]
|
||||||
|
|
||||||
If <value> is given, sets the channel configuration variable for <name>
|
If <value> is given, sets the channel configuration variable for <name>
|
||||||
to <value> for <channel>. Otherwise, returns the current channel
|
to <value> for <channel> on the <network>.
|
||||||
|
Otherwise, returns the current channel
|
||||||
configuration value of <name>. <channel> is only necessary if the
|
configuration value of <name>. <channel> is only necessary if the
|
||||||
message isn't sent in the channel itself. More than one channel may
|
message isn't sent in the channel itself. More than one channel may
|
||||||
be given at once by separating them with commas."""
|
be given at once by separating them with commas.
|
||||||
if not group.channelValue:
|
<network> defaults to the current network."""
|
||||||
|
if not group._channelValue:
|
||||||
irc.error(_('That configuration variable is not a channel-specific '
|
irc.error(_('That configuration variable is not a channel-specific '
|
||||||
'configuration variable.'))
|
'configuration variable.'))
|
||||||
return
|
return
|
||||||
if value is not None:
|
if value is not None:
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
assert irc.isChannel(channel)
|
assert irc.isChannel(channel)
|
||||||
|
|
||||||
|
# Sets the non-network-specific value, for forward
|
||||||
|
# compatibility, ie. this will work even if the owner rolls
|
||||||
|
# back Limnoria to an older version.
|
||||||
|
# It's also an easy way to support plugins which are not
|
||||||
|
# network-aware.
|
||||||
self._setValue(irc, msg, group.get(channel), value)
|
self._setValue(irc, msg, group.get(channel), value)
|
||||||
|
|
||||||
|
if network != '*':
|
||||||
|
# Set the network-specific value
|
||||||
|
self._setValue(irc, msg, group.get(':' + network.network).get(channel), value)
|
||||||
|
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
else:
|
else:
|
||||||
|
if network == '*':
|
||||||
|
network = None
|
||||||
values = []
|
values = []
|
||||||
private = None
|
private = None
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
(value, private_value) = self._getValue(irc, msg, group.get(channel))
|
(value, private_value) = \
|
||||||
|
self._getValue(irc, msg, group, network, channel)
|
||||||
values.append((channel, value))
|
values.append((channel, value))
|
||||||
if private_value:
|
if private_value:
|
||||||
private = True
|
private = True
|
||||||
@ -261,7 +286,8 @@ class Config(callbacks.Plugin):
|
|||||||
for (channel, value) in values]))
|
for (channel, value) in values]))
|
||||||
else:
|
else:
|
||||||
irc.reply(values[0][1])
|
irc.reply(values[0][1])
|
||||||
channel = wrap(channel, ['channels', 'settableConfigVar',
|
channel = wrap(channel, [optional(first(('literal', '*'), 'networkIrc')),
|
||||||
|
'channels', 'settableConfigVar',
|
||||||
additional('text')])
|
additional('text')])
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
@ -276,7 +302,10 @@ class Config(callbacks.Plugin):
|
|||||||
self._setValue(irc, msg, group, value)
|
self._setValue(irc, msg, group, value)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
else:
|
else:
|
||||||
(value, private) = self._getValue(irc, msg, group, addChannel=group.channelValue)
|
(value, private) = self._getValue(
|
||||||
|
irc, msg, group, network=irc,
|
||||||
|
channel=msg.args[0] if irc.isChannel(msg.args[0]) else None,
|
||||||
|
addGlobal=group._channelValue)
|
||||||
irc.reply(value, private=private)
|
irc.reply(value, private=private)
|
||||||
config = wrap(config, ['settableConfigVar', additional('text')])
|
config = wrap(config, ['settableConfigVar', additional('text')])
|
||||||
|
|
||||||
|
@ -133,13 +133,13 @@ class ConfigTestCase(ChannelPluginTestCase):
|
|||||||
'^Completely: Error: ',
|
'^Completely: Error: ',
|
||||||
frm=self.prefix3)
|
frm=self.prefix3)
|
||||||
self.assertResponse('config plugins.Config.%s' % var_name,
|
self.assertResponse('config plugins.Config.%s' % var_name,
|
||||||
'Global: 0; #test: 0')
|
'Global: 0; #test @ test: 0')
|
||||||
|
|
||||||
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
|
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
|
||||||
'^Completely: Error: ',
|
'^Completely: Error: ',
|
||||||
frm=self.prefix3)
|
frm=self.prefix3)
|
||||||
self.assertResponse('config plugins.Config.%s' % var_name,
|
self.assertResponse('config plugins.Config.%s' % var_name,
|
||||||
'Global: 0; #test: 1')
|
'Global: 0; #test @ test: 1')
|
||||||
|
|
||||||
def testOpNonEditable(self):
|
def testOpNonEditable(self):
|
||||||
var_name = 'testOpNonEditable' + random_string()
|
var_name = 'testOpNonEditable' + random_string()
|
||||||
@ -154,18 +154,18 @@ class ConfigTestCase(ChannelPluginTestCase):
|
|||||||
'^Completely: Error: ',
|
'^Completely: Error: ',
|
||||||
frm=self.prefix3)
|
frm=self.prefix3)
|
||||||
self.assertResponse('config plugins.Config.%s' % var_name,
|
self.assertResponse('config plugins.Config.%s' % var_name,
|
||||||
'Global: 0; #test: 0')
|
'Global: 0; #test @ test: 0')
|
||||||
|
|
||||||
self.assertRegexp('config channel plugins.Config.%s 1' % var_name,
|
self.assertRegexp('config channel plugins.Config.%s 1' % var_name,
|
||||||
'^Completely: Error: ',
|
'^Completely: Error: ',
|
||||||
frm=self.prefix3)
|
frm=self.prefix3)
|
||||||
self.assertResponse('config plugins.Config.%s' % var_name,
|
self.assertResponse('config plugins.Config.%s' % var_name,
|
||||||
'Global: 0; #test: 0')
|
'Global: 0; #test @ test: 0')
|
||||||
|
|
||||||
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
|
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
|
||||||
'^Completely: Error: ')
|
'^Completely: Error: ')
|
||||||
self.assertResponse('config plugins.Config.%s' % var_name,
|
self.assertResponse('config plugins.Config.%s' % var_name,
|
||||||
'Global: 0; #test: 1')
|
'Global: 0; #test @ test: 1')
|
||||||
|
|
||||||
def testChannel(self):
|
def testChannel(self):
|
||||||
self.assertResponse('config reply.whenAddressedBy.strings ^',
|
self.assertResponse('config reply.whenAddressedBy.strings ^',
|
||||||
@ -181,6 +181,54 @@ class ConfigTestCase(ChannelPluginTestCase):
|
|||||||
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '.')
|
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '.')
|
||||||
self.assertResponse('config channel #testchan2 reply.whenAddressedBy.strings', '.')
|
self.assertResponse('config channel #testchan2 reply.whenAddressedBy.strings', '.')
|
||||||
|
|
||||||
|
def testChannelNetwork(self):
|
||||||
|
irc = self.irc
|
||||||
|
irc1 = getTestIrc('testnet1')
|
||||||
|
irc2 = getTestIrc('testnet2')
|
||||||
|
irc3 = getTestIrc('testnet3')
|
||||||
|
conf.supybot.reply.whenAddressedBy.strings.get('#test')._wasSet = False
|
||||||
|
# 1. Set global
|
||||||
|
self.assertResponse('config reply.whenAddressedBy.strings ^',
|
||||||
|
'The operation succeeded.')
|
||||||
|
|
||||||
|
# 2. Set for current net + #testchan1
|
||||||
|
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings @',
|
||||||
|
'The operation succeeded.')
|
||||||
|
|
||||||
|
# Exact match for #2:
|
||||||
|
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
|
||||||
|
|
||||||
|
# 3: Set for #testchan1 for all nets:
|
||||||
|
self.assertNotError('config channel * #testchan1 reply.whenAddressedBy.strings $')
|
||||||
|
|
||||||
|
# Still exact match for #2:
|
||||||
|
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
|
||||||
|
|
||||||
|
# Inherit from *:
|
||||||
|
self.assertResponse('config channel testnet1 #testchan1 reply.whenAddressedBy.strings', '$')
|
||||||
|
self.assertResponse('config channel testnet2 #testchan1 reply.whenAddressedBy.strings', '$')
|
||||||
|
|
||||||
|
# 4: Set for testnet1 for #testchan1 and #testchan2:
|
||||||
|
self.assertNotError('config channel testnet1 #testchan1,#testchan2 reply.whenAddressedBy.strings .')
|
||||||
|
|
||||||
|
# 5: Set for testnet2 for #testchan1:
|
||||||
|
self.assertNotError('config channel testnet2 #testchan1 reply.whenAddressedBy.strings :')
|
||||||
|
|
||||||
|
# Inherit from global value (nothing was set of current net or current
|
||||||
|
# chan):
|
||||||
|
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
|
||||||
|
|
||||||
|
# Still exact match for #2:
|
||||||
|
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
|
||||||
|
self.assertResponse('config channel %s #testchan1 reply.whenAddressedBy.strings' % irc.network, '@')
|
||||||
|
|
||||||
|
# Exact match for #4:
|
||||||
|
self.assertResponse('config channel testnet1 #testchan1 reply.whenAddressedBy.strings', '.')
|
||||||
|
self.assertResponse('config channel testnet1 #testchan2 reply.whenAddressedBy.strings', '.')
|
||||||
|
|
||||||
|
# Inherit from #5, which set for #testchan1 on all nets
|
||||||
|
self.assertResponse('config channel testnet3 #testchan1 reply.whenAddressedBy.strings', ':')
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ supybot.log.plugins.individualLogfiles: False
|
|||||||
supybot.protocols.irc.throttleTime: 0
|
supybot.protocols.irc.throttleTime: 0
|
||||||
supybot.reply.whenAddressedBy.chars: @
|
supybot.reply.whenAddressedBy.chars: @
|
||||||
supybot.networks.test.server: should.not.need.this
|
supybot.networks.test.server: should.not.need.this
|
||||||
|
supybot.networks.testnet1.server: should.not.need.this
|
||||||
|
supybot.networks.testnet2.server: should.not.need.this
|
||||||
|
supybot.networks.testnet3.server: should.not.need.this
|
||||||
supybot.nick: test
|
supybot.nick: test
|
||||||
supybot.databases.users.allowUnregistration: True
|
supybot.databases.users.allowUnregistration: True
|
||||||
""" % {'base_dir': os.getcwd()})
|
""" % {'base_dir': os.getcwd()})
|
||||||
|
@ -1391,33 +1391,33 @@ class PluginMixin(BasePlugin, irclib.IrcCallback):
|
|||||||
else:
|
else:
|
||||||
self.__parent.__call__(irc, msg)
|
self.__parent.__call__(irc, msg)
|
||||||
|
|
||||||
def registryValue(self, name, channel=None, value=True):
|
def registryValue(self, name, channel=None, network=None, value=True):
|
||||||
|
if isinstance(network, bool):
|
||||||
|
# Network-unaware plugin that uses 'value' as a positional
|
||||||
|
# argument.
|
||||||
|
(network, value) = (value, network)
|
||||||
plugin = self.name()
|
plugin = self.name()
|
||||||
group = conf.supybot.plugins.get(plugin)
|
group = conf.supybot.plugins.get(plugin)
|
||||||
names = registry.split(name)
|
names = registry.split(name)
|
||||||
for name in names:
|
for name in names:
|
||||||
group = group.get(name)
|
group = group.get(name)
|
||||||
if channel is not None:
|
|
||||||
if ircutils.isChannel(channel):
|
|
||||||
group = group.get(channel)
|
|
||||||
else:
|
|
||||||
self.log.debug('%s: registryValue got channel=%r', plugin,
|
|
||||||
channel)
|
|
||||||
if value:
|
if value:
|
||||||
|
group = group.getSpecific(network=network, channel=channel)
|
||||||
return group()
|
return group()
|
||||||
else:
|
else:
|
||||||
return group
|
return group
|
||||||
|
|
||||||
def setRegistryValue(self, name, value, channel=None):
|
def setRegistryValue(self, name, value, channel=None, network=None):
|
||||||
plugin = self.name()
|
plugin = self.name()
|
||||||
group = conf.supybot.plugins.get(plugin)
|
group = conf.supybot.plugins.get(plugin)
|
||||||
names = registry.split(name)
|
names = registry.split(name)
|
||||||
for name in names:
|
for name in names:
|
||||||
group = group.get(name)
|
group = group.get(name)
|
||||||
if channel is None:
|
if network:
|
||||||
group.setValue(value)
|
group = group.get(':' + network)
|
||||||
else:
|
if channel:
|
||||||
group.get(channel).setValue(value)
|
group = group.get(channel)
|
||||||
|
group.setValue(value)
|
||||||
|
|
||||||
def userValue(self, name, prefixOrName, default=None):
|
def userValue(self, name, prefixOrName, default=None):
|
||||||
try:
|
try:
|
||||||
|
15
src/conf.py
15
src/conf.py
@ -83,12 +83,14 @@ def registerGroup(Group, name, group=None, **kwargs):
|
|||||||
return Group.register(name, group)
|
return Group.register(name, group)
|
||||||
|
|
||||||
def registerGlobalValue(group, name, value):
|
def registerGlobalValue(group, name, value):
|
||||||
value.channelValue = False
|
value._networkValue = False
|
||||||
|
value._channelValue = False
|
||||||
return group.register(name, value)
|
return group.register(name, value)
|
||||||
|
|
||||||
def registerChannelValue(group, name, value, opSettable=True):
|
def registerChannelValue(group, name, value, opSettable=True):
|
||||||
value._supplyDefault = True
|
value._supplyDefault = True
|
||||||
value.channelValue = True
|
value._networkValue = True
|
||||||
|
value._channelValue = True
|
||||||
value._opSettable = opSettable
|
value._opSettable = opSettable
|
||||||
g = group.register(name, value)
|
g = group.register(name, value)
|
||||||
gname = g._name.lower()
|
gname = g._name.lower()
|
||||||
@ -96,8 +98,13 @@ def registerChannelValue(group, name, value, opSettable=True):
|
|||||||
if name.lower().startswith(gname) and len(gname) < len(name):
|
if name.lower().startswith(gname) and len(gname) < len(name):
|
||||||
name = name[len(gname)+1:] # +1 for .
|
name = name[len(gname)+1:] # +1 for .
|
||||||
parts = registry.split(name)
|
parts = registry.split(name)
|
||||||
if len(parts) == 1 and parts[0] and ircutils.isChannel(parts[0]):
|
if len(parts) == 2 and parts[0] and parts[0].startswith(':') \
|
||||||
# This gets the channel values so they always persist.
|
and parts[1] and ircutils.isChannel(parts[1]):
|
||||||
|
# This gets the network+channel values so they always persist.
|
||||||
|
g.get(parts[0])()
|
||||||
|
g.get(parts[0]).get(parts[1])()
|
||||||
|
elif len(parts) == 1 and parts[0] and ircutils.isChannel(parts[0]):
|
||||||
|
# Old-style variant of the above, without a network
|
||||||
g.get(parts[0])()
|
g.get(parts[0])()
|
||||||
|
|
||||||
def registerPlugin(name, currentValue=None, public=True):
|
def registerPlugin(name, currentValue=None, public=True):
|
||||||
|
@ -212,7 +212,7 @@ class Group(object):
|
|||||||
s = '%r is not a valid entry in %r' % (attr, self._name)
|
s = '%r is not a valid entry in %r' % (attr, self._name)
|
||||||
raise NonExistentRegistryEntry(s)
|
raise NonExistentRegistryEntry(s)
|
||||||
|
|
||||||
def __makeChild(self, attr, s):
|
def _makeChild(self, attr, s):
|
||||||
v = self.__class__(self._default, self._help)
|
v = self.__class__(self._default, self._help)
|
||||||
v.set(s)
|
v.set(s)
|
||||||
v._wasSet = False
|
v._wasSet = False
|
||||||
@ -225,10 +225,12 @@ class Group(object):
|
|||||||
return attr in self._children
|
return attr in self._children
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr in self._children:
|
if attr.startswith('_'):
|
||||||
|
object.__getattr__(self, attr)
|
||||||
|
elif attr in self._children:
|
||||||
return self._children[attr]
|
return self._children[attr]
|
||||||
elif self._supplyDefault:
|
elif self._supplyDefault:
|
||||||
return self.__makeChild(attr, str(self))
|
return self._makeChild(attr, str(self))
|
||||||
else:
|
else:
|
||||||
self.__nonExistentEntry(attr)
|
self.__nonExistentEntry(attr)
|
||||||
|
|
||||||
@ -253,7 +255,7 @@ class Group(object):
|
|||||||
parts = split(rest)
|
parts = split(rest)
|
||||||
if len(parts) == 1 and parts[0] == name:
|
if len(parts) == 1 and parts[0] == name:
|
||||||
try:
|
try:
|
||||||
self.__makeChild(name, v)
|
self._makeChild(name, v)
|
||||||
except InvalidRegistryValue:
|
except InvalidRegistryValue:
|
||||||
# It's probably supposed to be registered later.
|
# It's probably supposed to be registered later.
|
||||||
pass
|
pass
|
||||||
@ -328,7 +330,7 @@ class Value(Group):
|
|||||||
"""Invalid registry value. If you're getting this message, report it,
|
"""Invalid registry value. If you're getting this message, report it,
|
||||||
because we forgot to put a proper help string here."""
|
because we forgot to put a proper help string here."""
|
||||||
__slots__ = ('__parent', '_default', '_showDefault', '_help', '_callbacks',
|
__slots__ = ('__parent', '_default', '_showDefault', '_help', '_callbacks',
|
||||||
'value', 'channelValue', '_opSettable')
|
'value', '_networkValue', '_channelValue', '_opSettable')
|
||||||
def __init__(self, default, help, setDefault=True,
|
def __init__(self, default, help, setDefault=True,
|
||||||
showDefault=True, **kwargs):
|
showDefault=True, **kwargs):
|
||||||
self.__parent = super(Value, self)
|
self.__parent = super(Value, self)
|
||||||
@ -340,6 +342,24 @@ class Value(Group):
|
|||||||
if setDefault:
|
if setDefault:
|
||||||
self.setValue(default)
|
self.setValue(default)
|
||||||
|
|
||||||
|
def _makeChild(self, attr, s):
|
||||||
|
v = self.__class__(self._default, self._help)
|
||||||
|
v.set(s)
|
||||||
|
v._wasSet = False
|
||||||
|
if self._networkValue and self._channelValue:
|
||||||
|
# If this is both a network-specific and channel-specific value,
|
||||||
|
# then the child is (only) channel-specific.
|
||||||
|
v._networkValue = False
|
||||||
|
v._channelValue = True
|
||||||
|
v._supplyDefault = True
|
||||||
|
else:
|
||||||
|
# Otherwise, the child is neither network-specific or
|
||||||
|
# channel-specific.
|
||||||
|
v._supplyDefault = False
|
||||||
|
v._help = '' # Clear this so it doesn't print a bazillion times.
|
||||||
|
self.register(attr, v)
|
||||||
|
return v
|
||||||
|
|
||||||
def error(self, value=_NoValueGiven):
|
def error(self, value=_NoValueGiven):
|
||||||
if hasattr(self, 'errormsg') and value is not _NoValueGiven:
|
if hasattr(self, 'errormsg') and value is not _NoValueGiven:
|
||||||
try:
|
try:
|
||||||
@ -356,6 +376,58 @@ class Value(Group):
|
|||||||
e.value = self
|
e.value = self
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def getSpecific(self, network=None, channel=None, check=True):
|
||||||
|
"""Gets the network-specific and/or channel-specific value of this
|
||||||
|
Value.
|
||||||
|
If `check=True` (the default), this will raise an error if `network`
|
||||||
|
(resp. `channel`) is provided but this Value is not network-specific
|
||||||
|
(resp. channel-specific). If `check=False`, then `network` and/or
|
||||||
|
`channel` may be silently ignored.
|
||||||
|
"""
|
||||||
|
if network and not self._networkValue:
|
||||||
|
if check:
|
||||||
|
raise NonExistentRegistryEntry('%s is not network-specific' %
|
||||||
|
self._name)
|
||||||
|
else:
|
||||||
|
network = None
|
||||||
|
if channel and not self._channelValue:
|
||||||
|
if check:
|
||||||
|
raise NonExistentRegistryEntry('%s is not channel-specific' %
|
||||||
|
self._name)
|
||||||
|
else:
|
||||||
|
channel = None
|
||||||
|
if network and channel:
|
||||||
|
# The complicated case. We want a net+chan specific value,
|
||||||
|
# which may come in three different ways:
|
||||||
|
#
|
||||||
|
# 1. it was set explicitely net+chan
|
||||||
|
# 2. it's inherited from a net specific value (which may itself be
|
||||||
|
# inherited from the base value)
|
||||||
|
# 3. it's inherited from the chan specific value (which is not a
|
||||||
|
# actually a parent in the registry tree, but we need this to
|
||||||
|
# load configuration from old bots).
|
||||||
|
#
|
||||||
|
# The choice between 2 and 3 is done by checking which of the
|
||||||
|
# net-specific and chan-specific values was set explicitely by
|
||||||
|
# a user/admin. In case both were, the net-specific value is used
|
||||||
|
# (there is no particular reason for this, I just think it makes
|
||||||
|
# more sense).
|
||||||
|
network_value = self.get(':' + network)
|
||||||
|
network_channel_value = network_value.get(channel)
|
||||||
|
channel_value = self.get(channel)
|
||||||
|
if network_value._wasSet or network_channel_value._wasSet:
|
||||||
|
# cases 1 and 2
|
||||||
|
return network_channel_value
|
||||||
|
else:
|
||||||
|
# case 3
|
||||||
|
return channel_value
|
||||||
|
elif network:
|
||||||
|
return self.get(':' + network)
|
||||||
|
elif channel:
|
||||||
|
return self.get(channel)
|
||||||
|
else:
|
||||||
|
return self
|
||||||
|
|
||||||
def setName(self, *args):
|
def setName(self, *args):
|
||||||
if self._name == 'unset':
|
if self._name == 'unset':
|
||||||
self._lastModified = 0
|
self._lastModified = 0
|
||||||
|
@ -96,8 +96,8 @@ def retry(tries=3):
|
|||||||
return newf
|
return newf
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def getTestIrc():
|
def getTestIrc(name='test'):
|
||||||
irc = irclib.Irc('test')
|
irc = irclib.Irc(name)
|
||||||
# Gotta clear the connect messages (USER, NICK, etc.)
|
# Gotta clear the connect messages (USER, NICK, etc.)
|
||||||
while irc.takeMsg():
|
while irc.takeMsg():
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user