示例#1
0
class Images(wheel(desc='image manipulation')):
    def __init__(self, bot):
        super().__init__(bot)

        self.frothy_images = glob('images/frothy/*.png')

    @command(brief='the scrub mentality',
             help="""
        // get a random picture of frothy omen
        &frothy

        // get a specific picture of frothy omen
        &frothy 0
        """)
    async def frothy(self, ctx, idx: int = None):
        if not idx:
            await ctx.send(file=File(choice(self.frothy_images)))
        elif idx not in range(len(self.frothy_images)):
            await ctx.send(
                f'index must be between 0 and {len(self.frothy_images)}')
        else:
            await ctx.send(file=File(self.frothy_images[idx]))

    @command(brief='get a picture of a cat',
             help="""
        // get a cat picture from the internet
        &cat
        """)
    async def cat(self, ctx):
        obj = await json_request('https://api.thecatapi.com/v1/images/search')
        return await ctx.send(
            embed=ctx.embed('cat', 'thecatapi.com', image=obj[0]['url']))
示例#2
0
class Media(wheel(desc='social media websites')):
    def __init__(self, bot):
        super().__init__(bot)

        if rcfg := bot.config.get('reddit', None):
            self.rapi = Reddit(client_id=rcfg['id'],
                               client_secret=rcfg['secret'],
                               user_agent='python:discord.claymore:v2')
        else:
示例#3
0
class Admin(wheel(desc='server administration tools')):
    def __init__(self, bot):
        super().__init__(bot)

        @bot.listen()
        async def on_member_join(member):
            if roles := await self.db.roles.find_one({'id': member.guild.id}):
                await member.edit(roles=[
                    it for each in roles['roles']
                    if (it := member.guild.get_role(each))
                ])
示例#4
0
class Fun(wheel(desc = 'fun commands')):
    @command()
    async def coinflip(self, ctx):
        pass

    @command()
    async def rate(self, ctx, *, thing: str):
        pass

    @command(
        brief = 'ask the magic 8ball a question',
        aliases = [ '8', '8ball' ]
    )
    async def magic(self, ctx):
        pass

    @command()
    async def rank(self, ctx, *, items: str):
        pass
示例#5
0
class Star(wheel(desc='starboard')):
    def __init__(self, bot):
        super().__init__(bot)

        @bot.listen()
        async def on_raw_reaction_add(event):
            guild = self.bot.get_guild(event.guild_id)
            chan = guild.get_channel(event.channel_id)
            user = event.member
            msg = await chan.fetch_message(event.message_id)

            if emote := await self.db.star.find_one({'id': user.guild.id}):
                if not (channel := user.guild.get_channel(emote['channel'])):
                    return

                num = len([
                    react for react in msg.reactions
                    if react.emoji == emote['emote']
                ])
                if num >= emote.get('limit', 10):
                    await channel.send(embed=star_embed(msg.author, msg))
示例#6
0
class Moderation(wheel(desc='server moderation')):
    #TODO: all these
    @command()
    @has_permissions(manage_messages=True)
    async def warn(self, ctx, user: Member):
        pass

    @command()
    async def warnings(self, ctx, user: Member = None):
        pass

    @command()
    @has_permissions(administrator=True)
    async def kick(self, ctx, user: Member):
        pass

    @command()
    @has_permissions(administrator=True)
    async def ban(self,
                  ctx,
                  user: Member,
                  *,
                  reason: str = 'no reason provided'):
        pass

    @command()
    @has_permissions(manage_messages=True)
    async def mute(self,
                   ctx,
                   user: Member,
                   time: str = None,
                   *,
                   reason: str = 'no reason provided'):
        pass

    @command()
    @has_permissions(manage_messages=True)
    async def unmute(self, ctx, user: Member):
        pass
示例#7
0
class Utils(wheel(desc='helpful tools')):
    def __init__(self, bot):
        super().__init__(bot)
        if wkey := bot.config['keys'].get('wolfram', None):
            self.wapi = Wolfram(wkey)
        else:
示例#8
0
class Text(wheel(desc = 'automatic messages')):
    def __init__(self, bot):
        super().__init__(bot)

        @bot.listen()
        async def on_message(message):
            if message.author.bot:
                return

            reacts = await self.db.reacts.find_one({ 'id': message.guild.id })

            for text, emotes in (reacts or {}).items():
                if 'id' in text:
                    continue

                if text in message.content:
                    for emote in emotes:
                        await message.add_reaction(emote)

        @bot.listen()
        async def on_member_join(member):
            if member.bot:
                return

            message = await self.db.welcome.find_one({ 'id': member.guild.id })
            if not message or not message['msg']:
                return

            await member.guild.get_channel(message['channel']).send(message['msg'].replace('$user', member.mention))

        @bot.listen()
        async def on_member_remove(member):
            if member.bot:
                return

            message = await self.db.leave.find_one({ 'id': member.guild.id })
            if not message or not message['msg']:
                return

            await member.guild.get_channel(message['channel']).send(message['msg'].replace('$user', member.mention))

    @group(
        invoke_without_command = True,
        brief = 'list all reacts',
        help = """
        // list all current autoreacts for the server
        &reacts
        """
    )
    @guild_only()
    async def reacts(self, ctx):
        async def fail():
            await ctx.send(embed = ctx.embed('no autoreacts', 'add autoreacts using `reacts add`'))

        if not (current := await self.db.reacts.find_one({ 'id': ctx.guild.id })):
            return await fail()

        embed = PagedEmbed('all embeds', f'`{len(current)}` total phrases')

        for phrase, emotes in current.items():
            if 'id' in phrase:
                continue

            embed.add_field(phrase, ', '.join(emotes))

        if not embed.fields:
            return await fail()

        await ctx.page_embeds(embed)
示例#9
0
class Help(wheel(desc='bot usage commands')):
    def __init__(self, bot: Claymore):
        super().__init__(bot)
        bot.add_listener(self.on_command_error)

    async def on_command_error(self, ctx, err):
        options = {
            CommandNotFound: self.command_not_found,
            PermissionError: self.permission_denied,
            CommandOnCooldown: self.cooldown,
            BotMissingPermissions: self.missing_permissions
        }

        await ctx.send(options.get(type(err), self.report_error)(ctx, err))

    def report_error(self, ctx, err: Exception) -> str:
        stack = '\n'.join(format_exception(type(err), err, err.__traceback__))
        self.log.error(f'encountered {err} exception {stack}')
        return 'encountered an unexpected issue, this interaction has been reported'

    def command_not_found(self, ctx, _) -> str:
        return f'command `{ctx.invoked_with}` not found'

    def permission_denied(self, ctx, _) -> str:
        return f'you do not have sufficient privileges to use the `{ctx.invoked_with}` command`'

    def cooldown(self, ctx, err) -> str:
        return f'command is still on cooldown, try again in `{err.retry_after:.2f}s`'

    def missing_permissions(self, ctx, err) -> str:
        return f'i am missing permissions to execute that command\nrequired permissions: {", ".join(err.missing_perms)}'

    def search_fuzz(self, ctx, items, item: str, msg: str):
        res = fuzzy(items, item)
        if not res:
            return f'no {msg} named {item}'

        names = "  \n".join(res)
        return ctx.embed(f'no {msg} named {item}',
                         f'possible results\n```{names}```')

    def all_cogs(self, ctx, prefix) -> Embed:
        fields = {
            name: body.description
            for name, body in self.bot.cogs.items() if not body.hidden
        }
        desc = f'`{", ".join(prefix)}` are the current prefixes' if isinstance(
            prefix, tuple) else f'`{prefix}` is the current prefix'
        return ctx.embed('all cogs',
                         f'all cogs you have permission to use\n{desc}',
                         fields)

    def cog_help(self, ctx, cog_name: str) -> Embed:
        cog = first(self.bot.cogs.items(), cog_name)
        if not cog or cog.hidden:
            return self.search_fuzz(ctx, self.bot.cogs.keys(), cog_name, 'cog')

        cmds = {
            cmd.name: (cmd.brief or cmd.usage) if cmd.enabled else '(disabled)'
            for cmd in cog.get_commands() if not cmd.hidden
        }

        return ctx.embed(f'all commands in {cog_name}',
                         f'{len(cmds)} total commands', cmds)

    async def cmd_help(self, ctx, name):
        if not name:
            return False

        cmd = self.bot.get_command(name.lower())
        if not cmd or cmd.hidden:
            return False

        details = {
            'signature':
            f'```\n{cmd.qualified_name} {cmd.signature}```',
            'enabled':
            str(cmd.enabled).lower(),
            'aliases':
            ', '.join(cmd.aliases) if cmd.aliases else 'no aliases',
            'usage': (f'```{dedent(cmd.help)}```',
                      False) if cmd.help else 'see signature'
        }

        if isinstance(cmd, Group):
            details[
                'subcommands'] = f'```\n{", ".join([it.name for it in cmd.commands])}```'

        await ctx.send(embed=ctx.embed(cmd.name, cmd.brief, details))
        return True

    @command(brief='bot usermanual',
             help="""
        // get general help
        &help

        // get help about a cog
        &help utils

        // get help for a specific command
        &help ping
        """)
    async def help(self, ctx: Context, *, name: str = None):
        # self.cmd_help prints and returns true if it finds a command
        if not await self.cmd_help(ctx, name):
            await ctx.push(
                self.cog_help(ctx, name.lower()) if name else self.
                all_cogs(ctx, await self.bot.get_prefix(ctx)))

    def cog_commands(self, ctx, name: str):
        cog = first(self.bot.cogs.items(), name)

        if not cog:
            return self.search_fuzz(ctx, self.bot.cogs.keys(), name, 'cog')

        cmds = cog.get_commands()
        names = "  \n".join([format_cmds(cmd) for cmd in cmds])

        return ctx.embed(f'all commands for {name}',
                         f'{len(cmds)} total commands```\n{names}```')

    def all_commands(self, ctx):
        ncogs = 0
        ncmds = 0
        fields = {}

        for it, cog in self.bot.cogs.items():
            if cog.hidden:
                continue

            cmds = cog.get_commands()
            ncogs += 1
            ncmds += len(cmds)

            names = ''
            names = '\n'.join([format_cmds(cmd) for cmd in cmds])
            fields[it] = f'```\n{names}```'

        return ctx.embed('all commands',
                         f'{ncogs} cogs containing {ncmds} commands', fields)

    @command(brief='command & module listings',
             help="""
        // list all commands
        &commands

        // list all commands in a specific module
        &help utils
        """)
    async def commands(self, ctx: Context, mod: str = None):
        await ctx.send(embed=self.cog_commands(ctx, mod.lower(
        )) if mod else self.all_commands(ctx))