Пример #1
0
    async def logging_add(self, ctx, channel: Union[TextChannel],
                          logging_types: commands.Greedy[ModLoggingType]):
        """CONFIG_LOGGING_ADD_HELP"""
        logging_types = list(set(logging_types))  # BIG BRAIN CODE

        for logging_type in logging_types:
            if channel.id in getattr(
                    self.bot.cache.guilds.get(ctx.guild.id).logging,
                    logging_type.value):
                logging_types.remove(logging_type)
            else:
                await self.bot.db.logging.add(logging_type, ctx.guild.id,
                                              channel.id)

        if len(logging_types) <= 0:
            return await ctx.send(Translator.translate('NOTHING_CHANGED', ctx))

        await self.bot.cache.refresh(ctx.guild.id)
        await ctx.send(
            Translator.translate('MOD_LOGGING_ADDED',
                                 ctx,
                                 channel=channel.mention,
                                 logging_types=", ".join([
                                     ltype.value for ltype in logging_types
                                 ])))
Пример #2
0
    async def language(self, ctx, new_language=None):
        """CONFIG_LANGUAGE_HELP"""
        if new_language is None:
            settings = self.bot.cache.guilds.get(ctx.guild.id, None)
            current_language = (settings.language if settings is not None else
                                'en_US') or 'en_US'

            return await ctx.send(
                Translator.translate("CONFIG_LANGUAGE_CURRENT",
                                     ctx,
                                     language=current_language))

        if new_language not in Translator.translations.keys():
            return await ctx.send(
                Translator.translate(
                    "CONFIG_LANGUAGE_BAD_LANGUAGE",
                    ctx,
                    languages=", ".join(list(Translator.translations.keys()))))

        await self.bot.db.languages.set(ctx.guild.id, new_language)
        await self.bot.cache.refresh(ctx.guild.id)

        await ctx.send(
            Translator.translate("CONFIG_LANGUAGE_UPDATED",
                                 ctx,
                                 language=new_language))
Пример #3
0
    async def on_mod_log_join_leave(self, is_join: bool, member: Member):
        destinations = await self.get_destinations(member.guild.id,
                                                   ModLoggingType.join_leave)
        guild_tz = self.bot.cache.guilds.get(member.guild.id).timezone

        if is_join:
            time_fmt = datetime.now().astimezone(
                timezone(guild_tz)).strftime("%H:%M:%S")

            for channel in destinations:
                await channel.send(
                    Translator.translate('MOD_LOGS_JOIN',
                                         member.guild.id,
                                         time=time_fmt,
                                         target=str(member),
                                         target_id=str(member.id)))
        else:
            time_fmt = datetime.now().astimezone(
                timezone(guild_tz)).strftime("%H:%M:%S")

            for channel in destinations:
                await channel.send(
                    Translator.translate('MOD_LOGS_LEAVE',
                                         member.guild.id,
                                         time=time_fmt,
                                         target=str(member),
                                         target_id=str(member.id)))
Пример #4
0
    async def export(self, ctx):
        """TODO_EXPORT_HELP"""
        await ctx.trigger_typing()

        async with (await self.bot.db.get_pool()).acquire() as db:
            current_todos = await db.fetch(
                "SELECT * FROM bot.todos WHERE user_id = $1 ORDER BY timestamp DESC LIMIT 200;",
                ctx.author.id)

        if len(current_todos) <= 0:
            await ctx.send(Translator.translate("TODOS_EMPTY", ctx))
        else:
            output = "Todo:\n"
            for index, todo in enumerate(current_todos):
                output += f"{index + 1}) {todo['content']}\n"

            bdata = BytesIO()
            bdata.write(output.encode(encoding='utf-8'))
            bdata.seek(0)

            try:
                await ctx.author.send(
                    file=File(bdata, filename="Todo List.txt"))
                await ctx.send(Translator.translate('TODO_EXPORTED', ctx))
            except Forbidden:
                await ctx.send(
                    Translator.translate('TODO_EXPORT_CLOSED_DM',
                                         ctx,
                                         author=ctx.author.mention))
Пример #5
0
    async def serverinfo(self, ctx, server_id: Union[discord.Guild, int] = None):
        """SERVERINFO_HELP"""
        if server_id is None:
            guild = ctx.guild
        else:
            guild = self.bot.get_guild(server_id)

        if guild is None:
            return await ctx.send(Translator.translate('SERVERINFO_NOT_FOUND', ctx, id=str(server_id)))

        guild_features = "\n".join(guild.features) if len(guild.features) > 0 else None
        guild_emojis = " ".join(walk_emojis(guild.emojis))

        embed = DefraEmbed(title=f"{guild.name}")
        embed.set_thumbnail(url=guild.icon_url)
        embed.add_field(name="**ID**", value=str(guild.id), inline=False)
        embed.add_field(name=Translator.translate("SERVERINFO_OWNER", ctx), value=str(guild.owner), inline=False)
        embed.add_field(name=Translator.translate("SERVERINFO_MEMBERS", ctx), value=str(guild.member_count), inline=False)

        if guild_features is not None:
            embed.add_field(name=Translator.translate("SERVERINFO_FEATURES", ctx), value=guild_features, inline=False)

        embed.add_field(name=Translator.translate("SERVERINFO_EMOJILIST", ctx), value=guild_emojis[0:1000], inline=False)

        await ctx.send(embed=embed)
Пример #6
0
    async def mod_roles_remove(self, ctx, roles: commands.Greedy[int] = None):
        """MOD_ROLES_REMOVE_HELP"""
        if roles is None:
            return await ctx.send(embed=error_embed(
                text=None,
                title=Translator.translate('CONFIG_MOD_ROLES_EMPTY_ARGUMENT',
                                           ctx.guild.id)))

        # Iterate through provided list of roles
        for role_id in roles:
            # Check if role_id is already a mod role
            if role_id not in self.bot.cache.guilds.get(
                    ctx.guild.id).mod_roles:
                return await ctx.send(
                    embed=error_embed(text=None,
                                      title=Translator.translate(
                                          'CONFIG_MOD_ROLES_REMOVE_BAD_ROLE',
                                          ctx,
                                          role_id=role_id)))

            # Delete the role
            await self.bot.db.roles.remove(TableRolesTypes.mod_roles,
                                           ctx.guild.id, role_id)

        await self.bot.cache.refresh(ctx.guild.id)
        await ctx.send(embed=DefraEmbed(
            title=Translator.translate('CONFIG_MOD_ROLES_REMOVED',
                                       ctx.guild.id),
            description='\n'.join([
                str(
                    ctx.guild.get_role(role_id).mention if ctx.guild.
                    get_role(role_id) is not None else role_id)
                for role_id in roles
            ])))
Пример #7
0
    async def send_archive(bot, ctx: Context, messages: List[Message],
                           archived_channel: TextChannel):
        file_bytes = await Messages.archive_messages(bot, messages)
        filename = f"Archive for {archived_channel.name}.txt"

        try:
            file_bytes.seek(0)
            await ctx.author.send(file=File(file_bytes, filename=filename))
            await ctx.send(Translator.translate('ARCHIVE_SENT', ctx))
        except Forbidden:
            file_bytes.seek(0)
            await ctx.send(
                Translator.translate('ARCHIVE_WARNING_CLOSED_DMS',
                                     ctx,
                                     author=ctx.author.mention))

            try:

                def check(m):
                    return m.author == ctx.author and any(
                        ext.lower() in m.content.lower()
                        for ext in ['yes', 'no'])

                msg = await bot.wait_for('message', check=check, timeout=60.0)
            except asyncio.TimeoutError:
                await ctx.send(Translator.translate('ARCHIVE_TOO_SLOW', ctx))
            else:
                if 'yes' in msg.content.lower():
                    await ctx.send(file=File(file_bytes, filename=filename))
                else:
                    await ctx.send(
                        Translator.translate('ARCHIVE_CANCELLED', ctx))
Пример #8
0
 async def todo(self, ctx):
     """TODO_HELP"""
     if ctx.invoked_subcommand is None:
         await ctx.send(embed=warn_embed(
             title=Translator.translate("EMBED_NO_SUBCOMMAND_TITLE", ctx),
             text=Translator.translate(
                 "EMBED_NO_SUBCOMMAND_DESCRIPTION",
                 ctx,
                 help=f"{ctx.prefix}help {ctx.command.qualified_name}")))
Пример #9
0
 async def about(self, ctx):
     """ABOUT_TITLE"""
     e = DefraEmbed(
         title=Translator.translate("ABOUT_TITLE", ctx),
         footer_text=Translator.translate("ABOUT_FOOTER", ctx, user=ctx.author),
         footer_icon_url=ctx.author.avatar_url,
         description=Translator.translate('ABOUT_DESCRIPTION', ctx, owner=self.bot.owner, lib_version=f"discord.py {discord.__version__}")
     )
     e.set_thumbnail(url=self.bot.user.avatar_url_as(format="png"))
     await ctx.send(embed=e)
Пример #10
0
    async def what_prefix(self, ctx):
        """WHATPREFIX_HELP"""
        if ctx.guild is None:
            return await ctx.send(
                Translator.translate('WHATPREFIX',
                                     ctx,
                                     prefix=self.bot.cfg['DEFAULT_PREFIX']))

        prefix = self.bot.cache.guilds.get(
            ctx.guild.id).prefix or self.bot.cfg['DEFAULT_PREFIX']
        await ctx.send(Translator.translate('WHATPREFIX', ctx, prefix=prefix))
Пример #11
0
    async def mod_roles_reset(self, ctx):
        """MOD_ROLES_RESET_HELP"""
        if len(self.bot.cache.guilds.get(ctx.guild.id).mod_roles) <= 0:
            return await ctx.send(Translator.translate('MOD_ROLES_RESET_FAIL'),
                                  ctx)

        await self.bot.db.roles.set(TableRolesTypes.mod_roles, ctx.guild.id,
                                    [])
        await self.bot.cache.refresh(ctx.guild.id)

        await ctx.send(Translator.translate('MOD_ROLES_RESET_SUCCESS', ctx))
Пример #12
0
    async def translate(self, ctx, translate_from, translate_to, *, text: str):
        """TRANSLATE_HELP"""
        await ctx.trigger_typing()

        data = await self.bot.apis.yandex_translate(text=text, tr_to=translate_to, tr_from=translate_from)
        if data['code'] != 200:
            await ctx.send(embed=error_embed(title=Translator.translate('YANDEX_TRANSLATE_FAILED', ctx), text=data['message']))
        elif data['code'] == 200:
            e = DefraEmbed()
            e.description = data['text'][0]
            e.set_footer(text=Translator.translate('YANDEX_TRANSLATE_NOTICE', ctx), icon_url="https://translate.yandex.ru/icons/favicon.png")

            await ctx.send(embed=e)
Пример #13
0
    async def avatar(self, ctx, user: Union[discord.Member, SmartUser] = None):
        """AVATAR_HELP"""
        user = user or ctx.author

        avatar_url = user.avatar_url_as(static_format="png")

        embed = DefraEmbed(
            title=Translator.translate("AVATAR_TITLE", ctx, user=user),
            description=Translator.translate("AVATAR_DESCRIPTION", ctx, url=avatar_url)
        )
        embed.set_image(url=avatar_url)

        await ctx.send(embed=embed)
Пример #14
0
    async def purge(self, ctx):
        """TODO_PURGE_HELP"""
        await ctx.trigger_typing()

        async with (await self.bot.db.get_pool()).acquire() as conn:
            async with conn.transaction():
                resp = await conn.fetchval(
                    "DELETE FROM bot.todos WHERE user_id = $1 RETURNING True",
                    ctx.author.id)

        if resp is True:
            await ctx.send(Translator.translate("TODO_PURGE_DONE", ctx))
        else:
            await ctx.send(Translator.translate("TODO_PURGE_EMPTY_LIST", ctx))
Пример #15
0
    async def on_mod_logging_messages(self,
                                      payload: Union[RawMessageUpdateEvent,
                                                     RawMessageDeleteEvent],
                                      message_log_type: MessageLogType):
        if message_log_type is MessageLogType.deleted_message:
            destinations = await self.get_destinations(payload.guild_id,
                                                       ModLoggingType.messages)
            guild_tz = self.bot.cache.guilds.get(payload.guild_id).timezone

            time_fmt = datetime.now().astimezone(
                timezone(guild_tz)).strftime("%H:%M:%S")

            if (cached_message := payload.cached_message) is None:
                message = await self.bot.db.fetchrow(
                    "SELECT * FROM bot.messages WHERE guild_id = $1 AND message_id = $2",
                    payload.guild_id, payload.message_id)

                if message is not None:
                    content = self.bot.cryptor.decrypt(message['content'])
                    content_fmt = utils.escape_mentions(
                        utils.escape_markdown(
                            content.decode(encoding='utf-8')))
                    author = self.bot.get_user(message['author_id'])
                    c = self.bot.get_channel(message['channel_id'])

                    for channel in destinations:
                        await channel.send(
                            Translator.translate('MOD_LOGS_MESSAGE_DELETED',
                                                 payload.guild_id,
                                                 user=str(author),
                                                 time=time_fmt,
                                                 user_id=str(
                                                     message['author_id']),
                                                 content=content_fmt,
                                                 channel=c.mention))

            elif cached_message is not None:
                content_fmt = utils.escape_mentions(
                    utils.escape_markdown(cached_message.content))

                for channel in destinations:
                    await channel.send(
                        Translator.translate(
                            'MOD_LOGS_MESSAGE_DELETED',
                            cached_message.guild.id,
                            user=str(cached_message.author),
                            time=time_fmt,
                            user_id=str(cached_message.author.id),
                            content=content_fmt,
                            channel=cached_message.channel.mention))
Пример #16
0
    async def prefix(self, ctx: commands.Context, new_prefix=None):
        """CONFIG_PREFIX_HELP"""
        if new_prefix is None:
            return await ctx.send(Translator.translate("CONFIG_PREFIX_NO_NEW"))

        await self.bot.db.prefixes.set(ctx.guild.id, new_prefix)
        await self.bot.cache.refresh(ctx.guild.id)

        if self.bot.cache.guilds.get(ctx.guild.id).prefix == new_prefix:
            await ctx.send(
                Translator.translate("CONFIG_PREFIX_UPDATED",
                                     ctx,
                                     prefix=new_prefix))
        else:
            await ctx.send(Translator.translate("CONFIG_UPDATE_ERROR", ctx))
Пример #17
0
    async def add(self, ctx, *, task: str = None):
        """TODO_ADD_HELP"""
        await ctx.trigger_typing()

        if task is None:
            return await ctx.send(embed=warn_embed(
                title=Translator.translate("TODO_MISSING_ARG", ctx), text=""))

        async with (await self.bot.db.get_pool()).acquire() as conn:
            async with conn.transaction():
                resp = await conn.fetchval(
                    "INSERT INTO bot.todos (user_id, content) VALUES($1, $2) RETURNING True",
                    ctx.author.id, task)

        if resp is True:
            await ctx.send(Translator.translate("TODO_ADDED", ctx))
Пример #18
0
 async def hug(self, ctx, target: Member):
     """HUG_HELP"""
     await ctx.send(
         Translator.translate("HUG_MESSAGE_1",
                              ctx,
                              target=target.mention,
                              author=str(ctx.author)))
Пример #19
0
 async def config(self, ctx: commands.Context):
     """CONFIG_HELP"""
     if ctx.invoked_subcommand is None:
         await ctx.send(
             Translator.translate(
                 "NO_SUBCOMMAND",
                 ctx,
                 help=
                 f"{ctx.prefix}help {ctx.command} {ctx.command.signature}"))
Пример #20
0
    async def fox(self, ctx):
        """FOX_HELP"""
        await ctx.trigger_typing()
        some_cat = await self.bot.apis.get_fox()

        embed = DefraEmbed(
            title=":fox: {0}".format(Translator.translate("THIS_FOX", ctx)))
        embed.set_image(url=some_cat)

        await ctx.send(embed=embed)
Пример #21
0
    async def log_messages(self, ctx, mode: bool = None):
        """CONFIG_LOG_MESSAGES_HELP"""
        if mode is None:
            return await ctx.send(
                Translator.translate('CONFIG_LOG_MESSAGES_CURRENT_MOD',
                                     ctx,
                                     mode=self.bot.cache.guilds.get(
                                         ctx.guild.id).log_messages))

        await self.bot.db.execute(
            "UPDATE bot.guilds SET log_messages = $2 WHERE guild_id = $1;",
            ctx.guild.id, mode)
        await self.bot.cache.refresh(ctx.guild.id)

        await ctx.send(
            Translator.translate('CONFIG_LOG_MESSAGES_UPDATED',
                                 ctx,
                                 mode=self.bot.cache.guilds.get(
                                     ctx.guild.id).log_messages))
Пример #22
0
    async def cat(self, ctx):
        """CAT_HELP"""
        await ctx.trigger_typing()
        some_cat = await self.bot.apis.get_cat(self.bot.cfg['API_KEYS']['CATS']
                                               )

        embed = DefraEmbed(
            title=":cat: {0}".format(Translator.translate("THIS_CAT", ctx)))
        embed.set_image(url=some_cat)

        await ctx.send(embed=embed)
Пример #23
0
 async def mod_roles(self, ctx):
     """MOD_ROLES_HELP"""
     if ctx.invoked_subcommand is None:
         e = DefraEmbed(title=Translator.translate(
             'CONFIG_MOD_ROLES_CURRENT', ctx.guild.id),
                        description='\n'.join([
                            f'{role.mention} (`{role.id}`)' if
                            (role := ctx.guild.get_role(role_id))
                            is not None else f"`{role_id}`"
                            for role_id in self.bot.cache.guilds.get(
                                ctx.guild.id).mod_roles
                        ]))
Пример #24
0
    async def mod_roles_add(self, ctx, roles: commands.Greedy[int] = None):
        """MOD_ROLES_ADD_HELP"""
        if roles is None:
            return await ctx.send(embed=error_embed(
                text=None,
                title=Translator.translate('CONFIG_MOD_ROLES_EMPTY_ARGUMENT',
                                           ctx.guild.id)))

        # Filtering out non-existing roles and deleting duplicates
        roles = [
            ctx.guild.get_role(role) for role in set(
                filter(
                    lambda _id: True
                    if ctx.guild.get_role(_id) is not None else False, roles))
        ]

        if len(roles) <= 0:
            return await ctx.send(embed=error_embed(
                text=None,
                title=Translator.translate('CONFIG_MOD_ROLES_NONE_ADDED',
                                           ctx.guild.id)))

        # Adding each role id into the database
        for role in roles:
            if role.id not in self.bot.cache.guilds.get(
                    ctx.guild.id).mod_roles:
                await self.bot.db.roles.add(TableRolesTypes.mod_roles,
                                            ctx.guild.id, role.id)
            else:
                return await ctx.send(
                    embed=error_embed(title=Translator.translate(
                        'NOTHING_CHANGED', ctx.guild.id),
                                      text=None))

        await self.bot.cache.refresh(ctx.guild.id)
        await ctx.send(embed=DefraEmbed(
            title=Translator.translate('CONFIG_MOD_ROLES_ADDED', ctx.guild.id),
            description='\n'.join(
                [f"{role.mention} (`{role.id}`)" for role in roles])))
Пример #25
0
    async def shpaklevka(self, ctx, *, body: str):
        msg = await ctx.send("Your meme is being generated")

        if len(body) > 90:
            return await msg.edit(
                content=Translator.translate("CONTENT_LENGTH_90_MAX", ctx))

        fn = partial(self.generate_meme, "shpaklevka", body)
        meme = await self.bot.loop.run_in_executor(None, fn)
        file = discord.File(fp=meme, filename="shpaklevka.jpg")

        await ctx.send(file=file, content=f"{ctx.author.mention}")
        return await msg.delete()
Пример #26
0
    async def list(self, ctx):
        """TODO_LIST_HELP"""
        await ctx.trigger_typing()

        async with (await self.bot.db.get_pool()).acquire() as db:
            current_todos = await db.fetch(
                "SELECT * FROM bot.todos WHERE user_id = $1 ORDER BY timestamp DESC LIMIT 200;",
                ctx.author.id)

        if len(current_todos) <= 0:
            await ctx.send(Translator.translate("TODOS_EMPTY", ctx))
        else:
            entries = []
            for index, todo in enumerate(current_todos):
                entries.append(f"`{index + 1}` {todo['content']}")

            source = TodosSource(entries,
                                 title=Translator.translate("TODOS_LIST_TITLE",
                                                            ctx,
                                                            user=ctx.author))
            menu = MyPagesMenu(source, delete_message_after=True)
            await menu.start(ctx)
Пример #27
0
    async def timezone(self, ctx, new_timezone=None):
        """CONFIG_TIMEZONE_HELP"""
        if new_timezone is None:
            current_tz = self.bot.cache.guilds.get(ctx.guild.id).timezone
            return await ctx.send(
                Translator.translate("CONFIG_TIMEZONE_CURRENT",
                                     ctx,
                                     current=current_tz))

        if is_timezone(new_timezone) is False:
            return await ctx.send(
                Translator.translate("CONFIG_TIMEZONE_BAD_TIMEZONE", ctx))

        await self.bot.db.timezones.set(ctx.guild.id, new_timezone)
        await self.bot.cache.refresh(ctx.guild.id)

        if self.bot.cache.guilds.get(ctx.guild.id).timezone == new_timezone:
            await ctx.send(
                Translator.translate("CONFIG_TIMEZONE_UPDATED",
                                     ctx,
                                     timezone=new_timezone))
        else:
            await ctx.send(Translator.translate("CONFIG_UPDATE_ERROR", ctx))
Пример #28
0
    async def logging_reset(self,
                            ctx,
                            channel: Union[TextChannel, int] = None):
        """CONFIG_LOGGING_RESET_HELP"""
        if channel is None:
            return await ctx.send(
                Translator.translate('CONFIG_LOGGING_RESET_CHANNEL_IS_NONE',
                                     ctx))

        for logging_type in ModLoggingType:
            if isinstance(channel, TextChannel):
                await self.bot.db.logging.remove(logging_type, ctx.guild.id,
                                                 channel.id)
            elif isinstance(channel, int):
                await self.bot.db.logging.remove(logging_type, ctx.guild.id,
                                                 channel)

        await self.bot.cache.refresh(ctx.guild.id)
        await ctx.send(
            Translator.translate('CONFIG_LOGGING_RESET',
                                 ctx,
                                 channel=f"{channel.mention}" if isinstance(
                                     channel, TextChannel) else f"{channel}"))
Пример #29
0
    async def remove(self, ctx, todo_id):
        """TODO_REMOVE_HELP"""
        await ctx.trigger_typing()

        if not todo_id.isdigit():
            return await ctx.send(Translator.translate("TODO_MUST_BE_INT",
                                                       ctx))

        todo_id = int(todo_id)
        target_todo = None

        async with (await self.bot.db.get_pool()).acquire() as conn:
            todos = await conn.fetch(
                "SELECT * FROM bot.todos WHERE user_id = $1 ORDER BY timestamp DESC LIMIT 200;",
                ctx.author.id)

        for index, todo in enumerate(todos):
            if index + 1 == todo_id:
                target_todo = todo

        if target_todo is None:
            await ctx.send(embed=warn_embed(
                title=Translator.translate('TODO_NOT_EXISTING', ctx)))
        else:
            async with (await self.bot.db.get_pool()).acquire() as conn:
                async with conn.transaction():
                    params = (target_todo.get('timestamp'),
                              target_todo.get('user_id'))
                    is_deleted = await conn.fetchval(
                        "DELETE FROM bot.todos WHERE timestamp = $1 AND user_id = $2 RETURNING True",
                        *params)

            if is_deleted:
                await ctx.send(embed=DefraEmbed(
                    description=Translator.translate(
                        'TODO_REMOVED', ctx, todo=target_todo.get('content'))))
Пример #30
0
    async def logging(self, ctx):
        """CONFIG_LOGGING_HELP"""
        if ctx.invoked_subcommand is None:
            logging_settings = self.bot.cache.guilds.get(ctx.guild.id).logging
            embed = DefraEmbed(title=Translator.translate(
                'LOGGING_CURRENT_TITLE', ctx, servername=ctx.guild.name))

            for modlog_type in ModLoggingType:
                channel_ids = [
                    channel_id for channel_id in getattr(
                        logging_settings, modlog_type.value)
                ]
                channels_fmt = "\n".join([
                    f"{channel.mention}" if
                    (channel := self.bot.get_channel(channel_id)) else
                    f"~~`{channel_id}`~~" for channel_id in channel_ids
                ])