Source code for byte_bot.byte.plugins.python

"""Plugins for Python related things, including PyPI, PEPs, etc."""

from __future__ import annotations

from discord import Embed, Interaction
from discord.app_commands import Choice, autocomplete
from discord.app_commands import command as app_command
from discord.ext.commands import Bot, Cog

from byte_bot.byte.lib.common.assets import python_logo
from byte_bot.byte.lib.common.colors import python_blue, python_yellow
from byte_bot.byte.lib.utils import PEP, query_all_peps
from byte_bot.byte.views.abstract_views import ExtendedEmbed, Field
from byte_bot.byte.views.python import PEPView

__all__ = ("Python", "setup")


[docs] class Python(Cog): """Python cog."""
[docs] def __init__(self, bot: Bot, peps: list[PEP]) -> None: """Initialize cog.""" self.bot = bot self.__cog_name__ = "Python Commands" self._peps = {pep["number"]: pep for pep in peps}
async def _pep_autocomplete(self, interaction: Interaction, current_pep: str) -> list[Choice[str]]: # noqa: ARG002 """Autocomplete for PEP numbers and titles. .. warning:: ``interaction`` is not used, but is required. """ return [ Choice(name=f"PEP {number} - {pep['title']}", value=str(number)) for number, pep in self._peps.items() if current_pep.lower() in str(number) or current_pep.lower() in pep["title"].lower() ][:25] @app_command(name="pep") @autocomplete(pep=_pep_autocomplete) async def peps(self, interaction: Interaction, pep: int) -> None: """Slash command to look up and display a Python Enhancement Proposal (PEP). Args: interaction: Interaction object. pep: The PEP number to lookup. """ await interaction.response.send_message(f"Querying PEP {pep}...", ephemeral=True) if (pep_details := self._peps.get(pep)) is None: embed = Embed(title=f"PEP {pep} not found... Maybe you should submit it!", color=python_yellow) await interaction.followup.send(embed=embed, ephemeral=True) return fields: list[Field] = [ {"name": "Status", "value": pep_details["status"], "inline": True}, {"name": "Python Version", "value": pep_details["python_version"], "inline": True}, {"name": "Created", "value": str(pep_details["created"]), "inline": True}, {"name": "Resolution", "value": pep_details.get("resolution", "N/A"), "inline": False}, {"name": "Type", "value": pep_details["type"], "inline": True}, {"name": "Topic", "value": pep_details.get("topic", "N/A"), "inline": True}, {"name": "Requires", "value": pep_details.get("requires", "N/A"), "inline": True}, {"name": "Replaces", "value": pep_details.get("replaces", "N/A"), "inline": True}, {"name": "Superseded By", "value": pep_details.get("superseded_by", "N/A"), "inline": True}, {"name": "Authors", "value": ", ".join(pep_details.get("authors", ["N/A"])), "inline": False}, {"name": "Discussions To", "value": pep_details.get("discussions_to", "N/A"), "inline": False}, {"name": "Post History", "value": pep_details.get("post_history", "N/A"), "inline": False}, ] minified_embed = ExtendedEmbed.from_field_dicts( title=f"PEP {pep_details['number']}: {pep_details['title']}", color=python_blue, fields=fields[:4] ) minified_embed.set_thumbnail(url=python_logo) full_embed = minified_embed.deepcopy() full_embed.add_field_dicts(fields[4:]) # Ensure the Documentation field is always last minified_embed.add_field(name="Documentation", value=f"[PEP Documentation]({pep_details['url']})", inline=False) full_embed.add_field(name="Documentation", value=f"[PEP Documentation]({pep_details['url']})", inline=False) view = PEPView( # type: ignore[call-arg] author=interaction.user.id, bot=self.bot, original_embed=full_embed, minified_embed=minified_embed ) await interaction.followup.send(embed=minified_embed, view=view)
[docs] async def setup(bot: Bot) -> None: """Set up the Python cog.""" await bot.add_cog(Python(bot, await query_all_peps()))