Repository: python-discord/bot

Issue:
Command for fetching package information from PyPi
These should `!package <name>` command, that fetch information from [PyPi JSON API](https://wiki.python.org/moin/PyPIJSON). This should go under `Utils` cog.

## Information that will be shown in embed

- Name
- Summary
- Author
- Maintainer
- Project URL (PyPi)
- Homepage
- Required Python version
- Latest version
- License
- Downloads (last month)
- Quick installation copy paste string

I can work with this after my current PR get merged.


Discussion:
For the project descriptions, there may be some problems picking up the relevant data out of them; some start with an introduction, others with an install guide etc. There's always the option to not include the description or just cut it off before the char limit but something to take into consideration.

Also I think this should probably have its own cog if the above parsing gets involved
@Numerlor My idea is showing only short summary, author, supported Python versions, license, home page, PyPi page and latest version there, due READMEs may REALLY big.
The implementation details of this needs a lot more thought put into it & provided in the description before this can move forward. There's going to need to be more going on to implement this well than just requesting some JSON and dumping it all into an embed.

The amount of information present in a project's PyPI page ranges from very little to a whole lot, so it needs to be identified which information is always present and what is optionally present and, out of those, decide what we want to display in the embed while respecting the embed's various character limits.
@sco1 I added information about what would be in embed.
Since this command will only pull data from PyPi, I feel like `!pypi` is a better name for it. It sounds like a good command to have.
@Akarys42 Or maybe: `!pypi` as main name, `!package` as alias?
I wnt to work on this :)
@Anubhav1603 Are you still working on this?
yeh

I was waiting for getting this approved which got approved 5 day ago so now i started working on this

Resolving patch:
diff --git a/bot/constants.py b/bot/constants.py
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -246,13 +246,16 @@ class Colours(metaclass=YAMLGetter):
     section = "style"
     subsection = "colours"
 
+    blue: int
     bright_green: int
-    soft_green: int
-    soft_orange: int
-    soft_red: int
     orange: int
     pink: int
     purple: int
+    soft_green: int
+    soft_orange: int
+    soft_red: int
+    white: int
+    yellow: int
 
 
 class DuckPond(metaclass=YAMLGetter):
diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py
new file mode 100644
--- /dev/null
+++ b/bot/exts/info/pypi.py
@@ -0,0 +1,69 @@
+import itertools
+import logging
+import random
+
+from discord import Embed
+from discord.ext.commands import Cog, Context, command
+
+from bot.bot import Bot
+from bot.constants import Colours, NEGATIVE_REPLIES
+
+URL = "https://pypi.org/pypi/{package}/json"
+FIELDS = ("author", "requires_python", "summary", "license")
+PYPI_ICON = "https://cdn.discordapp.com/emojis/766274397257334814.png"
+PYPI_COLOURS = itertools.cycle((Colours.yellow, Colours.blue, Colours.white))
+
+log = logging.getLogger(__name__)
+
+
+class PyPi(Cog):
+    """Cog for getting information about PyPi packages."""
+
+    def __init__(self, bot: Bot):
+        self.bot = bot
+
+    @command(name="pypi", aliases=("package", "pack"))
+    async def get_package_info(self, ctx: Context, package: str) -> None:
+        """Provide information about a specific package from PyPI."""
+        embed = Embed(
+            title=random.choice(NEGATIVE_REPLIES),
+            colour=Colours.soft_red
+        )
+        embed.set_thumbnail(url=PYPI_ICON)
+
+        async with self.bot.http_session.get(URL.format(package=package)) as response:
+            if response.status == 404:
+                embed.description = "Package could not be found."
+
+            elif response.status == 200 and response.content_type == "application/json":
+                response_json = await response.json()
+                info = response_json["info"]
+
+                embed.title = f"{info['name']} v{info['version']}"
+                embed.url = info['package_url']
+                embed.colour = next(PYPI_COLOURS)
+
+                for field in FIELDS:
+                    field_data = info[field]
+
+                    # Field could be completely empty, in some cases can be a string with whitespaces, or None.
+                    if field_data and not field_data.isspace():
+                        if '\n' in field_data and field == "license":
+                            field_data = field_data.split('\n')[0]
+
+                        embed.add_field(
+                            name=field.replace("_", " ").title(),
+                            value=field_data,
+                            inline=False,
+                        )
+
+            else:
+                embed.description = "There was an error when fetching your PyPi package."
+                log.trace(f"Error when fetching PyPi package: {response.status}.")
+
+        await ctx.send(embed=embed)
+
+
+def setup(bot: Bot) -> None:
+    """Load the PyPi cog."""
+    bot.add_cog(PyPi(bot))


Test patch: