diff --git a/bot/cogs/debate.py b/bot/cogs/debate.py new file mode 100644 index 00000000..e69de29b diff --git a/bot/cogs/games/games.py b/bot/cogs/games/games.py index c709fd10..1da383cc 100644 --- a/bot/cogs/games/games.py +++ b/bot/cogs/games/games.py @@ -1,4 +1,5 @@ import random +import aiohttp from discord import Color, Embed from discord.ext.commands import Cog, Context, command @@ -39,3 +40,32 @@ async def ball8(self, ctx: Context, *, question: str) -> None: embed.add_field(name="Answer", value=answer) await ctx.send(embed=embed) + + @command(aliases=["pokesearch"]) + async def pokemon(self, ctx: Context, pokemon: str) -> None: + """ + Fetches data about a given pokemon eg. pokemon pikachu + """ + + async with aiohttp.ClientSession() as session: + async with session.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon}") as resp: + data = await resp.json() + + pokemon_embed = Embed( + title=f"{pokemon.capitalize()} Info", + color=Color.blurple() + ) + + ability_names = [f"`{ability['ability']['name']}`" for ability in data["abilities"]] + pokemon_types = [f"`{ptype_raw['type']['name']}`" for ptype_raw in data["types"]] + base_stat_names = ["Hp", "Attack", "Defence", "Special-Attack", "Special-Defence", "Speed"] + base_stats_zip = zip(base_stat_names, data["stats"]) + base_stats = [f"**{stat_name}**: `{str(base_stat_dict['base_stat'])}`" for stat_name, base_stat_dict in base_stats_zip] + + pokemon_embed.set_thumbnail(url=data["sprites"]["front_default"]) + pokemon_embed.add_field(name="Base Stats", value="❯❯ " + "\n❯❯ ".join(base_stats)) + pokemon_embed.add_field(name="Type", value="❯❯ " + "\n❯❯ ".join(pokemon_types)) + pokemon_embed.add_field(name="Weight", value=f"❯❯ `{str(data['weight'])}`") + pokemon_embed.add_field(name="Abilities", value="❯❯ " + "\n❯❯ ".join(ability_names), inline=True) + + await ctx.send(embed=pokemon_embed) diff --git a/bot/cogs/search.py b/bot/cogs/search.py index 9ad4ebf7..d6d87dba 100644 --- a/bot/cogs/search.py +++ b/bot/cogs/search.py @@ -1,12 +1,14 @@ +import os import re import textwrap from typing import List import aiohttp -import html2text -from discord import Embed, utils +from discord import Color, Embed, utils from discord.ext.commands import Cog, CommandError, Context, command +from discord.ext.commands.errors import CommandInvokeError +import html2text from bot import config from bot.core.bot import Bot @@ -201,68 +203,137 @@ async def anime(self, ctx: Context, *, query: str) -> None: ) await ctx.send(template) - @command() - async def manga(self, ctx: Context, *, query: str) -> None: - """Look up manga information.""" - base = "https://kitsu.io/api/edge/" - - # Handling - async with ctx.typing(): - async with aiohttp.ClientSession() as session: - async with session.get(base + "manga", params={"filter[text]": query}) as resp: - resp = await resp.json() - resp = resp["data"] - - query = utils.escape_mentions(query) - query = utils.escape_markdown(query) - - if not resp: - await ctx.send(f"No results for `{query}`.") - return - - manga = resp[0] - title = f'{manga["attributes"]["canonicalTitle"]}' - manga_id = manga["id"] - url = f"https://kitsu.io/manga/{manga_id}" - - embed = Embed(title=f"{title}", color=ctx.author.color, url=url) - embed.description = manga["attributes"]["synopsis"][0:425] + "..." - - if manga["attributes"]["averageRating"]: - embed.add_field(name="Average Rating", value=manga["attributes"]["averageRating"]) - embed.add_field(name="Popularity Rank", value=manga["attributes"]["popularityRank"]) - - if manga["attributes"]["ageRating"]: - embed.add_field(name="Age Rating", value=manga["attributes"]["ageRating"]) - embed.add_field(name="Status", value=manga["attributes"]["status"]) - thing = "" if not manga["attributes"]["endDate"] else f' to {manga["attributes"]["endDate"]}' - embed.add_field(name="Published", value=f"{manga['attributes']['startDate']}{thing}") - - if manga["attributes"]["chapterCount"]: - embed.add_field(name="Chapters", value=manga["attributes"]["chapterCount"]) - embed.add_field(name="Type", value=manga["attributes"]["mangaType"]) - embed.set_thumbnail(url=manga["attributes"]["posterImage"]["original"]) - - try: - await ctx.send(f"**{title}** - <{url}>", embed=embed) - except Exception: - aired = f"{manga['attributes']['startDate']}{thing}" - template = textwrap.dedent( - f""" - ``` - url: {url} - Title: {title} - Average Rating: {manga["attributes"]["averageRating"]} - Popularity Rank: {manga["attributes"]["popularityRank"]} - Age Rating: {manga["attributes"]["ageRating"]} - Status: {manga["attributes"]["status"]} - Aired: {aired} - Type: {manga['attributes']["showType"]} - Powered by HotWired - ``` - """ - ) - await ctx.send(template) + @command() + async def manga(self, ctx: Context, *, query: str) -> None: + """Look up manga information.""" + base = "https://kitsu.io/api/edge/" + + # Handling + async with ctx.typing(): + async with aiohttp.ClientSession() as session: + async with session.get(base + "manga", params={"filter[text]": query}) as resp: + resp = await resp.json() + resp = resp["data"] + + query = utils.escape_mentions(query) + query = utils.escape_markdown(query) + + if not resp: + await ctx.send(f"No results for `{query}`.") + return + + manga = resp[0] + title = f'{manga["attributes"]["canonicalTitle"]}' + manga_id = manga["id"] + url = f"https://kitsu.io/manga/{manga_id}" + + embed = Embed(title=title, color=ctx.author.color, url=url) + embed.description = manga["attributes"]["synopsis"][0:425] + "..." + + if manga["attributes"]["averageRating"]: + embed.add_field(name="Average Rating", value=manga["attributes"]["averageRating"]) + embed.add_field(name="Popularity Rank", value=manga["attributes"]["popularityRank"]) + + if manga["attributes"]["ageRating"]: + embed.add_field(name="Age Rating", value=manga["attributes"]["ageRating"]) + embed.add_field(name="Status", value=manga["attributes"]["status"]) + thing = "" if not manga["attributes"]["endDate"] else f' to {manga["attributes"]["endDate"]}' + embed.add_field(name="Published", value=f"{manga['attributes']['startDate']}{thing}") + + if manga["attributes"]["chapterCount"]: + embed.add_field(name="Chapters", value=manga["attributes"]["chapterCount"]) + embed.add_field(name="Type", value=manga["attributes"]["mangaType"]) + embed.set_thumbnail(url=manga["attributes"]["posterImage"]["original"]) + + try: + await ctx.send(f"**{title}** - <{url}>", embed=embed) + except Exception: + aired = f"{manga['attributes']['startDate']}{thing}" + template = textwrap.dedent( + f""" + ``` + url: {url} + Title: {title} + Average Rating: {manga["attributes"]["averageRating"]} + Popularity Rank: {manga["attributes"]["popularityRank"]} + Age Rating: {manga["attributes"]["ageRating"]} + Status: {manga["attributes"]["status"]} + Aired: {aired} + Type: {manga['attributes']["showType"]} + Powered by HotWired + ``` + """ + ) + await ctx.send(template) + + @command() + async def weather(self, ctx: Context, *, city: str = None) -> None: + """Sends current weather in the given city name + + eg. weather london + """ + + try: + url_formatted_city = city.replace(" ", "-") + except CommandInvokeError: + ctx.send("You didn't provide a city") + + async with aiohttp.ClientSession() as session: + weather_lookup_url = f"https://api.openweathermap.org/data/2.5/weather?q={url_formatted_city}&appid={os.getenv('WEATHER_API_KEY')}" + async with session.get(weather_lookup_url) as resp: + data = await resp.json() + + if data["cod"] == "401": + await ctx.send("Invalid API key") + return + if data["cod"] == "404": + await ctx.send("Invalid city name") + return + + weather_embed = Embed( + title=f"Current Weather in {city.capitalize()}", + color=Color.blue() + ) + longtitude = data["coord"]["lon"] + lattitude = data["coord"]["lat"] + weather_embed.add_field( + name="Coordinates", + value=f"**❯❯ Longtitude: **`{longtitude}`\n**❯❯ Latittude: **`{lattitude}`" + ) + actual_temp = round(data["main"]["temp"] / 10, 1) + feels_like = round(data["main"]["feels_like"] / 10, 1) + weather_embed.add_field( + name="Temperature", + value=f"**❯❯ Temperature: **`{actual_temp}°C`\n**❯❯ Feels Like: **`{feels_like}°C`" + ) + wind_speed = data["wind"]["speed"] + wind_direction = data["wind"]["deg"] + weather_embed.add_field( + name="Wind", + value=f"**❯❯ Speed: **`{wind_speed}km/h`\n**❯❯ Direction: **`{wind_direction}°`", + ) + visibility = round(data["visibility"] / 1000, 2) + humidity = data["main"]["humidity"] + weather_description = data["weather"][0]["description"] + weather_embed.add_field( + name="Miscellaneous", + value=f"**❯❯ Humidity: **`{humidity}%`\n**❯❯ Visibility: **`{visibility}km`\n**❯❯ Weather Summary: **`{weather_description}`", + ) + + if "wind" in weather_description: + weather_embed.set_image(url=config.WEATHER_ICONS["wind"]) + elif "partly" in weather_description: + weather_embed.set_image(url=config.WEATHER_ICONS["partly"]) + elif "cloud" in weather_description: + weather_embed.set_image(url=config.WEATHER_ICONS["cloud"]) + elif "snow" in weather_description: + weather_embed.set_image(url=config.WEATHER_ICONS["snow"]) + elif "rain" in weather_description: + weather_embed.set_image(url=config.WEATHER_ICONS["rain"]) + else: + weather_embed.set_image(url=config.WEATHER_ICONS["sun"]) + + await ctx.send(embed=weather_embed) def setup(bot: Bot) -> None: diff --git a/bot/config.py b/bot/config.py index 02b73493..176b9e08 100644 --- a/bot/config.py +++ b/bot/config.py @@ -42,6 +42,17 @@ line_img_url = "https://cdn.discordapp.com/attachments/581139962611892229/692712698487767080/animated_line.gif" + +WEATHER_ICONS = { + "wind": "https://cdn.discordapp.com/attachments/728569086174298112/735550169222873118/windy.png", + "rain": "https://cdn.discordapp.com/attachments/728569086174298112/735550164458274947/raining.png", + "sun": "https://cdn.discordapp.com/attachments/728569086174298112/735550167859593306/sunny.png", + "cloud": "https://cdn.discordapp.com/attachments/728569086174298112/735550159781494865/cloudy.png", + "partly": "https://cdn.discordapp.com/attachments/728569086174298112/735550162721701979/partly.png", + "snow": "https://cdn.discordapp.com/attachments/728569086174298112/735550166563684474/snowy.png" +} + + # Magic 8-Ball responses NEGATIVE_REPLIES = [ "Noooooo!!",