diff options
Diffstat (limited to 'bot')
-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 | ||||
-rw-r--r-- | bot/resources/easter/april_fools_vids.json | 12 | ||||
-rw-r--r-- | bot/resources/evergreen/py_topics.yaml | 6 | ||||
-rw-r--r-- | bot/resources/evergreen/starter.yaml | 19 |
8 files changed, 188 insertions, 38 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 diff --git a/bot/resources/easter/april_fools_vids.json b/bot/resources/easter/april_fools_vids.json index d8c1efa1..b2cbd07b 100644 --- a/bot/resources/easter/april_fools_vids.json +++ b/bot/resources/easter/april_fools_vids.json @@ -115,6 +115,18 @@ { "title": "Introducing Gmail Motion", "link": "https://youtu.be/Bu927_ul_X0" + }, + { + "title": "Introducing GeForce GTX G-Assist", + "link": "https://youtu.be/smM-Wdk2RLQ" + }, + { + "title": "The Hovering Mouse - Project McFly | Razer", + "link": "https://youtu.be/IlCx5gjAmqI" + }, + { + "title": "Be the Machine | Project Venom v2", + "link": "https://youtu.be/j8UJE7DoyJ8" } ] diff --git a/bot/resources/evergreen/py_topics.yaml b/bot/resources/evergreen/py_topics.yaml index f3b2eaa3..6b7e0206 100644 --- a/bot/resources/evergreen/py_topics.yaml +++ b/bot/resources/evergreen/py_topics.yaml @@ -69,7 +69,11 @@ # game-development 660625198390837248: - - + - What is your favorite game mechanic? + - What is your favorite framework and why? + - What games do you know that were written in Python? + - What books or tutorials would you recommend for game-development beginners? + - What made you start developing games? # microcontrollers 545603026732318730: diff --git a/bot/resources/evergreen/starter.yaml b/bot/resources/evergreen/starter.yaml index 949220f9..4fec6a10 100644 --- a/bot/resources/evergreen/starter.yaml +++ b/bot/resources/evergreen/starter.yaml @@ -31,3 +31,22 @@ - What is your favorite TV show? - What is your favorite media genre? - How many years have you spent coding? +- What book do you highly recommend everyone to read? +- What websites do you use daily to keep yourself up to date with the industry? +- What made you want to join this Discord server? +- How are you? +- What is the best advice you have ever gotten in regards to programming/software? +- What is the most satisfying thing you've done in your life? +- Who is your favorite music composer/producer/singer? +- What is your favorite song? +- What is your favorite video game? +- What are your hobbies other than programming? +- Who is your favorite Writer? +- What is your favorite movie? +- What is your favorite sport? +- What is your favorite fruit? +- What is your favorite juice? +- What is the best scenery you've ever seen? +- What artistic talents do you have? +- What is the tallest building you've entered? +- What is the oldest computer you've ever used? |