Source code for discord_http.role

from typing import TYPE_CHECKING, Union, Optional

from . import utils
from .colour import Colour
from .file import File
from .object import PartialBase

if TYPE_CHECKING:
    from .flag import Permissions
    from .guild import PartialGuild, Guild
    from .http import DiscordAPI

MISSING = utils.MISSING

__all__ = (
    "PartialRole",
    "Role",
)


[docs] class PartialRole(PartialBase): def __init__( self, *, state: "DiscordAPI", id: int, guild_id: int ): super().__init__(id=int(id)) self._state = state self.guild_id: int = guild_id def __repr__(self) -> str: return f"<PartialRole id={self.id} guild_id={self.guild_id}>" @property def guild(self) -> "PartialGuild": """ `PartialGuild`: Returns the guild this role is in """ from .guild import PartialGuild return PartialGuild(state=self._state, id=self.guild_id) @property def mention(self) -> str: """ `str`: Returns a string that mentions the role """ return f"<@&{self.id}>"
[docs] async def add_role( self, user_id: int, *, reason: Optional[str] = None ) -> None: """ Add the role to someone Parameters ---------- user_id: `int` The user ID to add the role to reason: `Optional[str]` The reason for adding the role """ await self._state.query( "PUT", f"/guilds/{self.guild_id}/members/{user_id}/roles/{self.id}", res_method="text", reason=reason )
[docs] async def remove_role( self, user_id: int, *, reason: Optional[str] = None ) -> None: """ Remove the role from someone Parameters ---------- user_id: `int` The user ID to remove the role from reason: `Optional[str]` The reason for removing the role """ await self._state.query( "DELETE", f"/guilds/{self.guild_id}/members/{user_id}/roles/{self.id}", res_method="text", reason=reason )
[docs] async def delete( self, *, reason: Optional[str] = None ) -> None: """ Delete the role Parameters ---------- reason: `Optional[str]` The reason for deleting the role """ await self._state.query( "DELETE", f"/guilds/{self.guild_id}/roles/{self.id}", reason=reason, res_method="text" )
[docs] async def edit( self, *, name: Optional[str] = MISSING, colour: Optional[Union[Colour, int]] = MISSING, hoist: Optional[bool] = MISSING, mentionable: Optional[bool] = MISSING, positions: Optional[int] = MISSING, permissions: Optional["Permissions"] = MISSING, unicode_emoji: Optional[str] = MISSING, icon: Optional[Union[File, bytes]] = MISSING, reason: Optional[str] = None, ) -> "Role": """ Edit the role Parameters ---------- name: `Optional[str]` The new name of the role colour: `Optional[Union[Colour, int]]` The new colour of the role hoist: `Optional[bool]` Whether the role should be displayed separately in the sidebar mentionable: `Optional[bool]` Whether the role should be mentionable unicode_emoji: `Optional[str]` The new unicode emoji of the role positions: `Optional[int]` The new position of the role permissions: `Optional[Permissions]` The new permissions for the role icon: `Optional[File]` The new icon of the role reason: `Union[str]` The reason for editing the role Returns ------- `Union[Role, PartialRole]` The edited role and its data Raises ------ `ValueError` - If both `unicode_emoji` and `icon` are set - If there were no changes applied to the role - If position was changed, but Discord API returned invalid data """ payload = {} _role: Optional["Role"] = None if name is not MISSING: payload["name"] = name if colour is not MISSING: if isinstance(colour, Colour): payload["colour"] = colour.value else: payload["colour"] = colour if permissions is not MISSING: payload["permissions"] = permissions.value if hoist is not MISSING: payload["hoist"] = hoist if mentionable is not MISSING: payload["mentionable"] = mentionable if unicode_emoji is not MISSING: payload["unicode_emoji"] = unicode_emoji if icon is not MISSING: payload["icon"] = ( utils.bytes_to_base64(icon) if icon else None ) if ( unicode_emoji is not MISSING and icon is not MISSING ): raise ValueError("Cannot set both unicode_emoji and icon") if positions is not MISSING: r = await self._state.query( "PATCH", f"/guilds/{self.guild_id}/roles", json={ "id": str(self.id), "position": positions }, reason=reason ) find_role: Optional[dict] = next(( r for r in r.response if r["id"] == str(self.id) ), None) if not find_role: raise ValueError( "Could not find role in response " "(Most likely Discord API bug)" ) _role = Role( state=self._state, guild=self.guild, data=find_role ) if payload: r = await self._state.query( "PATCH", f"/guilds/{self.guild_id}/roles/{self.id}", json=payload, reason=reason ) _role = Role( state=self._state, guild=self.guild, data=r.response ) if not _role: raise ValueError( "There were no changes applied to the role. " "No edits were taken" ) return _role
[docs] class Role(PartialRole): def __init__( self, *, state: "DiscordAPI", guild: Union["PartialGuild", "Guild"], data: dict ): super().__init__(state=state, id=data["id"], guild_id=guild.id) self.color: int = int(data["color"]) self.colour: int = int(data["color"]) self.name: str = data["name"] self.hoist: bool = data["hoist"] self.managed: bool = data["managed"] self.mentionable: bool = data["mentionable"] self.permissions: int = int(data["permissions"]) self.position: int = int(data["position"]) self.tags: dict = data.get("tags", {}) self.bot_id: Optional[int] = utils.get_int(data, "bot_id") self.integration_id: Optional[int] = utils.get_int(data, "integration_id") self.subscription_listing_id: Optional[int] = utils.get_int(data, "subscription_listing_id") self._premium_subscriber: bool = "premium_subscriber" in self.tags self._available_for_purchase: bool = "available_for_purchase" in self.tags self._guild_connections: bool = "guild_connections" in self.tags def __str__(self) -> str: return self.name def __repr__(self) -> str: return f"<Role id={self.id} name='{self.name}'>"
[docs] def is_bot_managed(self) -> bool: """ `bool`: Returns whether the role is bot managed """ return self.bot_id is not None
[docs] def is_integration(self) -> bool: """ `bool`: Returns whether the role is an integration """ return self.integration_id is not None
[docs] def is_premium_subscriber(self) -> bool: """ `bool`: Returns whether the role is a premium subscriber """ return self._premium_subscriber
[docs] def is_available_for_purchase(self) -> bool: """ `bool`: Returns whether the role is available for purchase """ return self._available_for_purchase
[docs] def is_guild_connection(self) -> bool: """ `bool`: Returns whether the role is a guild connection """ return self._guild_connections