Exemple #1
0
    async def on_member_join(self, member):
        general = neko.find(
            lambda c: c.name == 'general', member.guild.channels
        )

        if general:
            await general.send(
                f'Welcome to {member.guild}, {member.mention}!'
            )
Exemple #2
0
    async def on_member_remove(self, member):
        general = neko.find(
            lambda c: c.name == 'general', member.guild.channels
        )

        if general:
            await general.send(
                f'Oh no! {member.display_name} just left \N{CRYING CAT FACE}...'
            )
Exemple #3
0
    async def on_member_ban(self, guild, user):
        general = neko.find(
            lambda c: c.name == 'general', guild.channels
        )

        if general:
            await general.send(
                f'{user.display_name} just got bent.\n'
                'https://giphy.com/gifs/H99r2HtnYs492'
            )
Exemple #4
0
    async def reset_cooldown(self, ctx, *, command):
        command = neko.find(lambda c: c.qualified_name == command
                                      or command in c.qualified_aliases,
                            ctx.bot.walk_commands())

        if command:
            command._buckets._cooldown.reset()
            command._buckets._cache.clear()
            await ctx.send('Cooldown reset.', delete_after=10)
        else:
            await ctx.send('Couldn\'t find that command.')
Exemple #5
0
    async def on_message(self, msg):
        """
        When we get a message, we check if certain Discord-app
        binds are at the start. If there is, we reply with that
        bind. It is as close as I can get to actually supporting
        the binds that you can use on desktop, on mobile.
        """
        if not msg.guild or msg.author.bot:
            return

        guild = msg.guild.id
        chan = msg.channel.id

        timeout_k = str(guild) + str(chan)
        timeout_v = self.bind_cooldown_buckets.get(timeout_k)

        # If the user id was mapped under that identity in the
        # buckets, then we are on timeout, so don't bother doing
        # anything else.
        if timeout_v == msg.author.id:
            return

        async def callback():
            if msg.author.id == self.bot.owner_id:
                # Owner privileges, kek.
                return

            # Insert into the dict
            self.bind_cooldown_buckets[timeout_k] = msg.author.id
            # Cooldown for 30s.
            await asyncio.sleep(30)
            # Remove from the dict
            # Specify None to prevent KeyError if it was already
            # removed somehow.
            self.bind_cooldown_buckets.pop(timeout_k, None)

        # Attempt to find the bind (this returns a tuple or None if not found)
        bind = neko.find(lambda r: r.match(msg.content), binds)

        if not bind:
            return
        else:
            bind = binds[bind]

        # Ensure the future, but don't bother waiting.
        asyncio.ensure_future(callback())
        await msg.channel.send(bind)
Exemple #6
0
    async def on_error(cls, cog, ctx: commands.Context, error):
        """Handles any errors that may occur in a command."""
        ctx.bot.last_error = (type(error), error, error.__traceback__)

        try:
            # For specific types of error, just react.
            reacts = {
                commands.CheckFailure: '\N{NO ENTRY SIGN}',
                commands.MissingRequiredArgument: '\N{THOUGHT BALLOON}',
                commands.CommandOnCooldown: '\N{ALARM CLOCK}',
                commands.DisabledCommand: '\N{MOBILE PHONE OFF}',
                discord.ClientException: '\N{COLLISION SYMBOL}',
            }

            reaction = neko.find(lambda e: issubclass(type(error), e), reacts)
            reaction = reacts[reaction]

            if not issubclass(type(error), discord.NotFound):
                await ctx.message.add_reaction(reaction)
            else:
                pass  # ?? You cant react to something you cant react to.

        except KeyError:
            # If we haven't specified a reaction, we instead do something
            # meaningful.
            error = error.__cause__ if error.__cause__ else error

            if not isinstance(error, NotImplementedError):
                if isinstance(error, Warning):
                    title = f'\N{WARNING SIGN} {error}'
                else:
                    title = '\N{SQUARED SOS} Oh crap...'

                description = strings.capitalise(excuses.get_excuse())
            else:
                title = ('\N{NO PEDESTRIANS} '
                         'Road under construction. Follow diversion.')

                description = ('Seems this feature isn\'t finished! Hassle '
                               'Espy to get on it. ')

            embed = book.Page(
                title=title,
                description=description,
                colour=0xffbf00 if isinstance(error, Warning) else 0xff0000)

            if isinstance(error, NekoCommandError):
                pass
            elif not isinstance(error, Warning):
                # We only show info like the cog name, etc if we are not a
                # neko command error. Likewise, we only dump a traceback if the
                # latter holds.
                error_description = strings.pascal_to_space(
                    type(error).__name__)

                cog = strings.pascal_to_space(getattr(cog, 'name', str(cog)))
                error_str = str(error).strip()
                if error_str:
                    error_description += f' in {cog}: {str(error)}'
                else:
                    error_description += f' in {cog}.'

                embed.set_footer(text=error_description)
                traceback.print_exception(type(error), error,
                                          error.__traceback__)

            resp = await ctx.send(embed=embed)
            await asyncio.sleep(10)
            if isinstance(error, NekoCommandError):
                await resp.delete()
                return
            elif isinstance(error, Warning):
                await resp.edit(content='_Warnings were generated._')
            else:
                await resp.edit(content='_**Errors** were generated._')

            async def del_in_10():
                await asyncio.sleep(10 * 60)
                try:
                    await resp.delete()
                finally:
                    return

            asyncio.ensure_future(del_in_10)