mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-02-03 13:14:31 +03: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 .chat import Channel, Chat, ChatLike, Group, RestrictionReason, User
|
||||
from .chat import Channel, Chat, ChatLike, Group, User
|
||||
from .dialog import Dialog
|
||||
from .draft import Draft
|
||||
from .file import File, InFileLike, OutFileLike, OutWrapper
|
||||
|
@ -17,7 +17,6 @@ __all__ = [
|
|||
"Chat",
|
||||
"ChatLike",
|
||||
"Group",
|
||||
"RestrictionReason",
|
||||
"User",
|
||||
"Dialog",
|
||||
"Draft",
|
||||
|
|
|
@ -2,10 +2,10 @@ from typing import Union
|
|||
|
||||
from ....session import PackedChat
|
||||
from .channel import Channel
|
||||
from .chat import Chat
|
||||
from .group import Group
|
||||
from .user import RestrictionReason, User
|
||||
from .user import User
|
||||
|
||||
Chat = Union[Channel, Group, User]
|
||||
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 ....tl import abcs, types
|
||||
from ..meta import NoPublicConstructor
|
||||
from .chat import Chat
|
||||
|
||||
|
||||
class Channel(metaclass=NoPublicConstructor):
|
||||
class Channel(Chat, metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A broadcast channel.
|
||||
|
||||
|
@ -32,10 +33,25 @@ class Channel(metaclass=NoPublicConstructor):
|
|||
else:
|
||||
raise RuntimeError("unexpected case")
|
||||
|
||||
# region Overrides
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
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]:
|
||||
if self._raw.access_hash is None:
|
||||
return None
|
||||
|
@ -48,14 +64,4 @@ class Channel(metaclass=NoPublicConstructor):
|
|||
access_hash=None,
|
||||
)
|
||||
|
||||
@property
|
||||
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)
|
||||
# endregion Overrides
|
||||
|
|
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 ....tl import abcs, types
|
||||
from ..meta import NoPublicConstructor
|
||||
from .chat import Chat
|
||||
|
||||
|
||||
class Group(metaclass=NoPublicConstructor):
|
||||
class Group(Chat, metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A small group or supergroup.
|
||||
|
||||
|
@ -38,10 +39,25 @@ class Group(metaclass=NoPublicConstructor):
|
|||
else:
|
||||
raise RuntimeError("unexpected case")
|
||||
|
||||
# region Overrides
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
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]:
|
||||
if isinstance(self._raw, (types.ChatEmpty, types.Chat, types.ChatForbidden)):
|
||||
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
|
||||
)
|
||||
|
||||
@property
|
||||
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)
|
||||
# endregion Overrides
|
||||
|
||||
@property
|
||||
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))
|
||||
|
|
|
@ -1,39 +1,12 @@
|
|||
from typing import List, Optional, Self
|
||||
from typing import Optional, Self
|
||||
|
||||
from ....session import PackedChat, PackedType
|
||||
from ....tl import abcs, types
|
||||
from ..meta import NoPublicConstructor
|
||||
from .chat import Chat
|
||||
|
||||
|
||||
class RestrictionReason(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):
|
||||
class User(Chat, metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A user, representing either a bot account or an account created with a phone number.
|
||||
|
||||
|
@ -95,10 +68,27 @@ class User(metaclass=NoPublicConstructor):
|
|||
else:
|
||||
raise RuntimeError("unexpected case")
|
||||
|
||||
# region Overrides
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
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]:
|
||||
if self._raw.access_hash is not None:
|
||||
return PackedChat(
|
||||
|
@ -109,6 +99,8 @@ class User(metaclass=NoPublicConstructor):
|
|||
else:
|
||||
return None
|
||||
|
||||
# endregion Overrides
|
||||
|
||||
@property
|
||||
def first_name(self) -> str:
|
||||
return self._raw.first_name or ""
|
||||
|
@ -117,14 +109,6 @@ class User(metaclass=NoPublicConstructor):
|
|||
def last_name(self) -> str:
|
||||
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
|
||||
def phone(self) -> Optional[str]:
|
||||
return self._raw.phone
|
||||
|
@ -132,9 +116,3 @@ class User(metaclass=NoPublicConstructor):
|
|||
@property
|
||||
def bot(self) -> bool:
|
||||
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
|
||||
)
|
||||
|
||||
# https://github.com/python/mypy/issues/2115
|
||||
result: Dict[int, Chat] = {
|
||||
c.id: c for c in itertools.chain(users_iter, chats_iter) # type: ignore [attr-defined, misc]
|
||||
}
|
||||
result: Dict[int, Chat] = {c.id: c for c in itertools.chain(users_iter, chats_iter)}
|
||||
|
||||
if len(result) != len(users) + len(chats):
|
||||
# The fabled ID collision between different chat types.
|
||||
|
|
|
@ -5,20 +5,16 @@ from ._impl.client.types import (
|
|||
AsyncList,
|
||||
Channel,
|
||||
Chat,
|
||||
ChatLike,
|
||||
Dialog,
|
||||
Draft,
|
||||
File,
|
||||
Group,
|
||||
InFileLike,
|
||||
InlineResult,
|
||||
LoginToken,
|
||||
Message,
|
||||
OutFileLike,
|
||||
Participant,
|
||||
PasswordToken,
|
||||
RecentAction,
|
||||
RestrictionReason,
|
||||
User,
|
||||
)
|
||||
from ._impl.session import PackedChat, PackedType
|
||||
|
@ -28,19 +24,15 @@ __all__ = [
|
|||
"AsyncList",
|
||||
"Channel",
|
||||
"Chat",
|
||||
"ChatLike",
|
||||
"Dialog",
|
||||
"Draft",
|
||||
"File",
|
||||
"Group",
|
||||
"InFileLike",
|
||||
"LoginToken",
|
||||
"Message",
|
||||
"OutFileLike",
|
||||
"Participant",
|
||||
"PasswordToken",
|
||||
"RecentAction",
|
||||
"RestrictionReason",
|
||||
"User",
|
||||
"PackedChat",
|
||||
"PackedType",
|
||||
|
|
Loading…
Reference in New Issue
Block a user