Ejemplo n.º 1
0
class Grouphugs(lurklib.Client):
    def __init__(self, *args, **kwargs):
        self._args = args
        self._kwargs = kwargs
        self.run_mainloop_forever = True
        self.events = Events()
        self.triggers = []
        self.max_line_chars = 440
        self.max_spam_lines = 5
        self.logger = logging.getLogger(__name__)

        def shutdown_handler(signum, frame):
            self.run_mainloop_forever = False
            self.logger.info("Caught shutdown signal, shutting down.")
            self.quit("Caught shutdown signal, shutting down.")

        # Attach management signals
        signal.signal(signal.SIGINT, shutdown_handler)
        signal.signal(signal.SIGTERM, shutdown_handler)

    def wrap_sender(self, sender):
        return Sender(*sender)

    def mainloop(self):
        super().__init__(*self._args, **self._kwargs)
        while self.run_mainloop_forever:
            try:
                super().mainloop()
            except Exception as e:
                self.on_exeption(e)

    # Abstractions for lurklibs silly ways to do some things

    def is_op(self, nick, channel):
        return nick in self.channels[channel]['USERS'] and '@' in self.channels[channel]['USERS'][nick][2]

    def privmsg(self, channel, message, spam=False):
        # Insert newlines for every 'max_line_chars' chars without any newlines
        message = re.sub(r'([^\n]{%s})' % self.max_line_chars, r'\1\n', message)

        message = re.sub(r'\r', '', message)     # Remove carriage returns
        message = re.sub(r'\n+', '\n', message)  # Remove consecutive newlines
        message = re.sub(r'^\n', '', message)    # Remove leading newline
        message = re.sub(r'\n$', '', message)    # Remove trailing newline
        message = re.sub(r'\t', '    ', message) # Replace tabs with spaces

        # Send each line separately
        messages = message.split('\n')

        if not spam and len(messages) > self.max_spam_lines:
            super().privmsg(channel, "This would spam the channel with %s lines, replace ! with @ if you really want that." % len(messages))
            return

        for message in messages:
            super().privmsg(channel, message)

    # Custom events

    def add_trigger(self, trigger, func):
        self.triggers.append({'trigger': trigger, 'func': func})

    # lurklibs event methods
    # We're not overriding all of them - for an exhaustive list, see lurklib/__init__.py

    def on_connect(self):
        for channel in config.CHANNELS:
            self.join_(channel)

    def on_join(self, sender, channel):
        self.events.on_join(self.wrap_sender(sender), channel)

    def on_part(self, sender, channel, reason):
        self.events.on_part(self.wrap_sender(sender), channel, reason)

    def on_chanmsg(self, sender, channel, message):
        self.events.on_chanmsg(self.wrap_sender(sender), channel, message)
        for trigger in self.triggers:
            if message.startswith("!%s" % trigger['trigger']):
                trigger['func'](self.wrap_sender(sender), channel, message[len(trigger['trigger']) + 1:].strip(), spam=False)
            elif message.startswith("@%s" % trigger['trigger']):
                trigger['func'](self.wrap_sender(sender), channel, message[len(trigger['trigger']) + 1:].strip(), spam=True)

    def on_privmsg(self, sender, message):
        self.events.on_privmsg(self.wrap_sender(sender), message)

    def on_kick(self, sender, channel, who, reason):
        self.events.on_kick(self.wrap_sender(sender), channel, who, reason)

    def on_nick(self, sender, new_nick):
        self.events.on_nick(self.wrap_sender(sender), new_nick)

    def on_quit(self, sender, reason):
        self.events.on_quit(self.wrap_sender(sender), reason)

    def on_exeption(self, exception):
        logger.exception(exception)