# Path: cardinal/decorators.py
# def command(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Command must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.commands = triggers
#         return f
# 
#     return wrap
# 
# def help(lines):
#     # For backwards compatibility
#     if isinstance(lines, str):
#         lines = [lines]
# 
#     if not isinstance(lines, list):
#         raise TypeError("Help must be a help string or list of help strings")
# 
#     def wrap(f):
#         # Create help list or prepend to it
#         if not hasattr(f, 'help'):
#             f.help = lines
#         else:
#             f.help = lines + f.help
# 
#         return f
# 
#     return wrap
# 
# def event(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Event must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.events = triggers
#         return f
# 
#     return wrap
# 
# Path: cardinal/util.py
# def is_action(message):
#     """Checks if a message is a /me message."""
#     return message.startswith("\x01ACTION")
# 
# def parse_action(nick, message):
#     """Parses a /me message like an IRC client might.
# 
#     e.g. "/me dances." -> "* Cardinal dances."
#     """
#     if not is_action(message):
#         raise ValueError("This message is not an ACTION message")
# 
#     message = message[len("\x01ACTION "):]
#     if message and message[-1] == "\x01":
#         message = message[:-1]
# 
#     return "* {}{}".format(
#         nick,
#         " " + message if message else "",
#     )
# 
# def strip_formatting(line):
#     """Removes mIRC control code formatting"""
#     return re.sub(r"(?:\x03\d\d?,\d\d?|\x03\d\d?|[\x01-\x1f])", "", line)


from datetime import datetime, timezone
from cardinal.decorators import command, help, event
from cardinal.util import (
    is_action,
    parse_action,
    strip_formatting,
)
    @event('irc.privmsg')
    def irc_privmsg(self, cardinal, user, channel, message):
        if channel != cardinal.nickname and \
                channel not in self.ignored_channels:
            self.update_user(user.nick, PRIVMSG, [channel, message])

        self.do_tell(user.nick)

    @event('irc.notice')
    def irc_notice(self, cardinal, user, channel, message):
        if channel != cardinal.nickname and \
                channel not in self.ignored_channels:
            self.update_user(user.nick, NOTICE, [channel, message])

        self.do_tell(user.nick)

    @event('irc.mode')
    def irc_mode(self, cardinal, user, channel, mode):
        if channel not in self.ignored_channels:
            self.update_user(user.nick, MODE, [channel, mode])

        self.do_tell(user.nick)

    @event('irc.topic')
    def irc_topic(self, cardinal, user, channel, topic):
        if channel not in self.ignored_channels:
            self.update_user(user.nick, TOPIC, [channel, topic])

        self.do_tell(user.nick)


# Path: cardinal/decorators.py
# def command(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Command must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.commands = triggers
#         return f
# 
#     return wrap
# 
# def help(lines):
#     # For backwards compatibility
#     if isinstance(lines, str):
#         lines = [lines]
# 
#     if not isinstance(lines, list):
#         raise TypeError("Help must be a help string or list of help strings")
# 
#     def wrap(f):
#         # Create help list or prepend to it
#         if not hasattr(f, 'help'):
#             f.help = lines
#         else:
#             f.help = lines + f.help
# 
#         return f
# 
#     return wrap
# 
# def event(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Event must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.events = triggers
#         return f
# 
#     return wrap
# 
# Path: cardinal/util.py
# def is_action(message):
#     """Checks if a message is a /me message."""
#     return message.startswith("\x01ACTION")
# 
# def parse_action(nick, message):
#     """Parses a /me message like an IRC client might.
# 
#     e.g. "/me dances." -> "* Cardinal dances."
#     """
#     if not is_action(message):
#         raise ValueError("This message is not an ACTION message")
# 
#     message = message[len("\x01ACTION "):]
#     if message and message[-1] == "\x01":
#         message = message[:-1]
# 
#     return "* {}{}".format(
#         nick,
#         " " + message if message else "",
#     )
# 
# def strip_formatting(line):
#     """Removes mIRC control code formatting"""
#     return re.sub(r"(?:\x03\d\d?,\d\d?|\x03\d\d?|[\x01-\x1f])", "", line)


# Path: plugins/seen/plugin.py
from datetime import datetime, timezone
from cardinal.decorators import command, help, event
from cardinal.util import (
    is_action,
    parse_action,
    strip_formatting,
)

    @event('irc.privmsg')
    def irc_privmsg(self, cardinal, user, channel, message):
        if channel != cardinal.nickname and \
                channel not in self.ignored_channels:
            self.update_user(user.nick, PRIVMSG, [channel, message])

        self.do_tell(user.nick)

    @event('irc.notice')
    def irc_notice(self, cardinal, user, channel, message):
        if channel != cardinal.nickname and \
                channel not in self.ignored_channels:
            self.update_user(user.nick, NOTICE, [channel, message])

        self.do_tell(user.nick)

    @event('irc.mode')
    def irc_mode(self, cardinal, user, channel, mode):
        if channel not in self.ignored_channels:
            self.update_user(user.nick, MODE, [channel, mode])

        self.do_tell(user.nick)

    @event('irc.topic')
    def irc_topic(self, cardinal, user, channel, topic):
        if channel not in self.ignored_channels:
            self.update_user(user.nick, TOPIC, [channel, topic])

        self.do_tell(user.nick)


    @event('irc.join')