mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-06-19 03:26:39 +00:00
Create a base class for Chat
This commit is contained in:
parent
c4d399e32d
commit
04806a2a4a
@ -1,5 +1,5 @@
|
|||||||
from .async_list import AsyncList
|
from .async_list import AsyncList
|
||||||
from .chat import Channel, Chat, ChatLike, Group, RestrictionReason, User
|
from .chat import Channel, Chat, ChatLike, Group, User
|
||||||
from .dialog import Dialog
|
from .dialog import Dialog
|
||||||
from .draft import Draft
|
from .draft import Draft
|
||||||
from .file import File, InFileLike, OutFileLike, OutWrapper
|
from .file import File, InFileLike, OutFileLike, OutWrapper
|
||||||
@ -17,7 +17,6 @@ __all__ = [
|
|||||||
"Chat",
|
"Chat",
|
||||||
"ChatLike",
|
"ChatLike",
|
||||||
"Group",
|
"Group",
|
||||||
"RestrictionReason",
|
|
||||||
"User",
|
"User",
|
||||||
"Dialog",
|
"Dialog",
|
||||||
"Draft",
|
"Draft",
|
||||||
|
@ -2,10 +2,10 @@ from typing import Union
|
|||||||
|
|
||||||
from ....session import PackedChat
|
from ....session import PackedChat
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
|
from .chat import Chat
|
||||||
from .group import Group
|
from .group import Group
|
||||||
from .user import RestrictionReason, User
|
from .user import User
|
||||||
|
|
||||||
Chat = Union[Channel, Group, User]
|
|
||||||
ChatLike = Union[Chat, PackedChat, int, str]
|
ChatLike = Union[Chat, PackedChat, int, str]
|
||||||
|
|
||||||
__all__ = ["Chat", "ChatLike", "Channel", "Group", "RestrictionReason", "User"]
|
__all__ = ["Chat", "ChatLike", "Channel", "Group", "User"]
|
||||||
|
@ -3,9 +3,10 @@ from typing import Optional, Self, Union
|
|||||||
from ....session import PackedChat, PackedType
|
from ....session import PackedChat, PackedType
|
||||||
from ....tl import abcs, types
|
from ....tl import abcs, types
|
||||||
from ..meta import NoPublicConstructor
|
from ..meta import NoPublicConstructor
|
||||||
|
from .chat import Chat
|
||||||
|
|
||||||
|
|
||||||
class Channel(metaclass=NoPublicConstructor):
|
class Channel(Chat, metaclass=NoPublicConstructor):
|
||||||
"""
|
"""
|
||||||
A broadcast channel.
|
A broadcast channel.
|
||||||
|
|
||||||
@ -32,10 +33,25 @@ class Channel(metaclass=NoPublicConstructor):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("unexpected case")
|
raise RuntimeError("unexpected case")
|
||||||
|
|
||||||
|
# region Overrides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> int:
|
def id(self) -> int:
|
||||||
return self._raw.id
|
return self._raw.id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
"""
|
||||||
|
The channel's title.
|
||||||
|
|
||||||
|
This property is always present, but may be the empty string.
|
||||||
|
"""
|
||||||
|
return self._raw.title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def username(self) -> Optional[str]:
|
||||||
|
return getattr(self._raw, "username", None)
|
||||||
|
|
||||||
def pack(self) -> Optional[PackedChat]:
|
def pack(self) -> Optional[PackedChat]:
|
||||||
if self._raw.access_hash is None:
|
if self._raw.access_hash is None:
|
||||||
return None
|
return None
|
||||||
@ -48,14 +64,4 @@ class Channel(metaclass=NoPublicConstructor):
|
|||||||
access_hash=None,
|
access_hash=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
# endregion Overrides
|
||||||
def title(self) -> str:
|
|
||||||
return getattr(self._raw, "title", None) or ""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def full_name(self) -> str:
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
@property
|
|
||||||
def username(self) -> Optional[str]:
|
|
||||||
return getattr(self._raw, "username", None)
|
|
||||||
|
60
client/src/telethon/_impl/client/types/chat/chat.py
Normal file
60
client/src/telethon/_impl/client/types/chat/chat.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import abc
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from ....session import PackedChat
|
||||||
|
|
||||||
|
|
||||||
|
class Chat(abc.ABC):
|
||||||
|
"""
|
||||||
|
The base class for all chat types.
|
||||||
|
|
||||||
|
This will either be a :class:`User`, :class:`Group` or :class:`Channel`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abc.abstractmethod
|
||||||
|
def id(self) -> int:
|
||||||
|
"""
|
||||||
|
The chat's integer identifier.
|
||||||
|
|
||||||
|
This identifier is always a positive number.
|
||||||
|
|
||||||
|
This property is always present.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abc.abstractmethod
|
||||||
|
def name(self) -> str:
|
||||||
|
"""
|
||||||
|
The full name of the user, group or channel.
|
||||||
|
|
||||||
|
For users, this will be the :attr:`User.first_name` concatenated with the :attr:`User.last_name`.
|
||||||
|
|
||||||
|
For groups and channels, this will be their title.
|
||||||
|
|
||||||
|
If there is no name (such as for deleted accounts), an empty string ``''`` will be returned.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abc.abstractmethod
|
||||||
|
def username(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
The primary *@username* of the chat.
|
||||||
|
|
||||||
|
The returned string will *not* contain the at-sign ``@``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def pack(self) -> Optional[PackedChat]:
|
||||||
|
"""
|
||||||
|
Pack the chat into a compact and reusable object.
|
||||||
|
|
||||||
|
This object can be easily serialized and saved to persistent storage.
|
||||||
|
Unlike resolving usernames, packed chats can be reused without costly calls.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
:doc:`/concepts/chats`
|
||||||
|
"""
|
@ -3,9 +3,10 @@ from typing import Optional, Self, Union
|
|||||||
from ....session import PackedChat, PackedType
|
from ....session import PackedChat, PackedType
|
||||||
from ....tl import abcs, types
|
from ....tl import abcs, types
|
||||||
from ..meta import NoPublicConstructor
|
from ..meta import NoPublicConstructor
|
||||||
|
from .chat import Chat
|
||||||
|
|
||||||
|
|
||||||
class Group(metaclass=NoPublicConstructor):
|
class Group(Chat, metaclass=NoPublicConstructor):
|
||||||
"""
|
"""
|
||||||
A small group or supergroup.
|
A small group or supergroup.
|
||||||
|
|
||||||
@ -38,10 +39,25 @@ class Group(metaclass=NoPublicConstructor):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("unexpected case")
|
raise RuntimeError("unexpected case")
|
||||||
|
|
||||||
|
# region Overrides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> int:
|
def id(self) -> int:
|
||||||
return self._raw.id
|
return self._raw.id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
"""
|
||||||
|
The group's title.
|
||||||
|
|
||||||
|
This property is always present, but may be the empty string.
|
||||||
|
"""
|
||||||
|
return self._raw.title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def username(self) -> Optional[str]:
|
||||||
|
return getattr(self._raw, "username", None)
|
||||||
|
|
||||||
def pack(self) -> Optional[PackedChat]:
|
def pack(self) -> Optional[PackedChat]:
|
||||||
if isinstance(self._raw, (types.ChatEmpty, types.Chat, types.ChatForbidden)):
|
if isinstance(self._raw, (types.ChatEmpty, types.Chat, types.ChatForbidden)):
|
||||||
return PackedChat(ty=PackedType.CHAT, id=self._raw.id, access_hash=None)
|
return PackedChat(ty=PackedType.CHAT, id=self._raw.id, access_hash=None)
|
||||||
@ -52,18 +68,13 @@ class Group(metaclass=NoPublicConstructor):
|
|||||||
ty=PackedType.MEGAGROUP, id=self._raw.id, access_hash=None
|
ty=PackedType.MEGAGROUP, id=self._raw.id, access_hash=None
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
# endregion Overrides
|
||||||
def title(self) -> str:
|
|
||||||
return getattr(self._raw, "title", None) or ""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def full_name(self) -> str:
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
@property
|
|
||||||
def username(self) -> Optional[str]:
|
|
||||||
return getattr(self._raw, "username", None)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_megagroup(self) -> bool:
|
def is_megagroup(self) -> bool:
|
||||||
|
"""
|
||||||
|
Whether the group is a supergroup.
|
||||||
|
|
||||||
|
These are known as "megagroups" in Telegram's API, and are different from "gigagroups".
|
||||||
|
"""
|
||||||
return isinstance(self._raw, (types.Channel, types.ChannelForbidden))
|
return isinstance(self._raw, (types.Channel, types.ChannelForbidden))
|
||||||
|
@ -1,39 +1,12 @@
|
|||||||
from typing import List, Optional, Self
|
from typing import Optional, Self
|
||||||
|
|
||||||
from ....session import PackedChat, PackedType
|
from ....session import PackedChat, PackedType
|
||||||
from ....tl import abcs, types
|
from ....tl import abcs, types
|
||||||
from ..meta import NoPublicConstructor
|
from ..meta import NoPublicConstructor
|
||||||
|
from .chat import Chat
|
||||||
|
|
||||||
|
|
||||||
class RestrictionReason(metaclass=NoPublicConstructor):
|
class User(Chat, metaclass=NoPublicConstructor):
|
||||||
"""
|
|
||||||
A restriction reason for :class:`telethon.types.User`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ("_raw",)
|
|
||||||
|
|
||||||
def __init__(self, raw: types.RestrictionReason) -> None:
|
|
||||||
self._raw = raw
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _from_raw(cls, reason: abcs.RestrictionReason) -> Self:
|
|
||||||
assert isinstance(reason, types.RestrictionReason)
|
|
||||||
return cls._create(reason)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def platforms(self) -> List[str]:
|
|
||||||
return self._raw.platform.split("-")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reason(self) -> str:
|
|
||||||
return self._raw.reason
|
|
||||||
|
|
||||||
@property
|
|
||||||
def text(self) -> str:
|
|
||||||
return self._raw.text
|
|
||||||
|
|
||||||
|
|
||||||
class User(metaclass=NoPublicConstructor):
|
|
||||||
"""
|
"""
|
||||||
A user, representing either a bot account or an account created with a phone number.
|
A user, representing either a bot account or an account created with a phone number.
|
||||||
|
|
||||||
@ -95,10 +68,27 @@ class User(metaclass=NoPublicConstructor):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("unexpected case")
|
raise RuntimeError("unexpected case")
|
||||||
|
|
||||||
|
# region Overrides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> int:
|
def id(self) -> int:
|
||||||
return self._raw.id
|
return self._raw.id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
"""
|
||||||
|
The user's full name.
|
||||||
|
|
||||||
|
This property joins both the :attr:`first_name` and :attr:`last_name` into a single string.
|
||||||
|
|
||||||
|
This property is always present, but may be the empty string.
|
||||||
|
"""
|
||||||
|
return f"{self.first_name} {self.last_name}".strip()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def username(self) -> Optional[str]:
|
||||||
|
return self._raw.username
|
||||||
|
|
||||||
def pack(self) -> Optional[PackedChat]:
|
def pack(self) -> Optional[PackedChat]:
|
||||||
if self._raw.access_hash is not None:
|
if self._raw.access_hash is not None:
|
||||||
return PackedChat(
|
return PackedChat(
|
||||||
@ -109,6 +99,8 @@ class User(metaclass=NoPublicConstructor):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# endregion Overrides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def first_name(self) -> str:
|
def first_name(self) -> str:
|
||||||
return self._raw.first_name or ""
|
return self._raw.first_name or ""
|
||||||
@ -117,14 +109,6 @@ class User(metaclass=NoPublicConstructor):
|
|||||||
def last_name(self) -> str:
|
def last_name(self) -> str:
|
||||||
return self._raw.last_name or ""
|
return self._raw.last_name or ""
|
||||||
|
|
||||||
@property
|
|
||||||
def full_name(self) -> str:
|
|
||||||
return f"{self.first_name} {self.last_name}".strip()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def username(self) -> Optional[str]:
|
|
||||||
return self._raw.username
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def phone(self) -> Optional[str]:
|
def phone(self) -> Optional[str]:
|
||||||
return self._raw.phone
|
return self._raw.phone
|
||||||
@ -132,9 +116,3 @@ class User(metaclass=NoPublicConstructor):
|
|||||||
@property
|
@property
|
||||||
def bot(self) -> bool:
|
def bot(self) -> bool:
|
||||||
return self._raw.bot
|
return self._raw.bot
|
||||||
|
|
||||||
@property
|
|
||||||
def restriction_reasons(self) -> List[RestrictionReason]:
|
|
||||||
return [
|
|
||||||
RestrictionReason._from_raw(r) for r in (self._raw.restriction_reason or [])
|
|
||||||
]
|
|
||||||
|
@ -27,10 +27,7 @@ def build_chat_map(users: List[abcs.User], chats: List[abcs.Chat]) -> Dict[int,
|
|||||||
for c in chats
|
for c in chats
|
||||||
)
|
)
|
||||||
|
|
||||||
# https://github.com/python/mypy/issues/2115
|
result: Dict[int, Chat] = {c.id: c for c in itertools.chain(users_iter, chats_iter)}
|
||||||
result: Dict[int, Chat] = {
|
|
||||||
c.id: c for c in itertools.chain(users_iter, chats_iter) # type: ignore [attr-defined, misc]
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(result) != len(users) + len(chats):
|
if len(result) != len(users) + len(chats):
|
||||||
# The fabled ID collision between different chat types.
|
# The fabled ID collision between different chat types.
|
||||||
|
@ -5,20 +5,16 @@ from ._impl.client.types import (
|
|||||||
AsyncList,
|
AsyncList,
|
||||||
Channel,
|
Channel,
|
||||||
Chat,
|
Chat,
|
||||||
ChatLike,
|
|
||||||
Dialog,
|
Dialog,
|
||||||
Draft,
|
Draft,
|
||||||
File,
|
File,
|
||||||
Group,
|
Group,
|
||||||
InFileLike,
|
|
||||||
InlineResult,
|
InlineResult,
|
||||||
LoginToken,
|
LoginToken,
|
||||||
Message,
|
Message,
|
||||||
OutFileLike,
|
|
||||||
Participant,
|
Participant,
|
||||||
PasswordToken,
|
PasswordToken,
|
||||||
RecentAction,
|
RecentAction,
|
||||||
RestrictionReason,
|
|
||||||
User,
|
User,
|
||||||
)
|
)
|
||||||
from ._impl.session import PackedChat, PackedType
|
from ._impl.session import PackedChat, PackedType
|
||||||
@ -28,19 +24,15 @@ __all__ = [
|
|||||||
"AsyncList",
|
"AsyncList",
|
||||||
"Channel",
|
"Channel",
|
||||||
"Chat",
|
"Chat",
|
||||||
"ChatLike",
|
|
||||||
"Dialog",
|
"Dialog",
|
||||||
"Draft",
|
"Draft",
|
||||||
"File",
|
"File",
|
||||||
"Group",
|
"Group",
|
||||||
"InFileLike",
|
|
||||||
"LoginToken",
|
"LoginToken",
|
||||||
"Message",
|
"Message",
|
||||||
"OutFileLike",
|
|
||||||
"Participant",
|
"Participant",
|
||||||
"PasswordToken",
|
"PasswordToken",
|
||||||
"RecentAction",
|
"RecentAction",
|
||||||
"RestrictionReason",
|
|
||||||
"User",
|
"User",
|
||||||
"PackedChat",
|
"PackedChat",
|
||||||
"PackedType",
|
"PackedType",
|
||||||
|
Loading…
Reference in New Issue
Block a user