Created
May 28, 2025 00:48
-
-
Save i-am-unknown-81514525/8d84ed916f3943119759354a76bf1677 to your computer and use it in GitHub Desktop.
d.py DynamicItem Base Class implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from typing import Callable, Coroutine, Type, TypeVar, Self, overload, Any, Optional, Generic, ParamSpec | |
| K = TypeVar("K", bound=Item) | |
| R = TypeVar("R", bound="BaseOnboardingDynamicItem") | |
| P = ParamSpec("P") | |
| class BaseOnboardingDynamicItem(DynamicItem[K], Generic[K], template=r"onboarding::(\d+)::(\d+)::[a-zA-Z\d_]*::(\d+)"): | |
| ACTIONS: dict[Type["BaseOnboardingDynamicItem"], str] = {} | |
| generate_appearance: Callable[[P], ...] | |
| def __init_subclass__(cls, action_name: str): | |
| if any(map(lambda x: x not in string.ascii_letters + string.digits + "_", action_name)): | |
| raise ValueError(f"Contain invalid {action_name=}, only alphanumerical character and underscore allowed") | |
| template = ( | |
| r"onboarding::(\d+)::(\d+)::" + action_name + r"::(\d+)" | |
| ) # prefix::current_page::next_page::action_name::author | |
| BaseOnboardingDynamicItem.ACTIONS[cls] = action_name | |
| super().__init_subclass__(template=template) | |
| def __init__(self, current_page: int, next_page: int, author_id: int, *args: P.args, **kwargs: P.kwargs): | |
| self.current_page = current_page | |
| self.next_page = next_page | |
| self.author_id = author_id | |
| super().__init__(item=self.generate_appearance(*args, **kwargs)) | |
| def generate_appearance(self, *args, **kwargs) -> K: | |
| raise NotImplementedError("Require custom implement") | |
| @property | |
| def custom_id(self) -> str: | |
| return f"onboarding::{self.current_page}::{self.next_page}::{BaseOnboardingDynamicItem.ACTIONS[self.__class__]}::{self.author_id}" | |
| @classmethod | |
| async def from_custom_id( | |
| cls: Type[Self], interaction: Interaction[ClientT], item: Item[Any], match: re.Match[str], / | |
| ) -> Self: | |
| return cls(int(match.group(1)), int(match.group(2)), int(match.group(3))) | |
| async def update( | |
| self, interaction: discord.Interaction[AutoShardedBot], db: Optional[DB] = None, hasDefer: bool = True | |
| ): | |
| if not hasDefer: | |
| await interaction.response.defer() | |
| if not db: | |
| db = await db_manager.get_config(interaction.guild_id, bot=interaction.client) | |
| embed, view = page_generator(db, self.next_page, self.author_id) | |
| message = interaction.message | |
| if message: | |
| view.set_message(message) | |
| await self.content_update(interaction, embed, view) | |
| async def content_update(self, interaction: discord.Interaction, embed: Embed | None, view: View | None): | |
| if not embed and not view: | |
| return | |
| if embed and view: | |
| return await interaction.edit_original_response(embed=embed, view=view) | |
| if embed and not view: | |
| return await interaction.edit_original_response(embed=embed) | |
| if view and not embed: | |
| return await interaction.edit_original_response(view=view) | |
| async def callback(self, interaction: Interaction[AutoShardedBot]) -> Any: | |
| await self.update(interaction, hasDefer=False) | |
| return | |
| def loader(bot: Bot | AutoShardedBot): | |
| for cls in BaseOnboardingDynamicItem.ACTIONS: | |
| bot.add_dynamic_items(cls) | |
| def unloader(bot: Bot | AutoShardedBot): | |
| for cls in BaseOnboardingDynamicItem.ACTIONS: | |
| bot.remove_dynamic_items(cls) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Btw GPL-3.0 license applied