1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 18:23:12 +00:00
Lumi/stubs/reactionmenu/abc.pyi
2024-08-29 07:03:25 -04:00

816 lines
27 KiB
Python

"""
This type stub file was generated by pyright.
"""
import abc
import discord
from typing import Any, Callable, ClassVar, Final, Generic, List, Literal, NamedTuple, Optional, Set, TYPE_CHECKING, Tuple, TypeVar, Union, overload
from datetime import datetime
from typing_extensions import Self
from collections.abc import Sequence
from enum import Enum
from discord.ext.commands import Context
from discord.utils import MISSING
from .decorators import ensure_not_primed
from .errors import *
"""
MIT License
Copyright (c) 2021-present @defxult
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
if TYPE_CHECKING:
...
_DYNAMIC_EMBED_LIMIT: Final[int] = ...
_DEFAULT_STYLE: Final[str] = ...
DEFAULT_BUTTONS = ...
DEFAULT = MISSING
GB = TypeVar('GB', bound='_BaseButton')
M = TypeVar('M', bound='_BaseMenu')
class Page:
"""Represents a single "page" in the pagination process
.. added:: v3.1.0
"""
__slots__ = ...
def __init__(self, *, content: Optional[str] = ..., embed: Optional[discord.Embed] = ..., files: Optional[List[discord.File]] = ...) -> None:
...
def __repr__(self) -> str:
...
@staticmethod
def from_embeds(embeds: Sequence[discord.Embed]) -> List[Page]:
"""|static method|
Converts a sequence of embeds into a list of :class:`Page`
"""
...
class PaginationEmojis:
"""A set of basic emojis for your convenience to use for your buttons emoji
- ◀️ as `BACK_BUTTON`
- ▶️ as `NEXT_BUTTON`
- ⏪ as `FIRST_PAGE`
- ⏩ as `LAST_PAGE`
- 🔢 as `GO_TO_PAGE`
- ⏹️ as `END_SESSION`
"""
BACK_BUTTON: ClassVar[str] = ...
NEXT_BUTTON: ClassVar[str] = ...
FIRST_PAGE: ClassVar[str] = ...
LAST_PAGE: ClassVar[str] = ...
GO_TO_PAGE: ClassVar[str] = ...
END_SESSION: ClassVar[str] = ...
class _PageController:
def __init__(self, pages: List[Page]) -> None:
...
@property
def current_page(self) -> Page:
...
@property
def total_pages(self) -> int:
"""Return the total amount of pages registered to the menu"""
...
def validate_index(self) -> Page:
"""If the index is out of bounds, assign the appropriate values so the pagination process can continue and return the associated page"""
...
def skip_loop(self, action: str, amount: int) -> None:
"""Using `self.index += amount` does not work because this library is used to operating on a +-1 basis. This loop
provides a simple way to still operate on the +-1 standard.
"""
...
def skip(self, skip: _BaseButton.Skip) -> Page:
"""Return the page that the skip value was set to"""
...
def next(self) -> Page:
"""Return the next page in the pagination process"""
...
def prev(self) -> Page:
"""Return the previous page in the pagination process"""
...
def first_page(self) -> Page:
"""Return the first page in the pagination process"""
...
def last_page(self) -> Page:
"""Return the last page in the pagination process"""
...
class _MenuType(Enum):
TypeEmbed = ...
TypeEmbedDynamic = ...
TypeText = ...
MenuType = _MenuType
class _LimitDetails(NamedTuple):
limit: int
per: str
message: str
set_by_user: bool = ...
@classmethod
def default(cls) -> Self:
...
class _BaseButton(Generic[GB], metaclass=abc.ABCMeta):
Emojis: ClassVar[PaginationEmojis] = ...
def __init__(self, name: str, event: Optional[_BaseButton.Event], skip: _BaseButton.Skip) -> None:
...
@property
@abc.abstractmethod
def menu(self):
...
@property
def clicked_by(self) -> Set[discord.Member]:
"""
Returns
-------
Set[:class:`discord.Member`]: The members who clicked the button
"""
...
@property
def total_clicks(self) -> int:
"""
Returns
-------
:class:`int`: The amount of clicks on the button
"""
...
@property
def last_clicked(self) -> Optional[datetime]:
"""
Returns
-------
Optional[:class:`datetime.datetime`]: The time in UTC for when the button was last clicked. Can be :class:`None` if the button has not been clicked
"""
...
class Skip:
"""Initialize a skip button with the appropriate values
Parameters
----------
action: :class:`str`
Whether to go forward in the pagination process ("+") or backwards ("-")
amount: :class:`int`
The amount of pages to skip. Must be >= 1. If value is <= 0, it is implicitly set to 2
"""
def __init__(self, action: Literal['+', '-'], amount: int) -> None:
...
class Event:
"""Set a button to be disabled or removed when it has been pressed a certain amount of times. If the button is a :class:`ReactionButton`, only the "remove" event is available
Parameters
----------
event: :class:`str`
The action to take. Can either be "disable" or "remove"
value: :class:`int`
The amount set for the specified event. Must be >= 1. If value is <= 0, it is implicitly set to 1"""
_DISABLE = ...
_REMOVE = ...
def __init__(self, event_type: Literal['disable', 'remove'], value: int) -> None:
...
class _BaseMenu(metaclass=abc.ABCMeta):
TypeEmbed: Final[_MenuType] = ...
TypeEmbedDynamic: Final[_MenuType] = ...
TypeText: Final[_MenuType] = ...
_sessions_limit_details = ...
_active_sessions: List[Self]
def __init__(self, method: Union[Context, discord.Interaction], /, menu_type: _MenuType, **kwargs) -> None:
...
@abc.abstractmethod
def remove_all_buttons(self):
...
@abc.abstractmethod
def get_button(self):
...
@abc.abstractmethod
def remove_button(self):
...
@abc.abstractmethod
def add_button(self):
...
@abc.abstractmethod
def add_buttons(self):
...
@abc.abstractmethod
def stop(self):
...
@abc.abstractmethod
async def start(self):
...
@abc.abstractmethod
async def quick_start(cls):
...
@staticmethod
def separate(values: Sequence[Any]) -> Tuple[List[discord.Embed], List[str]]:
"""|static method|
Sorts all embeds and strings into a single tuple
Parameters
----------
values: Sequence[`Any`]
The values to separate
Returns
-------
Tuple[List[:class:`discord.Embed`], List[:class:`str`]]
Example
-------
>>> embeds, strings = .separate([...])
"""
...
@staticmethod
def all_embeds(values: Sequence[Any]) -> bool:
"""|static method|
Tests to see if all items in the sequence are of type :class:`discord.Embed`
Parameters
----------
values: Sequence[`Any`]
The values to test
Returns
-------
:class:`bool`: Can return `False` if the sequence is empty
"""
...
@staticmethod
def all_strings(values: Sequence[Any]) -> bool:
"""|static method|
Tests to see if all items in the sequence are of type :class:`str`
Parameters
----------
values: Sequence[`Any`]
The values to test
Returns
-------
:class:`bool`: Can return `False` if the sequence is empty
"""
...
@classmethod
def remove_limit(cls) -> None:
"""|class method|
Remove the limits currently set for menu's
"""
...
@classmethod
def get_all_dm_sessions(cls) -> List[Self]:
"""|class method|
Retrieve all active DM menu sessions
Returns
-------
A :class:`list` of active DM menu sessions that are currently running. Can be an empty list if there are no active DM sessions
"""
...
@classmethod
def get_all_sessions(cls) -> List[Self]:
"""|class method|
Retrieve all active menu sessions
Returns
-------
A :class:`list` of menu sessions that are currently running. Can be an empty list if there are no active sessions
"""
...
@classmethod
def get_session(cls, name: str) -> List[Self]:
"""|class method|
Get a menu instance by it's name
Parameters
----------
name: :class:`str`
The name of the menu to return
Returns
-------
A :class:`list` of menu sessions that are currently running that match the supplied :param:`name`. Can be an empty list if there are no active sessions that matched the :param:`name`
"""
...
@classmethod
def get_sessions_count(cls) -> int:
"""|class method|
Returns the number of active sessions
Returns
-------
:class:`int`: The amount of menu sessions that are active
"""
...
@classmethod
def set_sessions_limit(cls, limit: int, per: Literal['channel', 'guild', 'member'] = ..., message: str = ...) -> None:
"""|class method|
Sets the amount of menu sessions that can be active at the same time per guild, channel, or member. This applies to both :class:`ReactionMenu` & :class:`ViewMenu`
Parameters
----------
limit: :class:`int`
The amount of menu sessions allowed
per: :class:`str`
How menu sessions should be limited. Options: "channel", "guild", or "member"
message: :class:`str`
Message that will be sent informing users about the menu limit when the limit is reached. Can be :class:`None` for no message
Raises
------
- `IncorrectType`: The :param:`limit` parameter was not of type :class:`int`
- `MenuException`: The value of :param:`per` was not valid or the limit was not greater than or equal to one
"""
...
@classmethod
async def stop_session(cls, name: str, include_all: bool = ...) -> None:
"""|coro class method|
Stop a specific menu with the supplied name
Parameters
----------
name: :class:`str`
The menus name
include_all: :class:`bool`
If set to `True`, it stops all menu sessions with the supplied :param:`name`. If `False`, stops only the most recently started menu with the supplied :param:`name`
Raises
------
- `MenuException`: The session with the supplied name was not found
"""
...
@classmethod
async def stop_all_sessions(cls) -> None:
"""|coro class method|
Stops all menu sessions that are currently running
"""
...
@classmethod
def get_menu_from_message(cls, message_id: int, /) -> Optional[Self]:
"""|class method|
Return the menu object associated with the message with the given ID
Parameters
----------
message_id: :class:`int`
The `discord.Message.id` from the menu message
Returns
-------
The menu object. Can be :class:`None` if the menu was not found in the list of active menu sessions
"""
...
@property
def rows(self) -> Optional[List[str]]:
"""
Returns
-------
Optional[List[:class:`str`]]: All rows that's been added to the menu. Can return `None` if the menu has not started or the `menu_type` is not `TypeEmbedDynamic`
.. added: v3.1.0
"""
...
@property
def menu_type(self) -> str:
"""
Returns
-------
:class:`str`: The `menu_type` you set via the constructor. This will either be `TypeEmbed`, `TypeEmbedDynamic`, or `TypeText`
.. added:: v3.1.0
"""
...
@property
def last_viewed(self) -> Optional[Page]:
"""
Returns
-------
Optional[:class:`Page`]: The last page that was viewed in the pagination process. Can be :class:`None` if the menu has not been started
"""
...
@property
def owner(self) -> Union[discord.Member, discord.User]:
"""
Returns
-------
Union[:class:`discord.Member`, :class:`discord.User`]: The owner of the menu (the person that started the menu). If the menu was started in a DM, this will return :class:`discord.User`
"""
...
@property
def total_pages(self) -> int:
"""
Returns
-------
:class:`int`: The amount of pages that have been added to the menu. If the `menu_type` is :attr:`TypeEmbedDynamic`, the amount of pages is not known until AFTER the menu has started.
If attempted to retrieve the value before a dynamic menu has started, this will return a value of -1
"""
...
@property
def pages(self) -> Optional[List[Page]]:
"""
Returns
-------
Optional[List[:class:`Page`]]: The pages currently applied to the menu. Can return :class:`None` if there are no pages
Note: If the `menu_type` is :attr:`TypeEmbedDynamic`, the pages aren't known until after the menu has started
"""
...
@property
def message(self) -> Optional[Union[discord.Message, discord.InteractionMessage]]:
"""
Returns
-------
Optional[Union[:class:`discord.Message`, :class:`discord.InteractionMessage`]]: The menu's message object. Can be :class:`None` if the menu has not been started
"""
...
@property
def is_running(self) -> bool:
"""
Returns
-------
:class:`bool`: `True` if the menu is currently running, `False` otherwise
"""
...
@property
def in_dms(self) -> bool:
"""
Returns
-------
:class:`bool`: If the menu was started in a DM
"""
...
def randomize_embed_colors(self) -> None:
"""Randomize the color of all the embeds that have been added to the menu
Raises
------
- `MenuException`: The `menu_type` was not of `TypeEmbed`
.. added:: v3.1.0
"""
...
def set_page_director_style(self, style_id: int, separator: str = ...) -> None:
"""Set how the page numbers dictating what page you are on (in the footer of an embed/regular message) are displayed
Parameters
----------
style_id: :class:`int`
Varying formats of how the page director can be presented. The following ID's are available:
- `1` = Page 1/10
- `2` = Page 1 out of 10
- `3` = 1 out of 10
- `4` = 1 • 10
- `5` = 1 » 10
- `6` = 1 | 10
- `7` = 1 : 10
- `8` = 1 - 10
- `9` = 1 / 10
- `10` = 1 🔹 10
- `11` = 1 🔸 10
separator: :class:`str`
The separator between the page director and any text you may have in the embed footer. The default separator is ":". It should be noted that whichever separator you assign,
if you wish to have spacing between the page director and the separator, you must place the space inside the string yourself as such: " :"
Raises
------
- `MenuException`: The :param:`style_id` value was not valid
"""
...
async def wait_until_closed(self) -> None:
"""|coro|
Waits until the menu session ends using `.stop()` or when the menu times out. This should not be used inside relays
.. added:: v3.0.1
"""
...
@ensure_not_primed
def add_from_messages(self, messages: Sequence[discord.Message]) -> None:
"""Add pages to the menu using the message object itself
Parameters
----------
messages: Sequence[:class:`discord.Message`]
A sequence of discord message objects
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: The messages provided did not have the correct values. For example, the `menu_type` was set to `TypeEmbed`, but the messages you've provided only contains text. If the `menu_type` is `TypeEmbed`, only messages with embeds should be provided
- `IncorrectType`: All messages were not of type :class:`discord.Message`
"""
...
@ensure_not_primed
async def add_from_ids(self, messageable: discord.abc.Messageable, message_ids: Sequence[int]) -> None:
"""|coro|
Add pages to the menu using the IDs of messages. This only grabs embeds (if the `menu_type` is :attr:`TypeEmbed`) or the content (if the `menu_type` is :attr:`TypeText`) from the message
Parameters
----------
messageable: :class:`discord.abc.Messageable`
A discord :class:`Messageable` object (:class:`discord.TextChannel`, :class:`commands.Context`, etc.)
message_ids: Sequence[:class:`int`]
The messages to fetch
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: The message IDs provided did not have the correct values when fetched. For example, the `menu_type` was set to `TypeEmbed`, but the messages you've provided for the library to fetch only contains text. If the `menu_type` is `TypeEmbed`, only messages with embeds should be provided
- `MenuException`: An error occurred when attempting to fetch a message or not all :param:`message_ids` were of type int
"""
...
@ensure_not_primed
def clear_all_row_data(self) -> None:
"""Delete all the data thats been added using :meth:`add_row()`
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: This method was called but the menus `menu_type` was not :attr:`TypeEmbedDynamic`
"""
...
@ensure_not_primed
def add_row(self, data: str) -> None:
"""Add text to the embed page by rows of data
Parameters
----------
data: :class:`str`
The data to add
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: This method was called but the menus `menu_type` was not :attr:`TypeEmbedDynamic`
- `MissingSetting`: The kwarg "rows_requested" (int) has not been set for the menu
"""
...
@ensure_not_primed
def set_main_pages(self, *embeds: discord.Embed) -> None:
"""On a menu with a `menu_type` of :attr:`TypeEmbedDynamic`, set the pages you would like to show first. These embeds will be shown before the embeds that contain your data
Parameters
----------
*embeds: :class:`discord.Embed`
An argument list of :class:`discord.Embed` objects
Raises
------
- `MenuSettingsMismatch`: Tried to use method on a menu that was not of `menu_type` :attr:`TypeEmbedDynamic`
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuException`: The "embeds" parameter was empty. At least one value is needed
- `IncorrectType`: All values in the argument list were not of type :class:`discord.Embed`
"""
...
@ensure_not_primed
def set_last_pages(self, *embeds: discord.Embed) -> None:
"""On a menu with a `menu_type` of :attr:`TypeEmbedDynamic`, set the pages you would like to show last. These embeds will be shown after the embeds that contain your data
Parameters
----------
*embeds: :class:`discord.Embed`
An argument list of :class:`discord.Embed` objects
Raises
------
- `MenuSettingsMismatch`: Tried to use method on a menu that was not of `menu_type` :attr:`TypeEmbedDynamic`
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuException`: The "embeds" parameter was empty. At least one value is needed
- `IncorrectType`: All values in the argument list were not of type :class:`discord.Embed`
"""
...
@ensure_not_primed
def add_page(self, embed: Optional[discord.Embed] = ..., content: Optional[str] = ..., files: Optional[List[discord.File]] = ...) -> None:
"""Add a page to the menu
Parameters
----------
embed: Optional[:class:`discord.Embed`]
The embed of the page
content: Optional[:class:`str`]
The text that appears above an embed in a message
files: Optional[Sequence[:class:`discord.File`]]
Files you'd like to attach to the page
Raises
------
- `MenuException`: Attempted to add a page with no parameters
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: The page being added does not match the menus `menu_type`
.. changes::
v3.1.0
Added parameter content
Added parameter embed
Added parameter files
Removed parameter "page"
"""
...
@overload
def add_pages(self, pages: Sequence[discord.Embed]) -> None:
...
@overload
def add_pages(self, pages: Sequence[str]) -> None:
...
@ensure_not_primed
def add_pages(self, pages: Sequence[Union[discord.Embed, str]]) -> None:
"""Add multiple pages to the menu at once
Parameters
----------
pages: Sequence[Union[:class:`discord.Embed`, :class:`str`]]
The pages to add. Can only be used when the menus `menu_type` is :attr:`TypeEmbed` (adding a :class:`discord.Embed`)
or :attr:`TypeText` (adding a :class:`str`)
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `MenuSettingsMismatch`: The page being added does not match the menus `menu_type`
"""
...
@ensure_not_primed
def remove_all_pages(self) -> None:
"""Remove all pages from the menu
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
"""
...
@ensure_not_primed
def remove_page(self, page_number: int) -> None:
"""Remove a page from the menu
Parameters
----------
page_number: :class:`int`
The page to remove
Raises
------
- `MenuAlreadyRunning`: Attempted to call method after the menu has already started
- `InvalidPage`: The page associated with the given page number was not valid
"""
...
def set_on_timeout(self, func: Callable[[M], None]) -> None:
"""Set the function to be called when the menu times out
Parameters
----------
func: Callable[[:type:`M`]], :class:`None`]
The function object that will be called when the menu times out. The function should contain a single positional argument
and should not return anything. The argument passed to that function is an instance of the menu.
Raises
------
- `IncorrectType`: Parameter "func" was not a callable object
"""
...
def remove_on_timeout(self) -> None:
"""Remove the timeout call to the function you have set when the menu times out"""
...
def set_relay(self, func: Callable[[NamedTuple], None], *, only: Optional[List[GB]] = ...) -> None:
"""Set a function to be called with a given set of information when a button is pressed on the menu. The information passed is `RelayPayload`, a named tuple.
The named tuple contains the following attributes:
- `member`: The :class:`discord.Member` object of the person who pressed the button. Could be :class:`discord.User` if the menu was started in a DM
- `button`: Depending on the menu instance, the :class:`ReactionButton` or :class:`ViewButton` object of the button that was pressed
Parameters
----------
func: Callable[[:class:`NamedTuple`], :class:`None`]
The function should only contain a single positional argument. Command functions (`@bot.command()`) not supported
only: Optional[List[:generic:`GB`]]
A list of buttons (`GB`) associated with the current menu instance. If the menu instance is :class:`ReactionMenu`, this should be a list of :class:`ReactionButton`
and vice-versa for :class:`ViewMenu` instances. If this is :class:`None`, all buttons on the menu will be relayed. If set, only button presses from those specified buttons will be relayed
Raises
------
- `IncorrectType`: The :param:`func` argument provided was not callable
"""
...
def remove_relay(self) -> None:
"""Remove the relay that's been set"""
...