Merge pull request #974 from GLolol/topic-allow-separator

Topic: remove limitation forbidding the topic separator in topic.add
This commit is contained in:
Valentin Lorentz 2014-12-27 20:12:20 +01:00
commit cb441da644
2 changed files with 29 additions and 15 deletions

View File

@ -79,6 +79,11 @@ conf.registerChannelValue(Topic, 'requireManageCapability',
channel-level capabilities. channel-level capabilities.
Note that absence of an explicit anticapability means user has Note that absence of an explicit anticapability means user has
capability."""))) capability.""")))
conf.registerChannelValue(Topic, 'allowSeparatorinTopics',
registry.Boolean(True, _("""Determines whether the bot will allow
topics containing the defined separator to be used. You may want
to disable this if you are signing all topics by nick (see the 'format'
option for ways to adjust this).""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -48,6 +48,7 @@ _ = PluginInternationalization('Topic')
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
def canChangeTopic(irc, msg, args, state): def canChangeTopic(irc, msg, args, state):
assert not state.channel assert not state.channel
callConverter('channel', irc, msg, args, state) callConverter('channel', irc, msg, args, state)
@ -58,11 +59,13 @@ def canChangeTopic(irc, msg, args, state):
c = irc.state.channels[state.channel] c = irc.state.channels[state.channel]
if 't' in c.modes and not c.isHalfopPlus(irc.nick): if 't' in c.modes and not c.isHalfopPlus(irc.nick):
state.error(format(_('I can\'t change the topic, I\'m not (half)opped ' state.error(format(_('I can\'t change the topic, I\'m not (half)opped '
'and %s is +t.'), state.channel), Raise=True) 'and %s is +t.'), state.channel), Raise=True)
def getTopic(irc, msg, args, state, format=True): def getTopic(irc, msg, args, state, format=True):
separator = state.cb.registryValue('separator', state.channel) separator = state.cb.registryValue('separator', state.channel)
if separator in args[0]: if separator in args[0] and not \
state.cb.registryValue('allowSeparatorinTopics', state.channel):
state.errorInvalid('topic', args[0], state.errorInvalid('topic', args[0],
format(_('The topic must not include %q.'), format(_('The topic must not include %q.'),
separator)) separator))
@ -73,6 +76,7 @@ def getTopic(irc, msg, args, state, format=True):
topic = ircutils.standardSubstitute(irc, msg, formatter, env) topic = ircutils.standardSubstitute(irc, msg, formatter, env)
state.args.append(topic) state.args.append(topic)
def getTopicNumber(irc, msg, args, state): def getTopicNumber(irc, msg, args, state):
def error(s): def error(s):
state.errorInvalid(_('topic number'), s) state.errorInvalid(_('topic number'), s)
@ -103,15 +107,19 @@ addConverter('topic', getTopic)
addConverter('topicNumber', getTopicNumber) addConverter('topicNumber', getTopicNumber)
addConverter('canChangeTopic', canChangeTopic) addConverter('canChangeTopic', canChangeTopic)
def splitTopic(topic, separator): def splitTopic(topic, separator):
return list(filter(None, topic.split(separator))) return list(filter(None, topic.split(separator)))
datadir = conf.supybot.directories.data() datadir = conf.supybot.directories.data()
filename = conf.supybot.directories.data.dirize('Topic.pickle') filename = conf.supybot.directories.data.dirize('Topic.pickle')
class Topic(callbacks.Plugin): class Topic(callbacks.Plugin):
"""This plugin allows you to use many topic-related functions, """This plugin allows you to use many topic-related functions,
such as Add, Undo, and Remove.""" such as Add, Undo, and Remove."""
def __init__(self, irc): def __init__(self, irc):
self.__parent = super(Topic, self) self.__parent = super(Topic, self)
self.__parent.__init__(irc) self.__parent.__init__(irc)
@ -165,13 +173,13 @@ class Topic(callbacks.Plugin):
stack = self.undos.setdefault(channel, []) stack = self.undos.setdefault(channel, [])
stack.append(topics) stack.append(topics)
maxLen = self.registryValue('undo.max', channel) maxLen = self.registryValue('undo.max', channel)
del stack[:len(stack)-maxLen] del stack[:len(stack) - maxLen]
def _addRedo(self, channel, topics): def _addRedo(self, channel, topics):
stack = self.redos.setdefault(channel, []) stack = self.redos.setdefault(channel, [])
stack.append(topics) stack.append(topics)
maxLen = self.registryValue('undo.max', channel) maxLen = self.registryValue('undo.max', channel)
del stack[:len(stack)-maxLen] del stack[:len(stack) - maxLen]
def _getUndo(self, channel): def _getUndo(self, channel):
try: try:
@ -199,8 +207,8 @@ class Topic(callbacks.Plugin):
elif len(newTopic) > maxLen: elif len(newTopic) > maxLen:
if self.registryValue('recognizeTopiclen', channel): if self.registryValue('recognizeTopiclen', channel):
irc.error(format(_('That topic is too long for this ' irc.error(format(_('That topic is too long for this '
'server (maximum length: %i; this topic: ' 'server (maximum length: %i; this topic: '
'%i).'), maxLen, len(newTopic)), '%i).'), maxLen, len(newTopic)),
Raise=True) Raise=True)
except KeyError: except KeyError:
pass pass
@ -233,7 +241,8 @@ class Topic(callbacks.Plugin):
if capabilities: if capabilities:
for capability in re.split(r'\s*;\s*', capabilities): for capability in re.split(r'\s*;\s*', capabilities):
if capability.startswith('channel,'): if capability.startswith('channel,'):
capability = ircdb.makeChannelCapability(channel, capability[8:]) capability = ircdb.makeChannelCapability(
channel, capability[8:])
if capability and ircdb.checkCapability(msg.prefix, capability): if capability and ircdb.checkCapability(msg.prefix, capability):
return True return True
return False return False
@ -253,7 +262,7 @@ class Topic(callbacks.Plugin):
return return
if irc.nick not in c.ops and 't' in c.modes: if irc.nick not in c.ops and 't' in c.modes:
self.log.debug('Not trying to restore topic in %s. I\'m not opped ' self.log.debug('Not trying to restore topic in %s. I\'m not opped '
'and %s is +t.', channel, channel) 'and %s is +t.', channel, channel)
return return
try: try:
topics = self.lastTopics[channel] topics = self.lastTopics[channel]
@ -262,7 +271,7 @@ class Topic(callbacks.Plugin):
else: else:
newTopic = self._formatTopics(irc, channel, topics) newTopic = self._formatTopics(irc, channel, topics)
if c.topic == '' or (c.topic != newTopic and if c.topic == '' or (c.topic != newTopic and
self.registryValue('alwaysSetOnJoin', channel)): self.registryValue('alwaysSetOnJoin', channel)):
self._sendTopics(irc, channel, newTopic) self._sendTopics(irc, channel, newTopic)
def do332(self, irc, msg): def do332(self, irc, msg):
@ -403,7 +412,7 @@ class Topic(callbacks.Plugin):
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
L = [] L = []
for (i, t) in enumerate(topics): for (i, t) in enumerate(topics):
L.append(format(_('%i: %s'), i+1, utils.str.ellipsisify(t, 30))) L.append(format(_('%i: %s'), i + 1, utils.str.ellipsisify(t, 30)))
s = utils.str.commaAndify(L) s = utils.str.commaAndify(L)
irc.reply(s) irc.reply(s)
list = wrap(list, ['inChannel']) list = wrap(list, ['inChannel'])
@ -550,9 +559,9 @@ class Topic(callbacks.Plugin):
if not topics: if not topics:
raise KeyError raise KeyError
except KeyError: except KeyError:
irc.error(format(_('I haven\'t yet set the topic in %s.'), irc.error(format(_('I haven\'t yet set the topic in %s.'),
channel)) channel))
return return
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
refresh = wrap(refresh, ['canChangeTopic']) refresh = wrap(refresh, ['canChangeTopic'])
@ -567,8 +576,8 @@ class Topic(callbacks.Plugin):
if not self._checkManageCapabilities(irc, msg, channel): if not self._checkManageCapabilities(irc, msg, channel):
capabilities = self.registryValue('requireManageCapability') capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True) irc.errorNoCapability(capabilities, Raise=True)
self._addRedo(channel, self._getUndo(channel)) # current topic. self._addRedo(channel, self._getUndo(channel)) # current topic.
topics = self._getUndo(channel) # This is the topic list we want. topics = self._getUndo(channel) # This is the topic list we want.
if topics is not None: if topics is not None:
self._sendTopics(irc, channel, topics, isDo=True) self._sendTopics(irc, channel, topics, isDo=True)
else: else: