fulvia/trigger.py

156 lines
4.1 KiB
Python
Raw Normal View History

2018-03-16 03:13:43 -04:00
#!/usr/bin/env python3
"""
The trigger abstraction layer.
"""
import datetime
def split_user(user):
"""
Splits a user hostmask into <nick>!<ident>@<host>
"""
nick, _, host = user.partition("!")
ident, _, host = host.partition("@")
if not host:
host = ident
ident = ""
return nick, ident, host
class Group(list):
"""
Custom list class that permits calling it like a function so as to
emulate a re.group instance.
"""
def __init__(self, message, config):
"""
Initializes the group class. If 'message' is a string, we split
it into groups according to the usual trigger.group structure.
Otherwise we assume it's already been split appropriately.
"""
if type(message) == str:
message = self.split_group(message, config)
list.__init__(self, message)
def __call__(self, n=0):
"""
Allows you to call the instance like a function. Or a re.group
instance ;^).
If calling would result in an index error, None is returned instead.
"""
try:
item = list.__getitem__(self, n)
except IndexError:
item = None
return item
def split_group(self, message, config):
"""
Splits the message by spaces.
group(0) is always the entire message.
group(1) is always the first word of the message minus the prefix, if
present. This is usually just the command.
group(2) is always the entire message after the first word.
group(3+) is always every individual word after the first word.
"""
prefix = config.core.prefix
group = []
group.append(message)
words = message.split()
group.append(words[0].replace(prefix, "", 1))
group.append(" ".join(words[1:]))
group += words[1:]
return group
class Trigger():
def __init__(self, user, channel, message, event, config):
self.channel = channel
"""
The channel from which the message was sent.
In a private message, this is the nick that sent the message.
"""
self.time = datetime.datetime.now()
"""
A datetime object at which the message was received by the IRC server.
If the server does not support server-time, then `time` will be the time
that the message was received by Fulvia.
2018-03-16 03:13:43 -04:00
"""
self.raw = ""
"""
The entire message, as sent from the server. This includes the CTCP
\\x01 bytes and command, if they were included.
"""
self.is_privmsg = not channel.startswith("#")
"""True if the trigger is from a user, False if it's from a channel."""
self.hostmask = user
"""
Entire hostmask of the person who sent the message.
eg. <nick>!<ident>@<host>
"""
nick, ident, host = split_user(user)
self.nick = nick
"""Nick of person who sent the message."""
self.ident = ident
self.user = ident
"""Local username (AKA ident) of the person who sent the message."""
self.host = host
"""The hostname of the person who sent the message"""
self.event = event
"""
The IRC event (e.g. ``PRIVMSG`` or ``MODE``) which triggered the
message.
"""
self.group = Group(message, config)
"""The ``group`` function of the ``match`` attribute.
See Python :mod:`re` documentation for details."""
self.args = ()
"""
A tuple containing each of the arguments to an event. These are the
strings passed between the event name and the colon. For example,
setting ``mode -m`` on the channel ``#example``, args would be
``('#example', '-m')``
"""
admins = config.core.admins.split(",") + [config.core.owner]
self.admin = any([self.compare_hostmask(admin) for admin in admins])
"""
True if the nick which triggered the command is one of the bot's
admins.
"""
self.owner = self.compare_hostmask(config.core.owner)
"""True if the nick which triggered the command is the bot's owner."""
def compare_hostmask(self, compare_against):
"""
Compares the current hostmask against the given one. If ident is not
None, it uses that, otherwise it only uses <nick>@<host>.
"""
if self.ident:
return compare_against == self.hostmask
else:
return compare_against == "@".join(self.nick, self.host)
def set_group(self, line, config):
"""
Allows a you to easily change the current group to a new Group
instance.
"""
self.group = Group(line, config)