implement /pwiki-lookup command

This commit is contained in:
Denis-Cosmin Nutiu 2024-01-26 20:41:56 +02:00
parent 0ab4170916
commit 480c8993a8
7 changed files with 108 additions and 1 deletions

View file

@ -1,4 +1,5 @@
discord: discord:
game_name: "Pathfinder 2E" game_name: "Pathfinder 2E"
test_guilds: []
command_prefix: "." command_prefix: "."
token: <your discord token> token: <your discord token>

View file

@ -66,6 +66,7 @@ class DiscordSettings(BaseModel):
game_name: str = Field(default="RPG") game_name: str = Field(default="RPG")
token: str = Field() token: str = Field()
command_prefix: str = Field(default=".") command_prefix: str = Field(default=".")
test_guilds: list[int] = Field(default=[])
class Settings(BaseSettings): class Settings(BaseSettings):

View file

@ -4,6 +4,7 @@ import disnake
from disnake.ext.commands import bot from disnake.ext.commands import bot
from src.bot.discord.commands.dice import DiceCog from src.bot.discord.commands.dice import DiceCog
from src.bot.discord.commands.pathfinder_wiki import PathfinderWikiCog
class NucuBot(bot.Bot): class NucuBot(bot.Bot):
@ -12,14 +13,18 @@ class NucuBot(bot.Bot):
self._logger = logging.getLogger(__name__) self._logger = logging.getLogger(__name__)
@staticmethod @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() intents = disnake.Intents.all()
discord_bot = NucuBot( discord_bot = NucuBot(
intents=intents, intents=intents,
command_prefix=command_prefix, command_prefix=command_prefix,
activity=disnake.Game(name=game_name), activity=disnake.Game(name=game_name),
test_guilds=test_guilds,
) )
discord_bot.add_cog(DiceCog(discord_bot)) discord_bot.add_cog(DiceCog(discord_bot))
discord_bot.add_cog(PathfinderWikiCog(discord_bot))
return discord_bot return discord_bot
async def on_ready(self): async def on_ready(self):

View file

@ -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}")

View file

View file

@ -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())

View file

@ -9,6 +9,7 @@ def main():
bot = NucuBot.create( bot = NucuBot.create(
command_prefix=settings.discord.command_prefix, command_prefix=settings.discord.command_prefix,
game_name=settings.discord.game_name, game_name=settings.discord.game_name,
test_guilds=settings.discord.test_guilds,
) )
bot.run(settings.discord.token) bot.run(settings.discord.token)