Skip to content

Commit

Permalink
Reworking blocks to use IRC nick!user@host syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan authored and Alan Huang committed Mar 22, 2018
1 parent b5bfbc2 commit 0d0b73a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 93 deletions.
54 changes: 21 additions & 33 deletions sopel/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,8 @@ def __init__(self, config, daemon=False):

# Set up block lists
# Default to empty
if not self.config.core.nick_blocks:
self.config.core.nick_blocks = []
if not self.config.core.host_blocks:
self.config.core.host_blocks = []
if not self.config.core.hostmask_blocks:
self.config.core.hostmask_blocks = []
self.setup()

# Backwards-compatibility aliases to attributes made private in 6.2. Remove
Expand Down Expand Up @@ -302,6 +300,7 @@ def say(self, text, recipient, max_messages=1):
message will contain the entire remainder, which may be truncated by
the server.
"""
text = re.sub("(?i)salaxalans", "Salad", text)
# We're arbitrarily saying that the max is 400 bytes of text when
# messages will be split. Otherwise, we'd have to acocunt for the bot's
# hostmask, which is hard.
Expand Down Expand Up @@ -515,11 +514,13 @@ def dispatch(self, pretrigger):
args = pretrigger.args
event, args, text = pretrigger.event, args, args[-1] if args else ''

if self.config.core.nick_blocks or self.config.core.host_blocks:
nick_blocked = self._nick_blocked(pretrigger.nick)
host_blocked = self._host_blocked(pretrigger.host)
if self.config.core.hostmask_blocks:
hostmask_blocked = self._hostmask_blocked(pretrigger.hostmask)
else:
nick_blocked = host_blocked = None
hostmask_blocked = None

if hostmask_blocked:
return

list_of_blocked_functions = []
for priority in ('high', 'medium', 'low'):
Expand All @@ -537,7 +538,7 @@ def dispatch(self, pretrigger):
for func in funcs:
if (not trigger.admin and
not func.unblockable and
(nick_blocked or host_blocked)):
hostmask_blocked):
function_name = "%s.%s" % (
func.__module__, func.__name__
)
Expand All @@ -557,38 +558,25 @@ def dispatch(self, pretrigger):
self.call(func, wrapper, trigger)

if list_of_blocked_functions:
if nick_blocked and host_blocked:
block_type = 'both'
elif nick_blocked:
block_type = 'nick'
else:
block_type = 'host'
if hostmask_blocked:
block_type = 'hostmask'
LOGGER.info(
"[%s]%s prevented from using %s.",
block_type,
trigger.nick,
', '.join(list_of_blocked_functions)
)

def _host_blocked(self, host):
bad_masks = self.config.core.host_blocks
for bad_mask in bad_masks:
bad_mask = bad_mask.strip()
if not bad_mask:
continue
if (re.match(bad_mask + '$', host, re.IGNORECASE) or
bad_mask == host):
return True
return False

def _nick_blocked(self, nick):
bad_nicks = self.config.core.nick_blocks
for bad_nick in bad_nicks:
bad_nick = bad_nick.strip()
if not bad_nick:
def _hostmask_blocked(self, hostmask):
bad_hostmasks = self.config.core.hostmask_blocks
for bad_hostmask in bad_hostmasks:
bad_hostmask = bad_hostmask.strip()
if not bad_hostmask:
continue
if (re.match(bad_nick + '$', nick, re.IGNORECASE) or
Identifier(bad_nick) == nick):
bad_hostmask = re.sub(r'\.', r'\.', bad_hostmask)
bad_hostmask = re.sub(r'\*', r'.*', bad_hostmask)
if re.match(bad_hostmask, hostmask, re.IGNORECASE):
print('hostmask {} blocked'.format(hostmask))
return True
return False

Expand Down
7 changes: 1 addition & 6 deletions sopel/config/core_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def homedir(self):
host = ValidatedAttribute('host', default='irc.dftba.net')
"""The server to connect to."""

host_blocks = ListAttribute('host_blocks')
hostmask_blocks = ListAttribute('hostmask_blocks')
"""A list of hostmasks which Sopel should ignore.
Regular expression syntax is used"""
Expand Down Expand Up @@ -141,11 +141,6 @@ def homedir(self):
nick = ValidatedAttribute('nick', Identifier, default=Identifier('Sopel'))
"""The nickname for the bot"""

nick_blocks = ListAttribute('nick_blocks')
"""A list of nicks which Sopel should ignore.
Regular expression syntax is used."""

not_configured = ValidatedAttribute('not_configured', bool, default=False)
"""For package maintainers. Not used in normal configurations.
Expand Down
74 changes: 20 additions & 54 deletions sopel/coretasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,71 +563,37 @@ def blocks(bot, trigger):
STRINGS = {
"success_del": "Successfully deleted block: %s",
"success_add": "Successfully added block: %s",
"no_nick": "No matching nick block found for: %s",
"no_host": "No matching hostmask block found for: %s",
"invalid": "Invalid format for %s a block. Try: .blocks add (nick|hostmask) sopel",
"invalid": "Invalid format for %s a block. Try: .blocks add hostmask nick!user@host",
"invalid_display": "Invalid input for displaying blocks.",
"nonelisted": "No %s listed in the blocklist.",
'huh': "I could not figure out what you wanted to do.",
}

masks = set(s for s in bot.config.core.host_blocks if s != '')
nicks = set(Identifier(nick)
for nick in bot.config.core.nick_blocks
if nick != '')
masks = set(s for s in bot.config.core.hostmask_blocks if s != '')
text = trigger.group().split()

if len(text) == 3 and text[1] == "list":
if text[2] == "hostmask":
if len(masks) > 0:
blocked = ', '.join(unicode(mask) for mask in masks)
bot.say("Blocked hostmasks: {}".format(blocked))
else:
bot.reply(STRINGS['nonelisted'] % ('hostmasks'))
elif text[2] == "nick":
if len(nicks) > 0:
blocked = ', '.join(unicode(nick) for nick in nicks)
bot.say("Blocked nicks: {}".format(blocked))
else:
bot.reply(STRINGS['nonelisted'] % ('nicks'))
if len(text) == 2 and text[1] == "list":
if len(masks) > 0:
blocked = ', '.join(unicode(mask) for mask in masks)
bot.say("Blocked hostmasks: {}".format(blocked))
else:
bot.reply(STRINGS['invalid_display'])

elif len(text) == 4 and text[1] == "add":
if text[2] == "nick":
nicks.add(text[3])
bot.config.core.nick_blocks = nicks
bot.config.save()
elif text[2] == "hostmask":
masks.add(text[3].lower())
bot.config.core.host_blocks = list(masks)
else:
bot.reply(STRINGS['invalid'] % ("adding"))
return
bot.reply(STRINGS['nonelisted'] % ('hostmasks'))

bot.reply(STRINGS['success_add'] % (text[3]))

elif len(text) == 4 and text[1] == "del":
if text[2] == "nick":
if Identifier(text[3]) not in nicks:
bot.reply(STRINGS['no_nick'] % (text[3]))
return
nicks.remove(Identifier(text[3]))
bot.config.core.nick_blocks = [unicode(n) for n in nicks]
bot.config.save()
bot.reply(STRINGS['success_del'] % (text[3]))
elif text[2] == "hostmask":
mask = text[3].lower()
if mask not in masks:
bot.reply(STRINGS['no_host'] % (text[3]))
return
masks.remove(mask)
bot.config.core.host_blocks = [unicode(m) for m in masks]
bot.config.save()
bot.reply(STRINGS['success_del'] % (text[3]))
else:
bot.reply(STRINGS['invalid'] % ("deleting"))
elif len(text) == 3 and text[1] == "add":
masks.add(text[2].lower())
bot.config.core.hostmask_blocks = list(masks)
bot.reply(STRINGS['success_add'] % (text[2]))

elif len(text) == 3 and text[1] == "del":
mask = text[2].lower()
if mask not in masks:
bot.reply(STRINGS['no_host'] % (text[2]))
return
masks.remove(mask)
bot.config.core.hostmask_blocks = [unicode(m) for m in masks]
bot.config.save()
bot.reply(STRINGS['success_del'] % (text[2]))
else:
bot.reply(STRINGS['huh'])

Expand Down

0 comments on commit 0d0b73a

Please sign in to comment.