# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence. """The !papież command: a random pope, his portrait, his Latin name, his article. The list this draws from is the same signal_bot/popes.json the version ladder is built on, so the bot posts the popes it is named after. """ from __future__ import annotations import secrets from typing import TYPE_CHECKING, Final from signal_bot.animals import load_aliases from signal_bot.versioning import POPES, article_url, pope_line if TYPE_CHECKING: from signal_bot.decorators import Decorator from signal_bot.portraits import PortraitCache from signal_bot.registry import CommandContext, CommandRegistry, Handler from signal_bot.versioning import Pope COMMAND_NAME: Final = "pope" DESCRIPTION: Final = "losowy papież z portretem i imieniem po łacinie" def random_pope() -> Pope: """Return one pope, uniformly at random. secrets rather than random for the reason animals.paged_url gives: the choice is not security-sensitive, but ruff's ALL rule set flags `random` and this repo forbids the noqa that would silence it. """ return POPES[secrets.randbelow(len(POPES))] def caption_for(pope: Pope) -> str: """Return the message that rides along with the portrait.""" return f"{pope.name} — {pope.latin}\n{pope_line(pope)}\n{article_url(pope)}" def pope_handler(cache: PortraitCache) -> Handler: """Build the handler that posts a random pope.""" async def handler(ctx: CommandContext) -> None: pope = random_pope() image = await cache.get_base64(pope) await ctx.reply_image(image, caption_for(pope)) return handler def register_pope_command( registry: CommandRegistry, cache: PortraitCache, *, decorate: Decorator | None = None, aliases: dict[str, list[str]] | None = None, ) -> None: """Register !papież under every trigger aliases.json gives it.""" table = load_aliases() if aliases is None else aliases handler = pope_handler(cache) if decorate is not None: handler = decorate(handler) registry.register(COMMAND_NAME, table[COMMAND_NAME], handler, DESCRIPTION)