Exemplo n.º 1
0
    async def charinfo(self, ctx: Context, *, characters: str) -> None:
        """Shows you information about up to 50 unicode characters."""
        match = re.match(r"<(a?):(\w+):(\d+)>", characters)
        if match:
            raise BadArgument(
                "Only unicode characters can be processed, but a custom Discord emoji "
                "was found. Please remove it and try again.",
            )
        if len(characters) > 50:
            raise BadArgument(f"Too many characters ({len(characters)}/50)")

        def get_info(char: str) -> Tuple[str, str]:
            digit = f"{ord(char):x}"
            if len(digit) <= 4:
                u_code = f"\\u{digit:>04}"
            else:
                u_code = f"\\U{digit:>08}"
            url = f"https://www.compart.com/en/unicode/U+{digit:>04}"
            name = f"[{unicodedata.name(char, '')}]({url})"
            info = f"`{u_code.ljust(10)}`: {name} - {utils.escape_markdown(char)}"
            return info, u_code

        char_list, raw_list = zip(*(get_info(c) for c in characters))
        embed = Embed(title="Character info", colour=Colours.green)

        if len(characters) > 1:
            # Maximum length possible is 502 out of 1024, so there's no need to truncate.
            embed.add_field(
                name="Full Raw Text", value=f"`{''.join(raw_list)}`", inline=False
            )

        await LinePaginator.paginate(
            char_list, ctx, embed, max_lines=10, max_size=2000, empty=False
        )
Exemplo n.º 2
0
 def slow(self, streamer: Streamer, info, mod_action: ModAction,
          embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_chatroom_attrs(mod_action, embed)
     embed.add_field(
         name=
         f"Slow Amount (second{'' if int(info['args'][0]) == 1 else 's'})",
         value=f"`{info['args'][0]}`",
         inline=True)
     return embed
Exemplo n.º 3
0
 def followers(self, streamer: Streamer, info, mod_action: ModAction,
               embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_chatroom_attrs(mod_action, embed)
     embed.add_field(
         name=
         f"Time Needed to be Following (minute{'' if int(info['args'][0]) == 1 else 's'})",
         value=f"`{info['args'][0]}`",
         inline=True)
     return embed
Exemplo n.º 4
0
 def raid(self, streamer: Streamer, info, mod_action: ModAction,
          embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_chatroom_attrs(mod_action, embed)
     embed.add_field(
         name="Raided Channel",
         value=
         f"[{info['args'][0]}](<https://www.twitch.tv/{info['args'][0]}>)",
         inline=True)
     return embed
Exemplo n.º 5
0
 def set_appeals_attrs(self, streamer: Streamer, info,
                       mod_action: ModAction,
                       embed: disnake.Embed) -> disnake.Embed:
     self.set_user_attrs(streamer, info, mod_action, embed)
     embed.add_field(
         name="Moderator Reason",
         value=
         f"`{info['moderator_message'] if info['moderator_message'] != '' else 'None Provided'}`",
         inline=False)
     return embed
Exemplo n.º 6
0
 def delete(self, streamer: Streamer, info, mod_action: ModAction,
            embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_user_attrs(streamer, info, mod_action, embed)
     if "`" in info['args'][1]:
         embed.add_field(name="Message", value=f"```{info['args'][1]}```")
     else:
         embed.add_field(name="Message", value=f"`{info['args'][1]}`")
     # embed.add_field(
     #     name="Message ID", value=f"`{info['args'][2]}`")
     return embed
Exemplo n.º 7
0
 def embed_helper(self, description: str, field: str) -> Embed:
     """Embed helper function."""
     embed = Embed(title="Eval Results",
                   colour=self.GREEN,
                   description=description)
     embed.add_field(
         name="Output",
         value=field,
     )
     return embed
Exemplo n.º 8
0
    async def get_commit_messages(self, event_body, brief=False):
        embed_commits = []
        branch = event_body['ref'].split('/', 2)[2]
        project = event_body['repository']['full_name']
        commits = event_body['commits']

        if brief and len(commits) > self.config['commit_truncation_limit']:
            first_hash = commits[0]['id']
            last_hash = commits[-2]['id']
            compare_url = f'https://github.com/{project}/compare/{first_hash}^...{last_hash}'
            embed = Embed(
                title=
                f'Skipped {len(commits) - 1} commits... (click link for diff)',
                colour=Colour(self._skipped_commit_colour),
                url=compare_url)
            embed_commits.append((embed, None))
            commits = commits[-1:]

        for commit in commits:
            author_username = commit['author'].get('username', None)
            author_name = commit['author'].get('name', None)
            timestamp = dateutil.parser.parse(commit['timestamp'])
            commit_message = commit['message'].split('\n')
            embed = Embed(title=commit_message[0],
                          colour=Colour(self._commit_colour),
                          url=commit['url'],
                          timestamp=timestamp)

            if len(commit_message) > 2 and not brief:
                commit_body = '\n'.join(commit_message[2:])
                embed.description = commit_body[:4096]

            author = await self.get_author_info(author_username)

            if author:
                if author['name'] and author['name'] != author['login']:
                    author_name = f'{author["name"]} ({author["login"]})'
                else:
                    author_name = author['login']

                embed.set_author(name=author_name,
                                 url=author['html_url'],
                                 icon_url=author['avatar_url'])
            elif author_name:
                embed.set_author(name=author_name)
            else:
                embed.set_author(name='<No Name>')

            embed.set_footer(text='Commit')
            embed.add_field(name='Repository', value=project, inline=True)
            embed.add_field(name='Branch', value=branch, inline=True)
            embed_commits.append((embed, commit['id']))

        return embed_commits
Exemplo n.º 9
0
 def set_user_attrs(self, streamer: Streamer, info, mod_action: ModAction,
                    embed: disnake.Embed) -> disnake.Embed:
     user = info["target_user_login"] or info['args'][0]
     user_escaped = user.lower().replace('_', '\_')
     embed.title = f"Mod {mod_action.value.replace('_', ' ').title()} Action"
     #embed.description=f"[Review Viewercard for User](<https://www.twitch.tv/popout/{streamer.username}/viewercard/{user.lower()}>)"
     embed.color = self.colour.red
     embed.add_field(
         name="Flagged Account",
         value=
         f"[{user_escaped}](<https://www.twitch.tv/popout/{streamer.username}/viewercard/{user_escaped}>)",
         inline=True)
     return embed
Exemplo n.º 10
0
    def automod_caught_message(self, streamer: Streamer, info,
                               mod_action: ModAction,
                               embed: disnake.Embed) -> disnake.Embed:
        ignore_message = False
        user = info["message"]["sender"]["login"]
        user_escaped = user.lower().replace('_', '\_')
        embed.title = f"{mod_action.value.replace('_', ' ').title()}"
        embed.color = self.colour.red
        embed.add_field(
            name="Flagged Account",
            value=
            f"[{user_escaped}](<https://www.twitch.tv/popout/{streamer.username}/viewercard/{user_escaped}>)",
            inline=True)
        embed.add_field(
            name="Content Classification",
            value=
            f"{info['content_classification']['category'].title()} level {info['content_classification']['level']}",
            inline=True)
        text_fragments = []
        topics = []
        for fragment in info["message"]["content"]["fragments"]:
            if fragment != {}:
                for topic in fragment.get("automod", {}).get("topics",
                                                             {}).keys():
                    if topic not in topics:
                        topics.append(topic.replace("_", " "))
                if fragment.get("text", None) is not None:
                    text_fragments.append(fragment.get("text", None))

        text_fragments = list(
            dict.fromkeys(text_fragments)
        )  #Remove duplicates from topics and text fragments, they're pointless
        topics = list(dict.fromkeys(topics))
        embed.add_field(
            name="Text fragments",
            value=
            f"`{', '.join([f.strip(' ') for f in text_fragments]).strip(', ')}`"
        )
        embed.add_field(name="Topics",
                        value=f"`{', '.join(topics).strip(', ')}`")
        if info["status"] == "PENDING":
            embed.colour = self.colour.yellow
            if "automod_caught_message" not in streamer.action_whitelist and streamer.action_whitelist != []:
                ignore_message = True
        elif info["status"] == "ALLOWED":
            if "automod_allowed_message" not in streamer.action_whitelist and streamer.action_whitelist != []:
                ignore_message = True
            embed.colour = self.colour.green
        elif info["status"] == "DENIED":
            if "automod_denied_message" not in streamer.action_whitelist and streamer.action_whitelist != []:
                ignore_message = True
            embed.colour = self.colour.red
        else:
            if "automod_caught_message" not in streamer.action_whitelist and streamer.action_whitelist != []:
                ignore_message = True
        if info["status"] != "PENDING":
            embed.title = embed.title.replace("Caught", info["status"].title())
        return ignore_message, embed
Exemplo n.º 11
0
    async def help(self, ctx: Context):
        # unfortunately the @check decorator doesn't really work for this use case.
        if not self.bot.is_admin(ctx.author):
            return
        is_private = self.bot.is_private(ctx.channel)

        embed = Embed(title='OBS Bot Help')
        for section, commands in self.help_sections.items():
            if section in self.restricted and not is_private:
                continue
            longest = max(len(cmd) for cmd, _ in commands)
            content = '\n'.join(f'{cmd.ljust(longest)} - {helptext}'
                                for cmd, helptext in commands)
            embed.add_field(name=section,
                            value=f'```{content}```',
                            inline=False)
        return await ctx.channel.send(embed=embed)
Exemplo n.º 12
0
    async def attempt_delivery(self, location, package):
        try:
            if location is None:
                return False

            tloc = None if isinstance(location, User) or isinstance(
                location, DMChannel) else location
            now = datetime.datetime.fromtimestamp(time.time())
            send_time = datetime.datetime.fromtimestamp(package.send)
            desc = Translator.translate(
                'reminder_delivery',
                tloc,
                date=send_time.strftime('%c'),
                timediff=server_info.time_difference(
                    now, send_time, tloc)) + f"```\n{package.to_remind}\n```"
            desc = Utils.trim_message(desc, 2048)
            embed = Embed(color=16698189,
                          title=Translator.translate('reminder_delivery_title',
                                                     tloc),
                          description=desc)
            if location.id == package.channel_id or package.guild_id == '@me':
                ref = MessageReference(guild_id=package.guild_id
                                       if package.guild_id != '@me' else None,
                                       channel_id=package.channel_id,
                                       message_id=package.message_id,
                                       fail_if_not_exists=False)
            else:
                ref = None
                embed.add_field(
                    name=Translator.translate('jump_link', tloc),
                    value=
                    f'[Click me!]({assemble_jumplink(package.guild_id, package.channel_id, package.message_id)})'
                )

            try:
                await location.send(embed=embed, reference=ref)
            except (Forbidden, NotFound):
                return False
            else:
                return True
        except Exception as ex:
            await TheRealGearBot.handle_exception("Reminder delivery",
                                                  self.bot, ex, None, None,
                                                  None, location, package)
            return False
Exemplo n.º 13
0
    async def on_button_click(self, interaction: MessageInteraction):
        if not interaction.data.custom_id.startswith('steamworks_'):
            return
        if not self.bot.is_contributor(interaction.author):
            return await interaction.response.send_message('You do not have permission to use this.', ephemeral=True)

        _, build_id, target_branch = interaction.data.custom_id.split('_')
        res = await self.set_build_live(build_id, target_branch, desc=f'Requested by {interaction.author}')
        if res['result'] != 1:
            embed = Embed(title='Build publishing failed.',
                          description=f'Failed to push build to "{target_branch}":\n'
                                      f'```\n{res["message"]}\n```')
            return await interaction.response.send_message(embed=embed)

        embed = interaction.message.embeds[0]
        embed.add_field(name='Published', value='Yes')
        await interaction.response.edit_message(embed=embed, components=None)
        await interaction.followup.send(content='Build published successfully. Scheduling refresh...', ephemeral=True)
        # tell bot to fetch update
        self.bot.loop.create_task(self.build_update())
Exemplo n.º 14
0
    async def fider(self):
        items = []
        async with self.bot.session.get(
                'https://ideas.obsproject.com/api/v1/posts?view=recent') as r:
            if r.status == 200:
                feed = await r.json()
                for entry in feed:
                    if entry['id'] <= self.bot.state['fider_last_id']:
                        continue
                    items.append(entry)
            else:
                logger.warning(
                    f'Fetching fider posts failed with status code {r.status}')
                return

        for item in reversed(items):
            if item['id'] > self.bot.state['fider_last_id']:
                self.bot.state['fider_last_id'] = item['id']

            url = f'https://ideas.obsproject.com/posts/{item["id"]}/'
            logger.info(f'Got new Fider post: {url}')

            description = item['description']
            if len(description) > 180:
                description = description[:180] + ' [...]'

            embed = Embed(title=f'{item["id"]}: {item["title"]}',
                          colour=Colour(self._fider_colour),
                          url=url,
                          description=description,
                          timestamp=dateutil.parser.parse(item['createdAt']))

            embed.set_author(
                name='Fider',
                url='https://ideas.obsproject.com/',
                icon_url='https://cdn.rodney.io/stuff/obsbot/fider.png')
            embed.set_footer(text='New Idea on Fider')
            name = 'Anonymous' if not item['user']['name'] else item['user'][
                'name']
            embed.add_field(name='Created By', value=name, inline=True)
            await self.fider_channel.send(embed=embed)
Exemplo n.º 15
0
    async def listfilters(self, ctx: Context):
        if not self.bot.is_admin(ctx.author):
            return
        if not self.bot.is_private(ctx.channel):
            return

        _ban_filters = []
        _kick_filters = []
        _delete_filters = []
        for name, regex in sorted(self.filters.items()):
            if name in self.bannable:
                _ban_filters.append(f'* "{name}" - `{regex.pattern}`')
            elif name in self.kickable:
                _kick_filters.append(f'* "{name}" - `{regex.pattern}`')
            else:
                _delete_filters.append(f'* "{name}" - `{regex.pattern}`')

        embed = Embed(title='Registered Message Filters')
        if _ban_filters:
            embed.add_field(name='Ban Filters',
                            inline=False,
                            value='```\n{}\n```'.format(
                                '\n'.join(_ban_filters)))
        if _kick_filters:
            embed.add_field(name='Kick Filters',
                            inline=False,
                            value='```\n{}\n```'.format(
                                '\n'.join(_kick_filters)))
        if _delete_filters:
            embed.add_field(name='Delete Filters',
                            inline=False,
                            value='```\n{}\n```'.format(
                                '\n'.join(_delete_filters)))

        return await ctx.send(embed=embed)
Exemplo n.º 16
0
    def gen_emoji_page(self, guild: disnake.Guild, page):
        se = sorted(guild.emojis, key=lambda e: e.name)

        embed = Embed(color=0x2db1f3)
        embed.set_author(name=Translator.translate('emoji_server',
                                                   guild,
                                                   server=guild.name,
                                                   page=page + 1,
                                                   pages=len(guild.emojis) +
                                                   1),
                         url=guild.icon.url)
        if page == 0:
            for chunk in Utils.chunks(se, 18):
                embed.add_field(name="\u200b",
                                value=" ".join(str(e) for e in chunk))
            animated = set()
            static = set()
            for e in guild.emojis:
                (animated if e.animated else static).add(str(e))
            max_emoji = guild.emoji_limit
            embed.add_field(name=Translator.translate('static_emoji', guild),
                            value=f"{len(static)} / {max_emoji}")
            embed.add_field(name=Translator.translate('animated_emoji', guild),
                            value=f"{len(animated)} / {max_emoji}")
        else:
            self.add_emoji_info(guild, embed, se[page - 1])

        return embed
Exemplo n.º 17
0
    async def status(self, ctx: Context):
        if not self.bot.is_admin(ctx.author):
            return

        embed = Embed(title='OBS Bot Status')
        embed.add_field(
            name='Core',
            inline=False,
            value=(
                f'Version:  {__version__} - "{__codename__}" Edition\n'
                f'Uptime:  {time.time() - self.bot.start_time:.0f} seconds\n'))

        mentions = ', '.join(u.mention for u in (self.bot.get_user(_id)
                                                 for _id in self.bot.admins)
                             if u)
        embed.add_field(name='Bot admins', inline=False, value=mentions)

        # get information from other Cogs if possible
        if fac := self.bot.get_cog('Factoids'):
            total_uses = sum(i['uses'] for i in fac.factoids.values())
            embed.add_field(
                name='Factoid module',
                inline=False,
                value=(f'Factoids:  {len(fac.factoids)}\n'
                       f'Aliases:  {len(fac.alias_map)}\n'
                       f'Total uses:  {total_uses} (since 2018-06-07)'))
Exemplo n.º 18
0
    async def get_issue_messages(self, event_body):
        issue_number = event_body['issue']['number']
        title = event_body['issue']['title']
        timestamp = dateutil.parser.parse(event_body['issue']['created_at'])
        embed = Embed(title=f'#{issue_number}: {title}',
                      colour=Colour(self._issue_colour),
                      url=event_body['issue']['html_url'],
                      timestamp=timestamp)

        author_name = event_body['issue']['user']['login']
        author = await self.get_author_info(author_name)
        if author and author['name'] and author['name'] != author['login']:
            author_name = f'{author["name"]} ({author["login"]})'

        embed.set_author(name=author_name,
                         url=event_body['issue']['user']['html_url'],
                         icon_url=event_body['issue']['user']['avatar_url'])

        embed.set_footer(text='Issue')
        embed.add_field(name='Repository',
                        value=event_body['repository']['full_name'],
                        inline=True)
        # create copy without description text for brief channel
        brief_embed = embed.copy()
        event_body['issue']['body'] = '\n'.join(
            l.strip() for l in event_body['issue']['body'].splitlines()
            if not l.startswith('<!-'))

        issue_text = event_body['issue']['body']
        # strip double-newlines from issue forms
        if '\n\n' in issue_text:
            issue_text = issue_text.replace('\n\n', '\n')

        if len(issue_text) >= 2048:
            embed.description = issue_text[:2000] + ' [... message trimmed]'
        else:
            embed.description = issue_text

        return brief_embed, embed
Exemplo n.º 19
0
    async def get_pr_messages(self, event_body):
        pr_number = event_body['number']
        title = event_body['pull_request']['title']
        timestamp = dateutil.parser.parse(
            event_body['pull_request']['created_at'])
        embed = Embed(title=f'#{pr_number}: {title}',
                      colour=Colour(self._pull_request_colour),
                      url=event_body['pull_request']['html_url'],
                      timestamp=timestamp)

        author_name = event_body['pull_request']['user']['login']
        author = await self.get_author_info(author_name)
        if author and author['name'] and author['name'] != author['login']:
            author_name = f'{author["name"]} ({author["login"]})'

        embed.set_author(
            name=author_name,
            url=event_body['pull_request']['user']['html_url'],
            icon_url=event_body['pull_request']['user']['avatar_url'])

        embed.set_footer(text='Pull Request')
        embed.add_field(name='Repository',
                        value=event_body['repository']['full_name'],
                        inline=True)
        # create copy without description text for brief channel
        brief_embed = embed.copy()
        # filter out comments in template
        event_body['pull_request']['body'] = '\n'.join(
            l.strip() for l in event_body['pull_request']['body'].splitlines()
            if not l.startswith('<!-'))

        # trim message to discord limits
        if len(event_body['pull_request']['body']) >= 2048:
            embed.description = event_body['pull_request'][
                'body'][:2000] + ' [... message trimmed]'
        else:
            embed.description = event_body['pull_request']['body']

        return brief_embed, embed
Exemplo n.º 20
0
    async def source_command(self,
                             ctx: commands.Context,
                             *,
                             source_item: typing.Optional[str] = None) -> None:
        """Displays information about the bot's source code."""
        if source_item is None:
            embed = Embed(title="Gurkbot's GitHub Repository")
            embed.add_field(name="Repository",
                            value=f"[Go to GitHub]({BOT_REPO_URL})")
            embed.set_thumbnail(url=self.bot.user.display_avatar.url)
            await ctx.send(embed=embed)
            return
        elif not ctx.bot.get_command(source_item):
            raise commands.BadArgument(
                f"Unable to convert `{source_item}` to valid command or Cog.")

        github_source = _source.Source(self.bot.http_session,
                                       self.bot.user.display_avatar.url)
        embed = await github_source.inspect(
            cmd=ctx.bot.get_command(source_item))

        await ctx.send(embed=embed)
Exemplo n.º 21
0
    async def stats(self, ctx: commands.Context) -> None:
        """Get the information and current uptime of the bot."""
        embed = Embed(
            title="Bot Stats",
            color=Colours.green,
        )

        embed.set_thumbnail(url=self.bot.user.display_avatar.url)

        uptime = humanize.precisedelta(
            datetime.utcnow().timestamp() - self.bot.launch_time
        )

        fields = {
            "Python version": python_version(),
            "Disnake version": __version__,
            "Uptime": uptime,
        }

        for name, value in list(fields.items()):
            embed.add_field(name=name, value=value, inline=False)
        await ctx.send(content=ctx.author.mention, embed=embed)
Exemplo n.º 22
0
    async def get_discussion_messages(self, event_body):
        discussion_number = event_body['discussion']['number']
        title = event_body['discussion']['title']
        category = event_body['discussion']['category']['name']
        timestamp = dateutil.parser.parse(
            event_body['discussion']['created_at'])
        embed = Embed(title=f'#{discussion_number}: {category} - {title}',
                      colour=Colour(self._discussion_colour),
                      timestamp=timestamp,
                      url=event_body['discussion']['html_url'])

        author_name = event_body['discussion']['user']['login']
        author = await self.get_author_info(author_name)
        if author and author['name'] and author['name'] != author['login']:
            author_name = f'{author["name"]} ({author["login"]})'

        embed.set_author(
            name=author_name,
            url=event_body['discussion']['user']['html_url'],
            icon_url=event_body['discussion']['user']['avatar_url'])

        embed.set_footer(text='Discussion')
        embed.add_field(name='Repository',
                        value=event_body['repository']['full_name'],
                        inline=True)
        # create copy without description text for brief channel
        brief_embed = embed.copy()
        event_body['discussion']['body'] = '\n'.join(
            l.strip() for l in event_body['discussion']['body'].splitlines()
            if not l.startswith('<!-'))

        if len(event_body['discussion']['body']) >= 1024:
            embed.description = event_body['discussion'][
                'body'][:1024] + ' [... message trimmed]'
        else:
            embed.description = event_body['discussion']['body']

        return brief_embed, embed
Exemplo n.º 23
0
    async def get_wiki_message(self, event_body):
        embed = Embed(colour=Colour(self._wiki_colour))
        embed.set_footer(text='GitHub Wiki Changes')
        # All edits in the response are from a single author
        author_name = event_body['sender']['login']
        author = await self.get_author_info(author_name)
        if author and author['name'] and author['name'] != author['login']:
            author_name = f'{author["name"]} ({author["login"]})'
        embed.set_author(name=author_name,
                         url=event_body['sender']['html_url'],
                         icon_url=event_body['sender']['avatar_url'])
        embed.add_field(name='Repository',
                        value=event_body['repository']['full_name'])

        body = []
        for page in event_body['pages']:
            diff_url = f'{page["html_url"]}/_compare/{page["sha"]}^...{page["sha"]}'
            page_url = f'{page["html_url"]}/{page["sha"]}'
            body.append(
                f'**{page["action"]}:** [{page["title"]}]({page_url}) [[diff]({diff_url})]'
            )
        embed.description = '\n'.join(body)
        return embed
Exemplo n.º 24
0
    async def tophardware(self, ctx: Context):
        embed = Embed(title='Top Hardware')

        cpus = []
        for pos, cpu in enumerate(sorted(self.hardware_stats['cpu'].values(),
                                         key=lambda a: a['count'],
                                         reverse=True)[:10],
                                  start=1):
            cpus.append(f'{pos:2d}. - {cpu["name"]} ({cpu["count"]})')
        embed.add_field(name='CPUs',
                        value='```{}```'.format('\n'.join(cpus)),
                        inline=False)

        gpus = []
        for pos, gpu in enumerate(sorted(self.hardware_stats['gpu'].values(),
                                         key=lambda a: a['count'],
                                         reverse=True)[:10],
                                  start=1):
            gpus.append(f'{pos:2d}. - {gpu["name"]} ({gpu["count"]})')
        embed.add_field(name='GPUs',
                        value='```{}```'.format('\n'.join(gpus)),
                        inline=False)

        return await ctx.send(embed=embed)
Exemplo n.º 25
0
    async def handle_unexpected_error(self, ctx: commands.Context,
                                      error: commands.CommandError) -> None:
        """Send a generic error message in `ctx` and log the exception as an error with exc_info."""
        await ctx.send(
            f"Sorry, an unexpected error occurred. Please let us know!\n\n"
            f"```{error.__class__.__name__}: {error}```")

        push_alert = Embed(
            title="An unexpected error occurred",
            color=Colours.soft_red,
        )
        push_alert.add_field(
            name="User",
            value=f"id: {ctx.author.id} | username: {ctx.author.mention}",
            inline=False,
        )
        push_alert.add_field(name="Command",
                             value=ctx.command.qualified_name,
                             inline=False)
        push_alert.add_field(
            name="Message & Channel",
            value=
            f"Message: [{ctx.message.id}]({ctx.message.jump_url}) | Channel: <#{ctx.channel.id}>",
            inline=False,
        )
        push_alert.add_field(name="Full Message",
                             value=ctx.message.content,
                             inline=False)

        dev_alerts = self.bot.get_channel(Channels.devalerts)
        if dev_alerts is None:
            logger.info(
                f"Fetching dev-alerts channel as it wasn't found in the cache (ID: {Channels.devalerts})"
            )
            try:
                dev_alerts = await self.bot.fetch_channel(Channels.devalerts)
            except disnake.HTTPException as discord_exc:
                logger.exception("Fetch failed", exc_info=discord_exc)
                return

        # Trigger the logger before trying to use Discord in case that's the issue
        logger.error(
            f"Error executing command invoked by {ctx.message.author}: {ctx.message.content}",
            exc_info=error,
        )
        await dev_alerts.send(embed=push_alert)
Exemplo n.º 26
0
 def delete_permitted_term(self, streamer: Streamer, info,
                           mod_action: ModAction,
                           embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_terms_attrs(mod_action, embed)
     embed.add_field(name="Removed by", value=f"{info['requester_login']}")
     if "`" in info["text"]:
         embed.add_field(name="Value", value=f"```{info['text']}```")
     else:
         embed.add_field(name="Value", value=f"`{info['text']}`")
     embed.remove_field(1)
     return embed
Exemplo n.º 27
0
 def ban(self, streamer: Streamer, info, mod_action: ModAction,
         embed: disnake.Embed) -> disnake.Embed:
     embed = self.set_user_attrs(streamer, info, mod_action, embed)
     if info['args'][1] == "":
         embed.add_field(name="Flag Reason", value=f"`None Provided`")
     else:
         if "`" in info["args"][1]:
             embed.add_field(name="Flag Reason",
                             value=f"```{info['args'][1]}```")
         else:
             embed.add_field(name="Flag Reason",
                             value=f"`{info['args'][1]}`")
     return embed
Exemplo n.º 28
0
    def timeout(self, streamer: Streamer, info, mod_action: ModAction,
                embed: disnake.Embed) -> disnake.Embed:
        embed = self.set_user_attrs(streamer, info, mod_action, embed)
        if info['args'][2] == "":
            embed.add_field(name="Flag Reason", value=f"`None Provided`")
        else:
            if "`" in info["args"][2]:
                embed.add_field(name="Flag Reason",
                                value=f"```{info['args'][2]}```")
            else:
                embed.add_field(name="Flag Reason",
                                value=f"`{info['args'][2]}`")

        embed.add_field(
            name="Duration",
            value=
            f"{info['args'][1]} second{'' if int(info['args'][1]) == 1 else 's'}"
        )

        #embed.add_field(name="\u200b", value="\u200b")
        return embed
Exemplo n.º 29
0
    async def info(self, ctx: Context, name: str.lower):
        _name = name if name in self.factoids else self.alias_map.get(name)
        if not _name or _name not in self.factoids:
            return await ctx.send(
                f'The specified factoid ("{name}") does not exist!')

        factoid = self.factoids[_name]
        message = factoid["message"].replace(
            '`', '\\`') if factoid["message"] else '<no message>'
        embed = Embed(title=f'Factoid information: {_name}',
                      description=f'```{message}```')
        if factoid['aliases']:
            embed.add_field(name='Aliases',
                            value=', '.join(factoid['aliases']))
        embed.add_field(name='Uses (since 2018-06-07)',
                        value=str(factoid['uses']))
        embed.add_field(name='Is Embed', value=str(factoid['embed']))
        if factoid['image_url']:
            embed.add_field(name='Image URL',
                            value=factoid['image_url'],
                            inline=False)
        return await ctx.send(embed=embed)
Exemplo n.º 30
0
    def append_command_doc_to_embed(self, command: commands.Command,
                                    embed: disnake.Embed):

        if not command.description:
            return embed.add_field(
                name="Description:",
                value=command.brief
                or "This command appears to not yet have a description.")

        def _eliminate_match_and_create_field(match: re.Match):
            # (?P<x>...) matches are returned in ~.groupdict() as {x: ...} instead of the usual
            # ~.groups() tuple. This can be used to quickly generate an embed field, which requires
            # 'name' and 'value' params
            embed.add_field(
                **match.groupdict(),
                inline=bool(
                    match[2]
                )  # 2nd match stores field flags <n_>, atm only 'i' for inline
            )

        # pattern substring that denotes how a name field should/can look, including flags
        name_flag = r"<n([i]?)>"

        remainder: str = re.sub(
            fr"({name_flag}(?P<name>.*?)<v>(?P<value>.*?))(?={name_flag}|\Z)",
            _eliminate_match_and_create_field,
            command.description,
            flags=re.M | re.S)

        if remainder and not remainder.isspace():
            # More than whitespace remains after eliminating fields ->
            # some data wasn't found, probably unintentional
            logger.warning(
                f"Docstr for command '{command.qualified_name}' has remaining "
                f"content after processing: '{remainder}'. ")

        return embed