diff --git a/config.yaml b/config.yaml index e10fffc..7e530d0 100644 --- a/config.yaml +++ b/config.yaml @@ -1,4 +1,5 @@ discord: game_name: "Pathfinder 2E" + test_guilds: [] command_prefix: "." token: \ No newline at end of file diff --git a/src/bot/config/configurator.py b/src/bot/config/configurator.py index 42a55d4..b816736 100644 --- a/src/bot/config/configurator.py +++ b/src/bot/config/configurator.py @@ -66,6 +66,7 @@ class DiscordSettings(BaseModel): game_name: str = Field(default="RPG") token: str = Field() command_prefix: str = Field(default=".") + test_guilds: list[int] = Field(default=[]) class Settings(BaseSettings): diff --git a/src/bot/discord/bot.py b/src/bot/discord/bot.py index ca9a15e..8bcce7b 100644 --- a/src/bot/discord/bot.py +++ b/src/bot/discord/bot.py @@ -4,6 +4,7 @@ import disnake from disnake.ext.commands import bot from src.bot.discord.commands.dice import DiceCog +from src.bot.discord.commands.pathfinder_wiki import PathfinderWikiCog class NucuBot(bot.Bot): @@ -12,14 +13,18 @@ class NucuBot(bot.Bot): self._logger = logging.getLogger(__name__) @staticmethod - def create(command_prefix: str = ".", game_name: str = "RPG") -> "NucuBot": + def create( + command_prefix: str = ".", game_name: str = "RPG", test_guilds: list[int] = () + ) -> "NucuBot": intents = disnake.Intents.all() discord_bot = NucuBot( intents=intents, command_prefix=command_prefix, activity=disnake.Game(name=game_name), + test_guilds=test_guilds, ) discord_bot.add_cog(DiceCog(discord_bot)) + discord_bot.add_cog(PathfinderWikiCog(discord_bot)) return discord_bot async def on_ready(self): diff --git a/src/bot/discord/commands/pathfinder_wiki.py b/src/bot/discord/commands/pathfinder_wiki.py new file mode 100644 index 0000000..2f0ee8e --- /dev/null +++ b/src/bot/discord/commands/pathfinder_wiki.py @@ -0,0 +1,28 @@ +import disnake +from disnake.ext import commands + +from src.knowledge.pathfinder_wiki import PathfinderWikiClient + + +async def pathfinder_wiki_lookup_autocomplete( + inter: disnake.ApplicationCommandInteraction, user_input: str +) -> list[str]: + async with PathfinderWikiClient() as wiki_client: + data = await wiki_client.search_pages(user_input) + return list(map(lambda x: x.key, data)) + + +class PathfinderWikiCog(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.slash_command( + name="pwiki-lookup", description="Lookup a Pathfinder wiki page." + ) + async def lookup( + self, + inter: disnake.ApplicationCommandInteraction, + query: str = commands.Param(autocomplete=pathfinder_wiki_lookup_autocomplete), + ): + wiki_link = PathfinderWikiClient.get_wiki_page_url(query) + await inter.send(f"@{inter.author} here's the wiki link: {wiki_link}") diff --git a/src/knowledge/__init__.py b/src/knowledge/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/knowledge/pathfinder_wiki.py b/src/knowledge/pathfinder_wiki.py new file mode 100644 index 0000000..633cfeb --- /dev/null +++ b/src/knowledge/pathfinder_wiki.py @@ -0,0 +1,71 @@ +import asyncio +import dataclasses + +import aiohttp +from pydantic_core import Url + + +@dataclasses.dataclass +class PathfinderWikiPage: + key: str + title: str + excerpt: str + image: Url + + +class PathfinderWikiClient: + """ + Simple PathfinderWikiClient + """ + + def __init__(self): + self.session = None + + async def __aenter__(self): + self.session = aiohttp.ClientSession() + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.session.close() + + async def search_pages(self, query: str) -> list[PathfinderWikiPage]: + """ + Searches the wiki pages that match the given query. + :param query: The wiki query. + :return: A list of: func:`PathfinderWikiPage`. + """ + if self.session is None: + self.session = aiohttp.ClientSession() + + def _convert_to_page(item) -> PathfinderWikiPage: + image = None + thumbnail = item.get("thumbnail", {}) + if thumbnail is not None: + image = thumbnail.get("image") + return PathfinderWikiPage( + key=item.get("key"), + title=item.get("title"), + excerpt=item.get("excerpt"), + image=image, + ) + + async with self.session.get( + f"https://pathfinderwiki.com/w/rest/v1/search/title?q={query}&limit=10" + ) as response: + result = await response.json() + return list(map(_convert_to_page, result.get("pages", []))) + + @staticmethod + def get_wiki_page_url(page_key) -> str: + return f"https://pathfinderwiki.com/wiki/{page_key}" + + async def close(self): + await self.session.close() + + +if __name__ == "__main__": + pf = PathfinderWikiClient() + asyncio.run(pf.search_pages("zom")) + print(pf.get_wiki_page_url("zombie_lord")) + + asyncio.run(pf.close()) diff --git a/src/main.py b/src/main.py index 8c4b737..1b372ba 100644 --- a/src/main.py +++ b/src/main.py @@ -9,6 +9,7 @@ def main(): bot = NucuBot.create( command_prefix=settings.discord.command_prefix, game_name=settings.discord.game_name, + test_guilds=settings.discord.test_guilds, ) bot.run(settings.discord.token)