Topic: Factorize capability checks + make requireManageCapability actually channel-specific.

This commit is contained in:
Valentin Lorentz 2015-07-08 11:35:48 +02:00
parent 1bdb9e38e3
commit 7d7945e719
1 changed files with 25 additions and 83 deletions

View File

@ -43,7 +43,7 @@ import supybot.ircmsgs as ircmsgs
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring from supybot.i18n import PluginInternationalization
_ = PluginInternationalization('Topic') _ = PluginInternationalization('Topic')
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
@ -244,10 +244,12 @@ class Topic(callbacks.Plugin):
capability = ircdb.makeChannelCapability( capability = ircdb.makeChannelCapability(
channel, capability[8:]) channel, capability[8:])
if capability and ircdb.checkCapability(msg.prefix, capability): if capability and ircdb.checkCapability(msg.prefix, capability):
return True return
return False capabilities = self.registryValue('requireManageCapability',
channel)
irc.errorNoCapability(capabilities, Raise=True)
else: else:
return True return
def doJoin(self, irc, msg): def doJoin(self, irc, msg):
if ircutils.strEqual(msg.nick, irc.nick): if ircutils.strEqual(msg.nick, irc.nick):
@ -281,7 +283,6 @@ class Topic(callbacks.Plugin):
# us to undo the first topic change that takes place in a channel. # us to undo the first topic change that takes place in a channel.
self._addUndo(msg.args[1], [msg.args[2]]) self._addUndo(msg.args[1], [msg.args[2]])
@internationalizeDocstring
def topic(self, irc, msg, args, channel): def topic(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -292,22 +293,18 @@ class Topic(callbacks.Plugin):
irc.reply(topic) irc.reply(topic)
topic = wrap(topic, ['inChannel']) topic = wrap(topic, ['inChannel'])
@internationalizeDocstring
def add(self, irc, msg, args, channel, topic): def add(self, irc, msg, args, channel, topic):
"""[<channel>] <topic> """[<channel>] <topic>
Adds <topic> to the topics for <channel>. <channel> is only necessary Adds <topic> to the topics for <channel>. <channel> is only necessary
if the message isn't sent in the channel itself. if the message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics.append(topic) topics.append(topic)
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
add = wrap(add, ['canChangeTopic', rest('topic')]) add = wrap(add, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def fit(self, irc, msg, args, channel, topic): def fit(self, irc, msg, args, channel, topic):
"""[<channel>] <topic> """[<channel>] <topic>
@ -316,29 +313,23 @@ class Topic(callbacks.Plugin):
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics.append(topic) topics.append(topic)
self._sendTopics(irc, channel, topics, fit=True) self._sendTopics(irc, channel, topics, fit=True)
fit = wrap(fit, ['canChangeTopic', rest('topic')]) fit = wrap(fit, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def replace(self, irc, msg, args, channel, i, topic): def replace(self, irc, msg, args, channel, i, topic):
"""[<channel>] <number> <topic> """[<channel>] <number> <topic>
Replaces topic <number> with <topic>. Replaces topic <number> with <topic>.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics[i] = topic topics[i] = topic
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
replace = wrap(replace, ['canChangeTopic', 'topicNumber', rest('topic')]) replace = wrap(replace, ['canChangeTopic', 'topicNumber', rest('topic')])
@internationalizeDocstring
def insert(self, irc, msg, args, channel, topic): def insert(self, irc, msg, args, channel, topic):
"""[<channel>] <topic> """[<channel>] <topic>
@ -346,24 +337,19 @@ class Topic(callbacks.Plugin):
currently on <channel>. <channel> is only necessary if the message currently on <channel>. <channel> is only necessary if the message
isn't sent in the channel itself. isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics.insert(0, topic) topics.insert(0, topic)
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
insert = wrap(insert, ['canChangeTopic', rest('topic')]) insert = wrap(insert, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def shuffle(self, irc, msg, args, channel): def shuffle(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Shuffles the topics in <channel>. <channel> is only necessary if the Shuffles the topics in <channel>. <channel> is only necessary if the
message isn't sent in the channel itself. message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
if len(topics) == 0 or len(topics) == 1: if len(topics) == 0 or len(topics) == 1:
irc.error(_('I can\'t shuffle 1 or fewer topics.'), Raise=True) irc.error(_('I can\'t shuffle 1 or fewer topics.'), Raise=True)
@ -376,7 +362,6 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
shuffle = wrap(shuffle, ['canChangeTopic']) shuffle = wrap(shuffle, ['canChangeTopic'])
@internationalizeDocstring
def reorder(self, irc, msg, args, channel, numbers): def reorder(self, irc, msg, args, channel, numbers):
"""[<channel>] <number> [<number> ...] """[<channel>] <number> [<number> ...]
@ -385,9 +370,7 @@ class Topic(callbacks.Plugin):
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
num = len(topics) num = len(topics)
if num == 0 or num == 1: if num == 0 or num == 1:
@ -401,7 +384,6 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, newtopics) self._sendTopics(irc, channel, newtopics)
reorder = wrap(reorder, ['canChangeTopic', many('topicNumber')]) reorder = wrap(reorder, ['canChangeTopic', many('topicNumber')])
@internationalizeDocstring
def list(self, irc, msg, args, channel): def list(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -417,7 +399,6 @@ class Topic(callbacks.Plugin):
irc.reply(s) irc.reply(s)
list = wrap(list, ['inChannel']) list = wrap(list, ['inChannel'])
@internationalizeDocstring
def get(self, irc, msg, args, channel, number): def get(self, irc, msg, args, channel, number):
"""[<channel>] <number> """[<channel>] <number>
@ -429,7 +410,6 @@ class Topic(callbacks.Plugin):
irc.reply(topics[number]) irc.reply(topics[number])
get = wrap(get, ['inChannel', 'topicNumber']) get = wrap(get, ['inChannel', 'topicNumber'])
@internationalizeDocstring
def change(self, irc, msg, args, channel, number, replacer): def change(self, irc, msg, args, channel, number, replacer):
"""[<channel>] <number> <regexp> """[<channel>] <number> <regexp>
@ -439,15 +419,12 @@ class Topic(callbacks.Plugin):
s/regexp/replacement/flags. <channel> is only necessary if the message s/regexp/replacement/flags. <channel> is only necessary if the message
isn't sent in the channel itself. isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics[number] = replacer(topics[number]) topics[number] = replacer(topics[number])
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
change = wrap(change, ['canChangeTopic', 'topicNumber', 'regexpReplacer']) change = wrap(change, ['canChangeTopic', 'topicNumber', 'regexpReplacer'])
@internationalizeDocstring
def set(self, irc, msg, args, channel, number, topic): def set(self, irc, msg, args, channel, number, topic):
"""[<channel>] [<number>] <topic> """[<channel>] [<number>] <topic>
@ -455,9 +432,7 @@ class Topic(callbacks.Plugin):
sets the entire topic. <channel> is only necessary if the message sets the entire topic. <channel> is only necessary if the message
isn't sent in the channel itself. isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
if number is not None: if number is not None:
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
topics[number] = topic topics[number] = topic
@ -468,7 +443,6 @@ class Topic(callbacks.Plugin):
optional('topicNumber'), optional('topicNumber'),
rest(('topic', False))]) rest(('topic', False))])
@internationalizeDocstring
def remove(self, irc, msg, args, channel, numbers): def remove(self, irc, msg, args, channel, numbers):
"""[<channel>] <number1> [<number2> <number3>...] """[<channel>] <number1> [<number2> <number3>...]
@ -477,9 +451,7 @@ class Topic(callbacks.Plugin):
to topics starting the from the end of the topic. <channel> is only to topics starting the from the end of the topic. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
numbers = set(numbers) numbers = set(numbers)
for n in numbers: for n in numbers:
@ -491,44 +463,35 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
remove = wrap(remove, ['canChangeTopic', many('topicNumber')]) remove = wrap(remove, ['canChangeTopic', many('topicNumber')])
@internationalizeDocstring
def lock(self, irc, msg, args, channel): def lock(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Locks the topic (sets the mode +t) in <channel>. <channel> is only Locks the topic (sets the mode +t) in <channel>. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
irc.queueMsg(ircmsgs.mode(channel, '+t')) irc.queueMsg(ircmsgs.mode(channel, '+t'))
irc.noReply() irc.noReply()
lock = wrap(lock, ['channel', ('haveHalfop+', _('lock the topic'))]) lock = wrap(lock, ['channel', ('haveHalfop+', _('lock the topic'))])
@internationalizeDocstring
def unlock(self, irc, msg, args, channel): def unlock(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Unlocks the topic (sets the mode -t) in <channel>. <channel> is only Unlocks the topic (sets the mode -t) in <channel>. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
irc.queueMsg(ircmsgs.mode(channel, '-t')) irc.queueMsg(ircmsgs.mode(channel, '-t'))
irc.noReply() irc.noReply()
unlock = wrap(unlock, ['channel', ('haveHalfop+', _('unlock the topic'))]) unlock = wrap(unlock, ['channel', ('haveHalfop+', _('unlock the topic'))])
@internationalizeDocstring
def restore(self, irc, msg, args, channel): def restore(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Restores the topic to the last topic set by the bot. <channel> is only Restores the topic to the last topic set by the bot. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
try: try:
topics = self.lastTopics[channel] topics = self.lastTopics[channel]
if not topics: if not topics:
@ -540,16 +503,13 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
restore = wrap(restore, ['canChangeTopic']) restore = wrap(restore, ['canChangeTopic'])
@internationalizeDocstring
def refresh(self, irc, msg, args, channel): def refresh(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Refreshes current topic set by anyone. Restores topic if empty. Refreshes current topic set by anyone. Restores topic if empty.
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topic = irc.state.channels[channel].topic topic = irc.state.channels[channel].topic
if topic: if topic:
self._sendTopics(irc, channel, topic) self._sendTopics(irc, channel, topic)
@ -565,7 +525,6 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
refresh = wrap(refresh, ['canChangeTopic']) refresh = wrap(refresh, ['canChangeTopic'])
@internationalizeDocstring
def undo(self, irc, msg, args, channel): def undo(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -573,9 +532,7 @@ class Topic(callbacks.Plugin):
set it. <channel> is only necessary if the message isn't sent in the set it. <channel> is only necessary if the message isn't sent in the
channel itself. channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
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:
@ -584,16 +541,13 @@ class Topic(callbacks.Plugin):
irc.error(format(_('There are no more undos for %s.'), channel)) irc.error(format(_('There are no more undos for %s.'), channel))
undo = wrap(undo, ['canChangetopic']) undo = wrap(undo, ['canChangetopic'])
@internationalizeDocstring
def redo(self, irc, msg, args, channel): def redo(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Undoes the last undo. <channel> is only necessary if the message isn't Undoes the last undo. <channel> is only necessary if the message isn't
sent in the channel itself. sent in the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._getRedo(channel) topics = self._getRedo(channel)
if topics is not None: if topics is not None:
self._sendTopics(irc, channel, topics, isDo=True) self._sendTopics(irc, channel, topics, isDo=True)
@ -601,7 +555,6 @@ class Topic(callbacks.Plugin):
irc.error(format(_('There are no redos for %s.'), channel)) irc.error(format(_('There are no redos for %s.'), channel))
redo = wrap(redo, ['canChangeTopic']) redo = wrap(redo, ['canChangeTopic'])
@internationalizeDocstring
def swap(self, irc, msg, args, channel, first, second): def swap(self, irc, msg, args, channel, first, second):
"""[<channel>] <first topic number> <second topic number> """[<channel>] <first topic number> <second topic number>
@ -609,9 +562,7 @@ class Topic(callbacks.Plugin):
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
if first == second: if first == second:
irc.error(_('I refuse to swap the same topic with itself.')) irc.error(_('I refuse to swap the same topic with itself.'))
@ -622,7 +573,6 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)
swap = wrap(swap, ['canChangeTopic', 'topicNumber', 'topicNumber']) swap = wrap(swap, ['canChangeTopic', 'topicNumber', 'topicNumber'])
@internationalizeDocstring
def save(self, irc, msg, args, channel): def save(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -630,9 +580,7 @@ class Topic(callbacks.Plugin):
later. <channel> is only necessary if the message isn't sent in later. <channel> is only necessary if the message isn't sent in
the channel itself. the channel itself.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topic = irc.state.getTopic(channel) topic = irc.state.getTopic(channel)
if topic: if topic:
self.setRegistryValue('default', value=topic, channel=channel) self.setRegistryValue('default', value=topic, channel=channel)
@ -641,7 +589,6 @@ class Topic(callbacks.Plugin):
irc.replySuccess() irc.replySuccess()
save = wrap(save, ['channel', 'inChannel']) save = wrap(save, ['channel', 'inChannel'])
@internationalizeDocstring
def default(self, irc, msg, args, channel): def default(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -649,9 +596,7 @@ class Topic(callbacks.Plugin):
default topic for a channel may be configured via the configuration default topic for a channel may be configured via the configuration
variable supybot.plugins.Topic.default. variable supybot.plugins.Topic.default.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topic = self.registryValue('default', channel) topic = self.registryValue('default', channel)
if topic: if topic:
self._sendTopics(irc, channel, [topic]) self._sendTopics(irc, channel, [topic])
@ -660,16 +605,13 @@ class Topic(callbacks.Plugin):
channel)) channel))
default = wrap(default, ['canChangeTopic']) default = wrap(default, ['canChangeTopic'])
@internationalizeDocstring
def separator(self, irc, msg, args, channel, separator): def separator(self, irc, msg, args, channel, separator):
"""[<channel>] <separator> """[<channel>] <separator>
Sets the topic separator for <channel> to <separator> Converts the Sets the topic separator for <channel> to <separator> Converts the
current topic appropriately. current topic appropriately.
""" """
if not self._checkManageCapabilities(irc, msg, channel): self._checkManageCapabilities(irc, msg, channel)
capabilities = self.registryValue('requireManageCapability')
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel) topics = self._splitTopic(irc.state.getTopic(channel), channel)
self.setRegistryValue('separator', separator, channel) self.setRegistryValue('separator', separator, channel)
self._sendTopics(irc, channel, topics) self._sendTopics(irc, channel, topics)