diff options
| author | 2021-04-06 10:29:46 +0200 | |
|---|---|---|
| committer | 2021-04-06 10:29:46 +0200 | |
| commit | 6241e9db8a2489c1bbdd0079cabd9dbd7b5b9b61 (patch) | |
| tree | ceb61a295c6a4456d6e077e35e9c56a55df06475 /bot/exts | |
| parent | Issues: ignore bots (diff) | |
| parent | Merge pull request #658 from python-discord/ks123/ghcr-token-to-github (diff) | |
Merge remote-tracking branch 'origin/main' into akarys/630/automatic-linking-everywhere
Diffstat (limited to 'bot/exts')
| -rw-r--r-- | bot/exts/easter/easter_riddle.py | 13 | ||||
| -rw-r--r-- | bot/exts/evergreen/githubinfo.py | 143 | ||||
| -rw-r--r-- | bot/exts/evergreen/issues.py | 27 | ||||
| -rw-r--r-- | bot/exts/evergreen/wolfram.py | 3 | ||||
| -rw-r--r-- | bot/exts/halloween/candy_collection.py | 3 | 
5 files changed, 152 insertions, 37 deletions
| diff --git a/bot/exts/easter/easter_riddle.py b/bot/exts/easter/easter_riddle.py index 3c612eb1..a93b3745 100644 --- a/bot/exts/easter/easter_riddle.py +++ b/bot/exts/easter/easter_riddle.py @@ -7,7 +7,7 @@ from pathlib import Path  import discord  from discord.ext import commands -from bot.constants import Colours +from bot.constants import Colours, NEGATIVE_REPLIES  log = logging.getLogger(__name__) @@ -36,6 +36,17 @@ class EasterRiddle(commands.Cog):          if self.current_channel:              return await ctx.send(f"A riddle is already being solved in {self.current_channel.mention}!") +        # Don't let users start in a DM +        if not ctx.guild: +            await ctx.send( +                embed=discord.Embed( +                    title=random.choice(NEGATIVE_REPLIES), +                    description="You can't start riddles in DMs", +                    colour=discord.Colour.red() +                ) +            ) +            return +          self.current_channel = ctx.message.channel          random_question = random.choice(RIDDLE_QUESTIONS) diff --git a/bot/exts/evergreen/githubinfo.py b/bot/exts/evergreen/githubinfo.py index 2e38e3ab..c8a6b3f7 100644 --- a/bot/exts/evergreen/githubinfo.py +++ b/bot/exts/evergreen/githubinfo.py @@ -1,16 +1,19 @@  import logging  import random  from datetime import datetime -from typing import Optional +from urllib.parse import quote  import discord  from discord.ext import commands  from discord.ext.commands.cooldowns import BucketType -from bot.constants import NEGATIVE_REPLIES +from bot.constants import Colours, NEGATIVE_REPLIES +from bot.exts.utils.extensions import invoke_help_command  log = logging.getLogger(__name__) +GITHUB_API_URL = "https://api.github.com" +  class GithubInfo(commands.Cog):      """Fetches info from GitHub.""" @@ -23,27 +26,28 @@ class GithubInfo(commands.Cog):          async with self.bot.http_session.get(url) as r:              return await r.json() -    @commands.command(name='github', aliases=['gh']) -    @commands.cooldown(1, 60, BucketType.user) -    async def get_github_info(self, ctx: commands.Context, username: Optional[str]) -> None: -        """ -        Fetches a user's GitHub information. - -        Username is optional and sends the help command if not specified. -        """ -        if username is None: -            await ctx.invoke(self.bot.get_command('help'), 'github') -            ctx.command.reset_cooldown(ctx) -            return +    @commands.group(name='github', aliases=('gh', 'git')) +    @commands.cooldown(1, 10, BucketType.user) +    async def github_group(self, ctx: commands.Context) -> None: +        """Commands for finding information related to GitHub.""" +        if ctx.invoked_subcommand is None: +            await invoke_help_command(ctx) +    @github_group.command(name='user', aliases=('userinfo',)) +    async def github_user_info(self, ctx: commands.Context, username: str) -> None: +        """Fetches a user's GitHub information."""          async with ctx.typing(): -            user_data = await self.fetch_data(f"https://api.github.com/users/{username}") +            user_data = await self.fetch_data(f"{GITHUB_API_URL}/users/{username}")              # User_data will not have a message key if the user exists -            if user_data.get('message') is not None: -                await ctx.send(embed=discord.Embed(title=random.choice(NEGATIVE_REPLIES), -                                                   description=f"The profile for `{username}` was not found.", -                                                   colour=discord.Colour.red())) +            if "message" in user_data: +                embed = discord.Embed( +                    title=random.choice(NEGATIVE_REPLIES), +                    description=f"The profile for `{username}` was not found.", +                    colour=Colours.soft_red +                ) + +                await ctx.send(embed=embed)                  return              org_data = await self.fetch_data(user_data['organizations_url']) @@ -63,7 +67,7 @@ class GithubInfo(commands.Cog):              embed = discord.Embed(                  title=f"`{user_data['login']}`'s GitHub profile info",                  description=f"```{user_data['bio']}```\n" if user_data['bio'] is not None else "", -                colour=0x7289da, +                colour=discord.Colour.blurple(),                  url=user_data['html_url'],                  timestamp=datetime.strptime(user_data['created_at'], "%Y-%m-%dT%H:%M:%SZ")              ) @@ -72,26 +76,99 @@ class GithubInfo(commands.Cog):              if user_data['type'] == "User": -                embed.add_field(name="Followers", -                                value=f"[{user_data['followers']}]({user_data['html_url']}?tab=followers)") -                embed.add_field(name="\u200b", value="\u200b") -                embed.add_field(name="Following", -                                value=f"[{user_data['following']}]({user_data['html_url']}?tab=following)") - -            embed.add_field(name="Public repos", -                            value=f"[{user_data['public_repos']}]({user_data['html_url']}?tab=repositories)") -            embed.add_field(name="\u200b", value="\u200b") +                embed.add_field( +                    name="Followers", +                    value=f"[{user_data['followers']}]({user_data['html_url']}?tab=followers)" +                ) +                embed.add_field( +                    name="Following", +                    value=f"[{user_data['following']}]({user_data['html_url']}?tab=following)" +                ) + +            embed.add_field( +                name="Public repos", +                value=f"[{user_data['public_repos']}]({user_data['html_url']}?tab=repositories)" +            )              if user_data['type'] == "User": -                embed.add_field(name="Gists", value=f"[{gists}](https://gist.github.com/{username})") +                embed.add_field(name="Gists", value=f"[{gists}](https://gist.github.com/{quote(username, safe='')})") -                embed.add_field(name=f"Organization{'s' if len(orgs)!=1 else ''}", -                                value=orgs_to_add if orgs else "No organizations") -                embed.add_field(name="\u200b", value="\u200b") +                embed.add_field( +                    name=f"Organization{'s' if len(orgs)!=1 else ''}", +                    value=orgs_to_add if orgs else "No organizations" +                )              embed.add_field(name="Website", value=blog)          await ctx.send(embed=embed) +    @github_group.command(name='repository', aliases=('repo',)) +    async def github_repo_info(self, ctx: commands.Context, *repo: str) -> None: +        """ +        Fetches a repositories' GitHub information. + +        The repository should look like `user/reponame` or `user reponame`. +        """ +        repo = '/'.join(repo) +        if repo.count('/') != 1: +            embed = discord.Embed( +                title=random.choice(NEGATIVE_REPLIES), +                description="The repository should look like `user/reponame` or `user reponame`.", +                colour=Colours.soft_red +            ) + +            await ctx.send(embed=embed) +            return + +        async with ctx.typing(): +            repo_data = await self.fetch_data(f"{GITHUB_API_URL}/repos/{quote(repo)}") + +            # There won't be a message key if this repo exists +            if "message" in repo_data: +                embed = discord.Embed( +                    title=random.choice(NEGATIVE_REPLIES), +                    description="The requested repository was not found.", +                    colour=Colours.soft_red +                ) + +                await ctx.send(embed=embed) +                return + +        embed = discord.Embed( +            title=repo_data['name'], +            description=repo_data["description"], +            colour=discord.Colour.blurple(), +            url=repo_data['html_url'] +        ) + +        # If it's a fork, then it will have a parent key +        try: +            parent = repo_data["parent"] +            embed.description += f"\n\nForked from [{parent['full_name']}]({parent['html_url']})" +        except KeyError: +            log.debug("Repository is not a fork.") + +        repo_owner = repo_data['owner'] + +        embed.set_author( +            name=repo_owner["login"], +            url=repo_owner["html_url"], +            icon_url=repo_owner["avatar_url"] +        ) + +        repo_created_at = datetime.strptime(repo_data['created_at'], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y") +        last_pushed = datetime.strptime(repo_data['pushed_at'], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y at %H:%M") + +        embed.set_footer( +            text=( +                f"{repo_data['forks_count']} ⑂ " +                f"• {repo_data['stargazers_count']} ⭐ " +                f"• Created At {repo_created_at} " +                f"• Last Commit {last_pushed}" +            ) +        ) + +        await ctx.send(embed=embed) +  def setup(bot: commands.Bot) -> None:      """Adding the cog to the bot.""" diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 7e9defbe..7255d450 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -7,7 +7,16 @@ from dataclasses import dataclass  import discord  from discord.ext import commands, tasks -from bot.constants import Categories, Colours, ERROR_REPLIES, Emojis, Tokens, WHITELISTED_CHANNELS +from bot.constants import ( +    Categories, +    Channels, +    Colours, +    ERROR_REPLIES, +    Emojis, +    NEGATIVE_REPLIES, +    Tokens, +    WHITELISTED_CHANNELS +)  from bot.utils.decorators import whitelist_override  log = logging.getLogger(__name__) @@ -200,7 +209,7 @@ class Issues(commands.Cog):              await ctx.invoke(self.bot.get_command('help'), 'issue')          results = [await self.fetch_issues(number, repository, user) for number in numbers] -        await ctx.send(embed=self.format_embed(results)) +        await ctx.send(embed=self.format_embed(results, user, repository))      @commands.Cog.listener()      async def on_message(self, message: discord.Message) -> None: @@ -218,6 +227,20 @@ class Issues(commands.Cog):          links = []          if issues: +            # Block this from working in DMs +            if not message.guild: +                await message.channel.send( +                    embed=discord.Embed( +                        title=random.choice(NEGATIVE_REPLIES), +                        description=( +                            "You can't retrieve issues from DMs. " +                            f"Try again in <#{Channels.community_bot_commands}>" +                        ), +                        colour=discord.Colour.red() +                    ) +                ) +                return +              log.trace(f"Found {issues = }")              # Remove duplicates              issues = set(issues) diff --git a/bot/exts/evergreen/wolfram.py b/bot/exts/evergreen/wolfram.py index 437d9e1a..14ec1041 100644 --- a/bot/exts/evergreen/wolfram.py +++ b/bot/exts/evergreen/wolfram.py @@ -62,7 +62,8 @@ def custom_cooldown(*ignore: List[int]) -> Callable:              # if the invoked command is help we don't want to increase the ratelimits since it's not actually              # invoking the command/making a request, so instead just check if the user/guild are on cooldown.              guild_cooldown = not guildcd.get_bucket(ctx.message).get_tokens() == 0  # if guild is on cooldown -            if not any(r.id in ignore for r in ctx.author.roles):  # check user bucket if user is not ignored +            # check the message is in a guild, and check user bucket if user is not ignored +            if ctx.guild and not any(r.id in ignore for r in ctx.author.roles):                  return guild_cooldown and not usercd.get_bucket(ctx.message).get_tokens() == 0              return guild_cooldown diff --git a/bot/exts/halloween/candy_collection.py b/bot/exts/halloween/candy_collection.py index 0cb37ecd..40e21f40 100644 --- a/bot/exts/halloween/candy_collection.py +++ b/bot/exts/halloween/candy_collection.py @@ -47,6 +47,9 @@ class CandyCollection(commands.Cog):      @commands.Cog.listener()      async def on_message(self, message: discord.Message) -> None:          """Randomly adds candy or skull reaction to non-bot messages in the Event channel.""" +        # Ignore messages in DMs +        if not message.guild: +            return          # make sure its a human message          if message.author.bot:              return | 
