BadWords: Re-allow words with a space (aka 'phrases')

I disallowed it in f3f628ddba because they
couldn't be deserialized properly.

This commit adds a new 'phrases' config var in addition to 'words',
that is comma-separated instead of space-separated.
This commit is contained in:
Valentin Lorentz 2020-09-05 22:21:11 +02:00
parent 23417b0675
commit bdbb74f046
3 changed files with 51 additions and 19 deletions

View File

@ -44,15 +44,27 @@ def configure(advanced):
'spaces)'))
conf.supybot.plugins.BadWords.words.set(words)
class LastModifiedSetOfStrings(registry.SpaceSeparatedSetOfStrings):
class LastModifiedSpaceSeparatedSetOfStrings(registry.SpaceSeparatedSetOfStrings):
lastModified = 0
def setValue(self, v):
self.lastModified = time.time()
registry.SpaceSeparatedListOfStrings.setValue(self, v)
class LastModifiedCommaSeparatedSetOfStrings(registry.CommaSeparatedSetOfStrings):
lastModified = 0
def set(self, v):
if not v.strip():
self.setValue(set())
else:
super().set(v)
def setValue(self, v):
self.lastModified = time.time()
registry.CommaSeparatedListOfStrings.setValue(self, v)
BadWords = conf.registerPlugin('BadWords')
conf.registerGlobalValue(BadWords, 'words',
LastModifiedSetOfStrings([], _("""Determines what words are
LastModifiedSpaceSeparatedSetOfStrings([], _("""Determines what words are
considered to be 'bad' so the bot won't say them.""")))
conf.registerChannelValue(BadWords,'requireWordBoundaries',
registry.Boolean(False, _("""Determines whether the bot will require bad
@ -62,6 +74,9 @@ conf.registerChannelValue(BadWords,'requireWordBoundaries',
false. After changing this setting, the BadWords regexp needs to be
regenerated by adding/removing a word to the list, or reloading the
plugin.""")))
conf.registerGlobalValue(BadWords, 'phrases',
LastModifiedCommaSeparatedSetOfStrings([], _("""Comma-separated groups
of words that are considered to be 'bad'.""")))
class String256(registry.String):
def __call__(self):

View File

@ -53,6 +53,7 @@ class BadWords(callbacks.Privmsg):
self.filtering = True
self.lastModified = 0
self.words = conf.supybot.plugins.BadWords.words
self.phrases = conf.supybot.plugins.BadWords.phrases
def callCommand(self, name, irc, msg, *args, **kwargs):
if ircdb.checkCapability(msg.prefix, 'admin'):
@ -71,7 +72,7 @@ class BadWords(callbacks.Privmsg):
self.filtering = True
# We need to check for bad words here rather than in doPrivmsg because
# messages don't get to doPrivmsg if the user is ignored.
if msg.command == 'PRIVMSG' and self.words():
if msg.command == 'PRIVMSG' and (self.words() or self.phrases()):
channel = msg.channel
self.updateRegexp(channel, irc.network)
s = ircutils.stripFormatting(msg.args[1])
@ -96,12 +97,14 @@ class BadWords(callbacks.Privmsg):
return msg
def updateRegexp(self, channel, network):
if self.lastModified < self.words.lastModified:
self.makeRegexp(self.words(), channel, network)
if self.lastModified < self.words.lastModified \
or self.lastModified < self.phrases.lastModified:
self.makeRegexp(self.words() | self.phrases(), channel, network)
self.lastModified = time.time()
def outFilter(self, irc, msg):
if self.filtering and msg.command == 'PRIVMSG' and self.words():
if self.filtering and msg.command == 'PRIVMSG' \
and (self.words() or self.phrases()):
channel = msg.channel
self.updateRegexp(channel, irc.network)
s = msg.args[1]
@ -124,7 +127,7 @@ class BadWords(callbacks.Privmsg):
Returns the list of words being censored.
"""
L = list(self.words())
L = list(self.words() | self.phrases())
if L:
self.filtering = False
utils.sortBy(str.lower, L)
@ -134,29 +137,42 @@ class BadWords(callbacks.Privmsg):
list = wrap(list, ['admin'])
@internationalizeDocstring
def add(self, irc, msg, args, words):
def add(self, irc, msg, args, new_words):
"""<word> [<word> ...]
Adds all <word>s to the list of words being censored.
"""
set = self.words()
set.update(words)
self.words.setValue(set)
words = self.words()
phrases = self.phrases()
for word in new_words:
if ' ' in word:
phrases.add(word)
else:
words.add(word)
self.words.setValue(words)
self.phrases.setValue(phrases)
irc.replySuccess()
add = wrap(add, ['admin', many('somethingWithoutSpaces')])
add = wrap(add, ['admin', many('something')])
@internationalizeDocstring
def remove(self, irc, msg, args, words):
def remove(self, irc, msg, args, old_words):
"""<word> [<word> ...]
Removes <word>s from the list of words being censored.
"""
set = self.words()
for word in words:
set.discard(word)
self.words.setValue(set)
words = self.words()
phrases = self.phrases()
for word in old_words:
words.discard(word)
phrases.discard(word)
self.words.setValue(words)
self.phrases.setValue(phrases)
irc.replySuccess()
remove = wrap(remove, ['admin', many('somethingWithoutSpaces')])
remove = wrap(remove, ['admin', many('something')])
Class = BadWords

View File

@ -76,7 +76,8 @@ class BadWordsTestCase(PluginTestCase):
self.assertNotError('badwords list')
self.assertNotError('badwords add shit')
self.assertNotError('badwords add ass')
self.assertResponse('badwords list', 'ass and shit')
self.assertNotError('badwords add "fuck you"')
self.assertResponse('badwords list', 'ass, fuck you, and shit')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: