Beispiel #1
0
    async def on_message_edit(self, ctx_before, ctx_after):
        if not ctx_before.author.bot:
            logs_channel = self.get_channel(settings.LOG_ROOMS['messages'])

            embed = discord.Embed()
            embed.colour = discord.Color.from_rgb(245, 124, 110)

            embed.set_author(name=tr('Bot.Edited', ctx_before),
                             icon_url=ctx_before.author.avatar_url)

            if not isinstance(ctx_before.channel, discord.channel.DMChannel):
                channel = ctx_before.channel.mention
            else:
                channel = ctx_before.author.mention

            embed.description = tr(
                'Bot.EventOccurredIn',
                ctx=ctx_before,
                author=ctx_before.author.mention,
                guild=ctx_before.guild.name
                if ctx_before.guild else ctx_before.author.mention,
                channel=channel)

            embed.add_field(name=tr('Before', ctx_before),
                            value=ctx_before.content,
                            inline=False)
            embed.add_field(name=tr('After', ctx_after),
                            value=ctx_after.content,
                            inline=False)

            await logs_channel.send(embed=embed)
Beispiel #2
0
    async def blend_images(self, ctx, template, bg_size, bg_coord):
        """
        Old function. Will be replaced.
        Blend two images
        Args:
            ctx (common.Message): context
            template (str): template image key
            bg_size (int): background size
            bg_coord (int): background coordinates
        """
        # Replace it by async request
        response = requests.get(await self.get_image(ctx))
        foreground = os.path.join(self._images_folder, template)
        foreground = Image.open(foreground)
        background = Image.open(BytesIO(response.content))

        if 3000 in background.size:
            await ctx.send(
                tr('Cogs.Fun.Fun.ImageSizeError',
                   ctx,
                   w=background.size[0],
                   h=background.size[1]))
        else:
            filepath = f'{self._temp_images_folder}/{template}'
            background = background.resize(bg_size)
            blended = Image.new('RGBA', foreground.size)
            blended.paste(background, bg_coord)
            blended.paste(foreground, (0, 0), foreground)
            blended.save(filepath, 'PNG')

            await ctx.send(file=discord.File(filepath))
            os.remove(filepath)
Beispiel #3
0
    async def reload_module(self, ctx, *cogs):
        # "prefix *"             - each module
        # "prefix Module.module" - specific one
        # TODO: add folder (group) reboot: "?rm tools (will reboot each module)"
        if not cogs:
            cogs = settings.COGS
        else:
            cogs = [f'cogs.{i}' for i in cogs]

        # First, we need to reload localization files
        Locales.load_aliases(cogs)
        Locales.load_translations(module_paths=cogs)
        await ctx.send(
            tr('Cogs.Tools.Bot.UpdatedLocalizationFiles', ctx, 'bookmark', 1))

        message = ''
        for cog in cogs:
            if cog in self.bot.extensions:
                try:
                    self.bot.reload_extension(cog)
                    message += f"{tr('Cogs.Tools.Bot.ModuleWasRebooted', ctx, 'wrench', 1, module=cog)}\n"
                except ExtensionError:
                    message += f"{tr('Cogs.Tools.Bot.FailedToRebootModule', ctx, 'fire', 1, module=cog)}\n"
            else:
                message += f"{tr('Cogs.Tools.Bot.ModuleNotFound', ctx, 'warning', 1, module=cog)}\n"

        await ctx.send(message)
Beispiel #4
0
    async def set_guild_prefix(self, ctx, prefix):
        # if prefix is a word then add space
        if not re.match(r'[@_!#$%^&*()<>?/\|}{~:]', prefix):
            prefix += ' '

        Guilds.update_guild(ctx.message.guild.id, prefix=prefix)
        await ctx.send(
            tr('Cogs.Tools.Admin.PrefixHasBeenSet', ctx, prefix=prefix))
Beispiel #5
0
 async def guild_info(self, ctx):
     info = Guilds.get_guild_info(ctx.message.guild.id)
     embed = discord.Embed()
     embed.title = tr('Guild info', ctx)
     embed.description = (
         f'\n• {tr("Locale", ctx)}: {info.get("locale")}'
         f'\n\n• {tr("Prefix", ctx)}: {info.get("prefix")}')
     await ctx.send(embed=embed)
Beispiel #6
0
 async def restart(self, ctx):
     embed = discord.Embed(
         title=tr('Cogs.Tools.Bot.RebootNotification',
                  ctx=ctx,
                  emoji='gear'),
         color=discord.Color.from_rgb(255, 188, 64),
     )
     subprocess.call([sys.executable, 'Bot/bot.py'])
     await ctx.send(embed=embed)
Beispiel #7
0
    async def set_guild_locale(self, ctx, locale: str = None):
        """
        Set guild locale
        Args:
            ctx (common.Message): context
            locale (str): locale key code in lower case
        """
        locale = locale.lower()
        if re.match(r'[a-z\-A-Z]{5}', locale):
            if locale == Guilds.get_guild_info(ctx.message.guild.id, 'locale'):
                await ctx.send(tr('Cogs.Tools.Admin.SameLocale', ctx))
            else:
                Guilds.update_guild(ctx.message.guild.id, locale=locale)
                Locales.load_translations(locale)

                await ctx.send(
                    tr('Cogs.Tools.Admin.LocaleHasBeenSet', ctx,
                       locale=locale))
        else:
            await ctx.send(tr('Cogs.Tools.Admin.LocaleFormatIsIncorrect', ctx))
Beispiel #8
0
    async def text_to_speech_list(self, ctx, section: str):
        lines = await AudioConverter.get_alphabet(section)
        lines = '"{}"'.format('", "'.join(lines.keys()))

        embed = discord.Embed()
        embed.set_author(name=tr('Cogs.Fun.TextToSpeechList', ctx))
        await ctx.author.send(embed=embed)

        for line in textwrap.wrap(lines, 500):
            # await ctx.author.send(line)
            embed.add_field(name='================', value=line)
            await ctx.author.send(embed=embed)
Beispiel #9
0
    async def on_command_error(self, ctx, error):
        logs_channel = self.get_channel(settings.LOG_ROOMS['errors'])
        message = tr('Error', ctx)

        if isinstance(error, commands.CommandOnCooldown):
            member = ctx.message.author.mention
            message = tr('Bot.PleaseWait', ctx, member=member)

        elif isinstance(error, commands.UserInputError):
            message = tr('Bot.InvalidInput', ctx, arg=ctx.command)

        elif isinstance(error, commands.BadArgument):
            message = tr('Bot.BadCommandArgument', arg=ctx.command.content)

        elif isinstance(error, commands.CommandNotFound):
            message = tr('Bot.CommandNotFound', ctx, arg=ctx.message.content)

        elif isinstance(error, commands.CommandInvokeError):
            message = f'{tr("Bot.CommandInvokeError", ctx)}: {error.original}'

        elif isinstance(error, UnboundLocalError):
            message = f'{tr("Bot.LocalError", ctx)}: {error}'

        title = tr('Error', ctx)
        embed_logs = discord.Embed()
        embed_logs.set_author(name=title,
                              icon_url=ctx.message.author.avatar_url)
        embed_logs.colour = discord.Color.from_rgb(252, 197, 114)
        channel = ctx.guild.id if ctx.guild else 'DM'
        embed_logs.description = f'{ctx.message.author.mention} in {channel}\n{message}'
        embed_logs.set_footer(text=f'{datetime.fromtimestamp(time.time())}')

        await ctx.send(message)
        await logs_channel.send(embed=embed_logs)
Beispiel #10
0
    async def on_message(self, ctx: discord.Message):
        """
        (AVATAR) [Type of event]
        User sent message in <#channel.mention>
        [Content title]
        Content
        [If File title]
        File URL
        """

        if not ctx.author.bot:
            logs_channel = self.get_channel(settings.LOG_ROOMS['messages'])

            embed = discord.Embed()
            embed.colour = discord.Color.from_rgb(110, 162, 245)

            embed.set_author(name=tr('Bot.Message', ctx),
                             icon_url=ctx.author.avatar_url)

            embed.description = tr(
                'Bot.EventOccurredIn',
                ctx=ctx,
                author=ctx.author.mention,
                guild=ctx.guild.name if ctx.guild else ctx.author.mention,
                channel=ctx.channel.mention
                if not isinstance(ctx.channel, discord.channel.DMChannel) else
                ctx.author.mention)

            if ctx.content:
                embed.add_field(name=tr('Bot.Message', ctx),
                                value=ctx.content,
                                inline=False)
            if ctx.attachments:
                embed.add_field(name=tr('Bot.File', ctx),
                                value=ctx.attachments[0].proxy_url,
                                inline=False)

            await logs_channel.send(embed=embed)
            await self.process_commands(ctx)
Beispiel #11
0
    async def info(self, ctx):
        embed = discord.Embed()
        embed.colour = discord.Color.from_rgb(178, 66, 219)

        uname = platform.uname()
        embed.description = f'''
            • :snake: Python - {sys.version.split()[0]}
            • :space_invader: Discord API - {discord.__version__}
            • :pager: {uname.system}
            • :computer: {uname.machine}
            • :bulb: {uname.processor}
        '''
        embed.set_author(name=tr('Cogs.Tools.Bot.BotInfoTitle', ctx),
                         icon_url=self.bot.get_user(
                             self.bot.user.id).avatar_url)
        await ctx.send(embed=embed)
Beispiel #12
0
    async def set_presence(self, ctx, presence: int = None):
        presences = (
            ('online', (157, 245, 110)),  # online/green
            ('idle', (252, 219, 3)),  # idle/orange
            ('dnd', (219, 66, 74)),  # dnd/red
            ('offline', (158, 158, 158)),  # offline/white
            ('invisible', (158, 158, 158)),  # invisible/white
        )

        embed = discord.Embed()
        embed.title = tr('Cogs.Tools.Bot.StatusHasBeenSet',
                         ctx,
                         status_name=presences[presence][0])
        embed.colour = discord.Color.from_rgb(*presences[presence][1])

        await ctx.send(embed=embed)
        await set_presence(self.bot, presence=presence)
Beispiel #13
0
    async def text_to_speech(self, ctx, section: str, *text: str):
        """
        Text to speech command.
        Example:
            pls <section; f.e: vox> <file1> <file2>
        Or if files contains more than one word:
            pls <section; f.e: kingpin> <file name 1>, <file name 2>
        """
        text = str(' '.join(text))
        text = text.split(',') if ',' in text else text.split(' ')

        result = await AudioConverter.text_to_speech(section, *text)
        if result:
            await ctx.send(ctx.message.author.mention,
                           file=discord.File(result.get('output')))
            os.remove(result.get('output'))
        else:
            await ctx.send(tr('Cogs.Fun.WrongCategory', ctx))
Beispiel #14
0
    async def magic(self, ctx, scale=3):
        if scale > 10:
            scale = 3
            await ctx.send(tr('The scale argument can\'t be more than 10',
                              ctx))

        image_path = self.save_image(await self.get_image(ctx))
        image = WImage(filename=image_path)

        image.liquid_rescale(width=int(image.width * 0.5),
                             height=int(image.height * 0.5),
                             delta_x=int(0.5 * scale) if scale else 1,
                             rigidity=0)

        image.liquid_rescale(width=int(image.width * 1.5),
                             height=int(image.height * 1.5),
                             delta_x=scale if scale else 2,
                             rigidity=0)
        image.save(filename=image_path)

        await ctx.send(file=discord.File(image_path))
        os.remove(image_path)
Beispiel #15
0
 def add_aliases_formatting(self, aliases):
     self.paginator.add_line(
         '**{}**: {}'.format(tr('Bot.AliasHeading', self.context), ', '.join(aliases)), empty=True
     )
Beispiel #16
0
    async def impact_meme(self, ctx, *string):
        # Forked from: https://github.com/Littlemansmg/Discord-Meme-Generator
        image_path = self.save_image(await self.get_image(ctx))
        font_path = f'{self._resources}/Fonts/impact.ttf'

        if string:
            string_size = len(string) // 2
            top_string = ' '.join(string[:string_size])
            bottom_string = ' '.join(string[string_size:])

            with Image.open(image_path) as image:
                size = image.size
                font_size = int(size[1] / 5)
                font = ImageFont.truetype(font_path, font_size)
                edit = ImageDraw.Draw(image)

                # find biggest font size that works

                top_text_size = font.getsize(top_string)
                bottom_text_size = font.getsize(bottom_string)

                while top_text_size[0] > size[0] - 20 or bottom_text_size[
                        0] > size[0] - 20:
                    font_size = font_size - 1
                    # fix it
                    font = ImageFont.truetype(font_path, font_size)
                    top_text_size = font.getsize(top_string)
                    bottom_text_size = font.getsize(bottom_string)

                # find top centered position for top text
                top_text_posx = (size[0] / 2) - (top_text_size[0] / 2)
                top_text_posy = 0
                top_text_pos = (top_text_posx, top_text_posy)

                # find bottom centered position for bottom text
                bottom_text_posx = (size[0] / 2) - (bottom_text_size[0] / 2)
                bottom_text_posy = size[1] - bottom_text_size[1] - 10
                bottom_text_pos = (bottom_text_posx, bottom_text_posy)

                # draw outlines
                # there may be a better way
                outline_range = int(font_size / 15)
                for x in range(-outline_range, outline_range + 1):
                    for y in range(-outline_range, outline_range + 1):
                        edit.text((top_text_pos[0] + x, top_text_pos[1] + y),
                                  top_string, (0, 0, 0),
                                  font=font)
                        edit.text(
                            (bottom_text_pos[0] + x, bottom_text_pos[1] + y),
                            bottom_string, (0, 0, 0),
                            font=font)

                edit.text(top_text_pos, top_string, (255, 255, 255), font=font)
                edit.text(bottom_text_pos,
                          bottom_string, (255, 255, 255),
                          font=font)
                image.save(image_path, 'PNG')

            await ctx.send(file=discord.File(image_path))
            os.remove(image_path)
        else:
            await ctx.send(tr('Cogs.Fun.Fun.ImpactMemeEmptyString', ctx))
Beispiel #17
0
 async def reload_translations(self, ctx):
     Locales.load_aliases()
     Locales.load_translations()
     await ctx.send(
         tr('Cogs.Tools.Bot.UpdatedLocalizationFiles', ctx, 'bookmark', 1))
Beispiel #18
0
 async def restart_error(self, ctx, error):
     if isinstance(error, commands.NotOwner):
         await ctx.send(
             tr('Cogs.Tools.Admin.AccessDenied', ctx=ctx, emoji='alien'))
Beispiel #19
0
    async def reload_module_error(self, ctx, error):
        if isinstance(error, commands.NotOwner):
            await ctx.send(tr('Cogs.Tools.Admin.AccessDenied', ctx))

        if isinstance(error, commands.BadArgument):
            await ctx.send('Invalid argument')