From 54039a4b2581e3d473309d2a46176ea53796d3a8 Mon Sep 17 00:00:00 2001 From: pixeldeee Date: Fri, 18 Aug 2023 01:11:22 +0300 Subject: [PATCH] many updates with guild (+ GuildMember) --- pytecord/__init__.py | 2 +- pytecord/guild.py | 145 +++++++++++++++++------------------------ pytecord/interfaces.py | 21 +----- pytecord/user.py | 31 ++++++++- pytecord/utils.py | 4 +- 5 files changed, 93 insertions(+), 110 deletions(-) diff --git a/pytecord/__init__.py b/pytecord/__init__.py index 42c1a41..16c47c9 100644 --- a/pytecord/__init__.py +++ b/pytecord/__init__.py @@ -2,5 +2,5 @@ from .guild import Guild, GuildChannel, Message, MessageDeleteEvent from .role import Role from .reaction import Emoji, Sticker -from .user import User +from .user import User, GuildMember from .commands import Interaction diff --git a/pytecord/guild.py b/pytecord/guild.py index 159147e..a077171 100644 --- a/pytecord/guild.py +++ b/pytecord/guild.py @@ -1,7 +1,7 @@ from typing import Any, Literal from .interfaces import Object -from .user import User +from .user import User, GuildMember from .role import Role from .reaction import Emoji, Sticker from .utils import MessagePayload, get_snowflake, get_list_of_types, apost, rget @@ -78,6 +78,21 @@ def __int__(self) -> int: return self.__integer +class GuildPreview(Object): + def __init__(self, data: dict[str, Any], token: str) -> None: + self.id: int = get_snowflake(data.get('id')) + self.name: str = data.get('name') + self.icon: str = data.get('icon') + self.splash: str = data.get('splash') + self.discovery_splash: str = data.get('discovery_splash') + self.emojis: list[Emoji] = get_list_of_types(Emoji, data.get('emojis'), token) + self.features: list[str] = data.get('features') + self.approximate_member_count: int = data.get('approximate_member_count') + self.approximate_presence_count: int = data.get('approximate_presence_count') + self.description: str | None = data.get('description') + self.stickers: list[Sticker] = get_list_of_types(Sticker, data.get('stickers'), token) + + class Guild(Object): def __init__(self, data: dict[str, Any], token: str): self.id: int = get_snowflake(data.get('id')) @@ -96,8 +111,6 @@ def __init__(self, data: dict[str, Any], token: str): self.verification_level: VerificationLevel = VerificationLevel(data.get('verification_level')) self.default_message_notifications: DefaultMessageNotificationLevel = DefaultMessageNotificationLevel(data.get('default_message_notifications')) self.explicit_content_filter: ExplicitContentFilterLevel = ExplicitContentFilterLevel(data.get('explicit_content_filter')) - self.roles: list[Role] = get_list_of_types(Role, data.get('roles', [])) - self.emojis: list[Emoji] = get_list_of_types(Emoji, data.get('emojis', [])) self.features: list[str] = data.get('features') self.mfa_enabled: bool = data.get('mfa_level') == 1 self.application_id: int | None = get_snowflake('application_id') @@ -119,7 +132,6 @@ def __init__(self, data: dict[str, Any], token: str): self.approximate_presence_count: int | None = data.get('approximate_presence_count') self.welcome_screen: WelcomeScreen | None = WelcomeScreen(x, token) if (x := data.get('welcome_screen')) else None self.nsfw_level: NSFWLevel = NSFWLevel(data.get('nsfw_level')) - self.stickers: list[Sticker] = get_list_of_types(Sticker, data.get('stickers'), token) self.premium_progress_bar_enabled: bool = data.get('premium_progress_bar_enabled') self.safety_alerts_channel_id: int | None = get_snowflake('safety_alerts_channel_id') @@ -131,39 +143,59 @@ def __init__(self, data: dict[str, Any], token: str): def owner(self) -> User: data = rget(f'/users/{self.__owner_id}', self.__token).json() return User(data, self.__token) + + @property + def channels(self) -> 'list[GuildChannel]': + data = rget(f'/guilds/{self.id}/channels', self.__token).json() + return get_list_of_types(GuildChannel, data, self.__token) + + @property + def emojis(self) -> list[Emoji]: + data = rget(f'/guilds/{self.id}/emojis', self.__token).json() + return get_list_of_types(Emoji, data, self.__token) + + @property + def roles(self) -> list[Role]: + data = rget(f'/guilds/{self.id}/roles', self.__token).json() + return get_list_of_types(Role, data) + + @property + def stickers(self) -> list[Sticker]: + data = rget(f'/guilds/{self.id}/stickers', self.__token).json() + return get_list_of_types(Sticker, data, self.__token) - def __int__(self) -> int: - """ - Returns a guild id + @property + def preview(self) -> GuildPreview: + data = rget(f'/guilds/{self.id}/preview', self.__token).json() + return GuildPreview(data, self.__token) - ``` - >>> guild = Guild() - >>> int(guild) - ``` - """ + def __int__(self) -> int: return self.id def __str__(self) -> str: - """ - Returns a guild name - - ``` - >>> guild = Guild() - >>> str(guild) - ``` - """ return self.name def eval(self) -> dict[str, Any]: + return self.__data + + def search(self, query: str, limit: int = 1) -> list[GuildMember] | GuildMember | None: """ - Returns a dict representation of guild + Returns a list of guild member objects whose username or nickname starts with a provided string - ``` - >>> guild = Guild() - >>> guild.eval() - ``` + https://discord.com/developers/docs/resources/guild#search-guild-members """ - return self.__data + payload = { + 'query': query, + 'limit': limit + } + data = rget(f'/guilds/{self.id}/members/search', self.__token, payload) + + result = get_list_of_types(GuildMember, data, self.__token, __default=[]) + if limit == 1 and len(result) == 1: + result = result[0] + elif len(result) == 0: + result = None + return result class Overwrite: def __init__(self, data: dict[str, Any]) -> None: @@ -174,9 +206,6 @@ def __init__(self, data: dict[str, Any]) -> None: self.deny: permissions_set = data.get('deny') def __int__(self) -> int: - """ - Returns a role or member id (see .type and .str_type) - """ return self.id @@ -229,47 +258,15 @@ def guild(self) -> Guild | None: return None def __int__(self) -> int: - """ - Returns a channel id - - ``` - >>> channel = GuildChannel() - >>> int(channel) - ``` - """ return self.id def __str__(self) -> str: - """ - Returns a channel name - - ``` - >>> channel = GuildChannel() - >>> str(channel) - ``` - """ return self.name - def __getitem__(self, key: int): - """ - Fetch a message - - ``` - >>> channel = GuildChannel() - >>> message = channel[955886808095399996] - ``` - """ + def __getitem__(self, key: int) return self.fetch(key) def eval(self) -> dict[str, Any]: - """ - Returns a dict representation of channel - - ``` - >>> channel = GuildChannel() - >>> channel.eval() - ``` - """ return self.__data def fetch(self, id: int) -> 'Message': @@ -336,36 +333,12 @@ def channel(self) -> GuildChannel: return GuildChannel(data, self.__token) def __int__(self) -> int: - """ - Returns a message id - - ``` - >>> message = Message() - >>> int(message) - ``` - """ return self.id def __str__(self) -> str: - """ - Returns a message content - - ``` - >>> message = Message() - >>> str(message) - ``` - """ return self.content def eval(self) -> dict[str, Any]: - """ - Returns a dict representation of channel - - ``` - >>> message = Message() - >>> message.eval() - ``` - """ return self.__data async def reply(self, content: str) -> 'Message': diff --git a/pytecord/interfaces.py b/pytecord/interfaces.py index 828b119..28c99c8 100644 --- a/pytecord/interfaces.py +++ b/pytecord/interfaces.py @@ -11,23 +11,6 @@ def listen(self, request: 'GatewayOutput'): ... class Object(AbstractClass): @abstract_method - def __int__(self) -> int: - """ - Returns an object id - - ``` - >>> obj = Object() - >>> int(obj) - ``` - """ - + def __int__(self) -> int: ... @abstract_method - def eval(self) -> dict[str, Any]: - """ - Returns a dict representation of object - - ``` - >>> obj = Object() - >>> obj.eval() - ``` - """ + def eval(self) -> dict[str, Any]: ... diff --git a/pytecord/user.py b/pytecord/user.py index c847c57..904373c 100644 --- a/pytecord/user.py +++ b/pytecord/user.py @@ -1,8 +1,8 @@ -from typing import Any +from typing import Any, Literal from .interfaces import Object from .annotations import hash_str -from .utils import get_snowflake +from .utils import get_snowflake, rget class User(Object): def __init__(self, data: dict[str, Any], token: str) -> None: @@ -48,3 +48,30 @@ def __int__(self) -> int: ``` """ return self.id + + +class GuildMember(Object): + def __init__(self, data: dict[str, Any], token: str) -> None: + self.user: User | None = User(x, token) if (x := data.get('user')) else None + self.nick: str | None = data.get('nick') + self.avatar: str | None = data.get('avatar') + self.roles: int = data.get('roles') + self.joined_at: str = data.get('joined_at') + self.premium_since: str | None = data.get('premium_since') + self.deaf: bool = data.get('deaf') + self.mute: bool = data.get('mute') + self.flags: int = data.get('flags') + self.pending: bool | None = data.get('pending') + self.permissions: str | None = data.get('permissions') + self.communication_disabled_until: str | None = data.get('communication_disabled_until') + + self.__data = data + + def __int__(self) -> int | Literal[0]: + return self.user.id if self.user else 0 + + def eval(self) -> dict[str, Any]: + return self.__data + + def __str__(self) -> str | Literal['']: + return self.nick if self.nick else '' diff --git a/pytecord/utils.py b/pytecord/utils.py index f4a61d6..fd0dded 100644 --- a/pytecord/utils.py +++ b/pytecord/utils.py @@ -42,11 +42,11 @@ def eval(self) -> dict[str, Any]: def get_headers(token: str): return {'Authorization': f'Bot {token}', 'content-Type': 'application/json'} -def rget(endpoint: str, token: str = None, headers: dict[str, Any] = None): +def rget(endpoint: str, token: str = None, payload: dict[str, Any] = None, headers: dict[str, Any] = None): if token: headers = get_headers(token) - resp = get(f'https://discord.com/api/v{API_VERSION}{endpoint}', headers=headers) + resp = get(f'https://discord.com/api/v{API_VERSION}{endpoint}', headers=headers, json=payload) if str(resp.status_code).startswith('2'): return resp