mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-02-13 18:11:06 +03:00
Remove utils file
This gets rid of awkward lazy imports as well.
This commit is contained in:
parent
8fe89496d6
commit
d80c6b3bb4
|
@ -3,8 +3,7 @@ from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from ..types import AsyncList, ChatLike, File, Participant, RecentAction
|
from ..types import AsyncList, ChatLike, File, Participant, RecentAction, build_chat_map
|
||||||
from ..utils import build_chat_map
|
|
||||||
from .messages import SearchList
|
from .messages import SearchList
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
|
@ -4,8 +4,7 @@ import time
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from ...tl import functions, types
|
from ...tl import functions, types
|
||||||
from ..types import AsyncList, ChatLike, Dialog, Draft
|
from ..types import AsyncList, ChatLike, Dialog, Draft, build_chat_map, build_msg_map
|
||||||
from ..utils import build_chat_map, build_msg_map
|
|
||||||
from .messages import parse_message
|
from .messages import parse_message
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
|
@ -16,9 +16,9 @@ from ..types import (
|
||||||
Message,
|
Message,
|
||||||
OutFileLike,
|
OutFileLike,
|
||||||
OutWrapper,
|
OutWrapper,
|
||||||
|
expand_stripped_size,
|
||||||
|
generate_random_id,
|
||||||
)
|
)
|
||||||
from ..types.file import expand_stripped_size
|
|
||||||
from ..utils import generate_random_id
|
|
||||||
from .messages import parse_message
|
from .messages import parse_message
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
|
@ -7,8 +7,16 @@ from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Tuple, Union
|
||||||
from ...session import PackedChat
|
from ...session import PackedChat
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from ..parsers import parse_html_message, parse_markdown_message
|
from ..parsers import parse_html_message, parse_markdown_message
|
||||||
from ..types import AsyncList, Chat, ChatLike, Message, buttons
|
from ..types import (
|
||||||
from ..utils import build_chat_map, generate_random_id, peer_id
|
AsyncList,
|
||||||
|
Chat,
|
||||||
|
ChatLike,
|
||||||
|
Message,
|
||||||
|
build_chat_map,
|
||||||
|
buttons,
|
||||||
|
generate_random_id,
|
||||||
|
peer_id,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import Client
|
from .client import Client
|
||||||
|
|
|
@ -16,7 +16,7 @@ from ...session import Gap
|
||||||
from ...tl import abcs
|
from ...tl import abcs
|
||||||
from ..events import Event as EventBase
|
from ..events import Event as EventBase
|
||||||
from ..events.filters import Filter
|
from ..events.filters import Filter
|
||||||
from ..utils import build_chat_map
|
from ..types import build_chat_map
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import Client
|
from .client import Client
|
||||||
|
|
|
@ -5,8 +5,16 @@ from typing import TYPE_CHECKING, Optional
|
||||||
from ...mtproto import RpcError
|
from ...mtproto import RpcError
|
||||||
from ...session import PackedChat, PackedType
|
from ...session import PackedChat, PackedType
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from ..types import AsyncList, Channel, Chat, ChatLike, Group, User
|
from ..types import (
|
||||||
from ..utils import build_chat_map, peer_id
|
AsyncList,
|
||||||
|
Channel,
|
||||||
|
Chat,
|
||||||
|
ChatLike,
|
||||||
|
Group,
|
||||||
|
User,
|
||||||
|
build_chat_map,
|
||||||
|
peer_id,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import Client
|
from .client import Client
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Literal, Optional, Tuple, Union
|
||||||
from ..event import Event
|
from ..event import Event
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ...client import Client
|
from ...client.client import Client
|
||||||
|
|
||||||
|
|
||||||
class Text:
|
class Text:
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
from .async_list import AsyncList
|
from .async_list import AsyncList
|
||||||
from .callback_answer import CallbackAnswer
|
from .callback_answer import CallbackAnswer
|
||||||
from .chat import Channel, Chat, ChatLike, Group, User
|
from .chat import (
|
||||||
|
Channel,
|
||||||
|
Chat,
|
||||||
|
ChatLike,
|
||||||
|
Group,
|
||||||
|
User,
|
||||||
|
build_chat_map,
|
||||||
|
expand_peer,
|
||||||
|
peer_id,
|
||||||
|
)
|
||||||
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, expand_stripped_size
|
||||||
from .inline_result import InlineResult
|
from .inline_result import InlineResult
|
||||||
from .login_token import LoginToken
|
from .login_token import LoginToken
|
||||||
from .message import Message
|
from .message import Message, adapt_date, build_msg_map, generate_random_id
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
from .participant import Participant
|
from .participant import Participant
|
||||||
from .password_token import PasswordToken
|
from .password_token import PasswordToken
|
||||||
|
@ -20,15 +29,22 @@ __all__ = [
|
||||||
"ChatLike",
|
"ChatLike",
|
||||||
"Group",
|
"Group",
|
||||||
"User",
|
"User",
|
||||||
|
"build_chat_map",
|
||||||
|
"expand_peer",
|
||||||
|
"peer_id",
|
||||||
"Dialog",
|
"Dialog",
|
||||||
"Draft",
|
"Draft",
|
||||||
"File",
|
"File",
|
||||||
"InFileLike",
|
"InFileLike",
|
||||||
"OutFileLike",
|
"OutFileLike",
|
||||||
"OutWrapper",
|
"OutWrapper",
|
||||||
|
"expand_stripped_size",
|
||||||
"InlineResult",
|
"InlineResult",
|
||||||
"LoginToken",
|
"LoginToken",
|
||||||
"Message",
|
"Message",
|
||||||
|
"adapt_date",
|
||||||
|
"build_msg_map",
|
||||||
|
"generate_random_id",
|
||||||
"NoPublicConstructor",
|
"NoPublicConstructor",
|
||||||
"Participant",
|
"Participant",
|
||||||
"PasswordToken",
|
"PasswordToken",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
from typing import Union
|
import itertools
|
||||||
|
import sys
|
||||||
|
from collections import defaultdict
|
||||||
|
from typing import DefaultDict, Dict, List, Optional, Union
|
||||||
|
|
||||||
from ....session import PackedChat
|
from ....session import PackedChat
|
||||||
|
from ....tl import abcs, types
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
from .chat import Chat
|
from .chat import Chat
|
||||||
from .group import Group
|
from .group import Group
|
||||||
|
@ -8,4 +12,81 @@ from .user import User
|
||||||
|
|
||||||
ChatLike = Union[Chat, PackedChat, int, str]
|
ChatLike = Union[Chat, PackedChat, int, str]
|
||||||
|
|
||||||
__all__ = ["Chat", "ChatLike", "Channel", "Group", "User"]
|
|
||||||
|
def build_chat_map(users: List[abcs.User], chats: List[abcs.Chat]) -> Dict[int, Chat]:
|
||||||
|
users_iter = (User._from_raw(u) for u in users)
|
||||||
|
chats_iter = (
|
||||||
|
Channel._from_raw(c)
|
||||||
|
if isinstance(c, (types.Channel, types.ChannelForbidden)) and c.broadcast
|
||||||
|
else Group._from_raw(c)
|
||||||
|
for c in chats
|
||||||
|
)
|
||||||
|
|
||||||
|
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.
|
||||||
|
counter: DefaultDict[int, List[Union[abcs.User, abcs.Chat]]] = defaultdict(list)
|
||||||
|
for user in users:
|
||||||
|
if (id := getattr(user, "id", None)) is not None:
|
||||||
|
counter[id].append(user)
|
||||||
|
for chat in chats:
|
||||||
|
if (id := getattr(chat, "id", None)) is not None:
|
||||||
|
counter[id].append(chat)
|
||||||
|
|
||||||
|
for k, v in counter.items():
|
||||||
|
if len(v) > 1:
|
||||||
|
for x in v:
|
||||||
|
print(x, file=sys.stderr)
|
||||||
|
|
||||||
|
raise RuntimeError(
|
||||||
|
f"chat identifier collision: {k}; please report this"
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def peer_id(peer: abcs.Peer) -> int:
|
||||||
|
if isinstance(peer, types.PeerUser):
|
||||||
|
return peer.user_id
|
||||||
|
elif isinstance(peer, types.PeerChat):
|
||||||
|
return peer.chat_id
|
||||||
|
elif isinstance(peer, types.PeerChannel):
|
||||||
|
return peer.channel_id
|
||||||
|
else:
|
||||||
|
raise RuntimeError("unexpected case")
|
||||||
|
|
||||||
|
|
||||||
|
def expand_peer(peer: abcs.Peer, *, broadcast: Optional[bool]) -> Chat:
|
||||||
|
if isinstance(peer, types.PeerUser):
|
||||||
|
return User._from_raw(types.UserEmpty(id=peer.user_id))
|
||||||
|
elif isinstance(peer, types.PeerChat):
|
||||||
|
return Group._from_raw(types.ChatEmpty(id=peer.chat_id))
|
||||||
|
elif isinstance(peer, types.PeerChannel):
|
||||||
|
if broadcast is None:
|
||||||
|
broadcast = True # assume broadcast by default (Channel type is more accurate than Group)
|
||||||
|
|
||||||
|
channel = types.ChannelForbidden(
|
||||||
|
broadcast=broadcast,
|
||||||
|
megagroup=not broadcast,
|
||||||
|
id=peer.channel_id,
|
||||||
|
access_hash=0,
|
||||||
|
title="",
|
||||||
|
until_date=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return Channel._from_raw(channel) if broadcast else Group._from_raw(channel)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("unexpected case")
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Chat",
|
||||||
|
"ChatLike",
|
||||||
|
"Channel",
|
||||||
|
"Group",
|
||||||
|
"User",
|
||||||
|
"build_chat_map",
|
||||||
|
"peer_id",
|
||||||
|
"expand_peer",
|
||||||
|
]
|
||||||
|
|
|
@ -3,13 +3,13 @@ from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING, Dict, Optional, Self, Union
|
from typing import TYPE_CHECKING, Dict, Optional, Self, Union
|
||||||
|
|
||||||
from ...tl import abcs, types
|
from ...tl import abcs, types
|
||||||
from .chat import Chat
|
from .chat import Chat, peer_id
|
||||||
from .draft import Draft
|
from .draft import Draft
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..client import Client
|
from ..client.client import Client
|
||||||
|
|
||||||
|
|
||||||
class Dialog(metaclass=NoPublicConstructor):
|
class Dialog(metaclass=NoPublicConstructor):
|
||||||
|
@ -51,8 +51,6 @@ class Dialog(metaclass=NoPublicConstructor):
|
||||||
"""
|
"""
|
||||||
The chat where messages are sent in this dialog.
|
The chat where messages are sent in this dialog.
|
||||||
"""
|
"""
|
||||||
from ..utils import peer_id
|
|
||||||
|
|
||||||
return self._chat_map[peer_id(self._raw.peer)]
|
return self._chat_map[peer_id(self._raw.peer)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -6,12 +6,12 @@ from typing import TYPE_CHECKING, Dict, Optional, Self
|
||||||
from ...session import PackedChat
|
from ...session import PackedChat
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from ..parsers import generate_html_message, generate_markdown_message
|
from ..parsers import generate_html_message, generate_markdown_message
|
||||||
from .chat import Chat
|
from .chat import Chat, expand_peer, peer_id
|
||||||
from .message import Message
|
from .message import Message, generate_random_id
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..client import Client
|
from ..client.client import Client
|
||||||
|
|
||||||
|
|
||||||
class Draft(metaclass=NoPublicConstructor):
|
class Draft(metaclass=NoPublicConstructor):
|
||||||
|
@ -60,8 +60,6 @@ class Draft(metaclass=NoPublicConstructor):
|
||||||
|
|
||||||
This is also the chat where the message will be sent to by :meth:`send`.
|
This is also the chat where the message will be sent to by :meth:`send`.
|
||||||
"""
|
"""
|
||||||
from ..utils import expand_peer, peer_id
|
|
||||||
|
|
||||||
return self._chat_map.get(peer_id(self._peer)) or expand_peer(
|
return self._chat_map.get(peer_id(self._peer)) or expand_peer(
|
||||||
self._peer, broadcast=None
|
self._peer, broadcast=None
|
||||||
)
|
)
|
||||||
|
@ -161,8 +159,6 @@ class Draft(metaclass=NoPublicConstructor):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _packed_chat(self) -> PackedChat:
|
async def _packed_chat(self) -> PackedChat:
|
||||||
from ..utils import peer_id
|
|
||||||
|
|
||||||
packed = None
|
packed = None
|
||||||
if chat := self._chat_map.get(peer_id(self._peer)):
|
if chat := self._chat_map.get(peer_id(self._peer)):
|
||||||
packed = chat.pack()
|
packed = chat.pack()
|
||||||
|
@ -184,8 +180,6 @@ class Draft(metaclass=NoPublicConstructor):
|
||||||
|
|
||||||
await draft.send(clear=False)
|
await draft.send(clear=False)
|
||||||
"""
|
"""
|
||||||
from ..utils import generate_random_id
|
|
||||||
|
|
||||||
packed = await self._packed_chat()
|
packed = await self._packed_chat()
|
||||||
peer = packed._to_input_peer()
|
peer = packed._to_input_peer()
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from ...tl import abcs, types
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..client import Client
|
from ..client.client import Client
|
||||||
|
|
||||||
math_round = round
|
math_round = round
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ from typing import TYPE_CHECKING, Optional, Union
|
||||||
|
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from .chat import ChatLike
|
from .chat import ChatLike
|
||||||
from .message import Message
|
from .message import Message, generate_random_id
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..client import Client
|
from ..client.client import Client
|
||||||
|
|
||||||
|
|
||||||
class InlineResult(metaclass=NoPublicConstructor):
|
class InlineResult(metaclass=NoPublicConstructor):
|
||||||
|
@ -62,8 +62,6 @@ class InlineResult(metaclass=NoPublicConstructor):
|
||||||
|
|
||||||
:return: The sent message.
|
:return: The sent message.
|
||||||
"""
|
"""
|
||||||
from ..utils import generate_random_id
|
|
||||||
|
|
||||||
if chat is None and isinstance(self._default_peer, types.InputPeerEmpty):
|
if chat is None and isinstance(self._default_peer, types.InputPeerEmpty):
|
||||||
raise ValueError("no target chat was specified")
|
raise ValueError("no target chat was specified")
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,37 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import time
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Self, Union
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Self, Union
|
||||||
|
|
||||||
from ...tl import abcs, types
|
from ...tl import abcs, types
|
||||||
from ..parsers import generate_html_message, generate_markdown_message
|
from ..parsers import generate_html_message, generate_markdown_message
|
||||||
from .buttons import Button, as_concrete_row, create_button
|
from .buttons import Button, as_concrete_row, create_button
|
||||||
from .chat import Chat, ChatLike
|
from .chat import Chat, ChatLike, expand_peer, peer_id
|
||||||
from .file import File
|
from .file import File
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..client import Client
|
from ..client.client import Client
|
||||||
|
|
||||||
|
|
||||||
|
_last_id = 0
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_id() -> int:
|
||||||
|
global _last_id
|
||||||
|
if _last_id == 0:
|
||||||
|
_last_id = int(time.time() * 1e9)
|
||||||
|
_last_id += 1
|
||||||
|
return _last_id
|
||||||
|
|
||||||
|
|
||||||
|
def adapt_date(date: Optional[int]) -> Optional[datetime.datetime]:
|
||||||
|
return (
|
||||||
|
datetime.datetime.fromtimestamp(date, tz=datetime.timezone.utc)
|
||||||
|
if date is not None
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Message(metaclass=NoPublicConstructor):
|
class Message(metaclass=NoPublicConstructor):
|
||||||
|
@ -148,8 +168,6 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
"""
|
"""
|
||||||
The date when the message was sent.
|
The date when the message was sent.
|
||||||
"""
|
"""
|
||||||
from ..utils import adapt_date
|
|
||||||
|
|
||||||
return adapt_date(getattr(self._raw, "date", None))
|
return adapt_date(getattr(self._raw, "date", None))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -157,8 +175,6 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
"""
|
"""
|
||||||
The :term:`chat` when the message was sent.
|
The :term:`chat` when the message was sent.
|
||||||
"""
|
"""
|
||||||
from ..utils import expand_peer, peer_id
|
|
||||||
|
|
||||||
peer = self._raw.peer_id or types.PeerUser(user_id=0)
|
peer = self._raw.peer_id or types.PeerUser(user_id=0)
|
||||||
pid = peer_id(peer)
|
pid = peer_id(peer)
|
||||||
if pid not in self._chat_map:
|
if pid not in self._chat_map:
|
||||||
|
@ -176,8 +192,6 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
|
|
||||||
If there is no sender, it means the message was sent by an anonymous user.
|
If there is no sender, it means the message was sent by an anonymous user.
|
||||||
"""
|
"""
|
||||||
from ..utils import expand_peer, peer_id
|
|
||||||
|
|
||||||
if (from_ := getattr(self._raw, "from_id", None)) is not None:
|
if (from_ := getattr(self._raw, "from_id", None)) is not None:
|
||||||
return self._chat_map.get(peer_id(from_)) or expand_peer(
|
return self._chat_map.get(peer_id(from_)) or expand_peer(
|
||||||
from_, broadcast=getattr(self._raw, "post", None)
|
from_, broadcast=getattr(self._raw, "post", None)
|
||||||
|
@ -444,3 +458,12 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
return not self._raw.noforwards
|
return not self._raw.noforwards
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def build_msg_map(
|
||||||
|
client: Client, messages: List[abcs.Message], chat_map: Dict[int, Chat]
|
||||||
|
) -> Dict[int, Message]:
|
||||||
|
return {
|
||||||
|
msg.id: msg
|
||||||
|
for msg in (Message._from_raw(client, m, chat_map) for m in messages)
|
||||||
|
}
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import itertools
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from collections import defaultdict
|
|
||||||
from typing import TYPE_CHECKING, DefaultDict, Dict, List, Optional, Union
|
|
||||||
|
|
||||||
from ..tl import abcs, types
|
|
||||||
from .types import Channel, Chat, Group, Message, User
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from .client import Client
|
|
||||||
|
|
||||||
_last_id = 0
|
|
||||||
|
|
||||||
|
|
||||||
def generate_random_id() -> int:
|
|
||||||
global _last_id
|
|
||||||
if _last_id == 0:
|
|
||||||
_last_id = int(time.time() * 1e9)
|
|
||||||
_last_id += 1
|
|
||||||
return _last_id
|
|
||||||
|
|
||||||
|
|
||||||
def build_chat_map(users: List[abcs.User], chats: List[abcs.Chat]) -> Dict[int, Chat]:
|
|
||||||
users_iter = (User._from_raw(u) for u in users)
|
|
||||||
chats_iter = (
|
|
||||||
Channel._from_raw(c)
|
|
||||||
if isinstance(c, (types.Channel, types.ChannelForbidden)) and c.broadcast
|
|
||||||
else Group._from_raw(c)
|
|
||||||
for c in chats
|
|
||||||
)
|
|
||||||
|
|
||||||
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.
|
|
||||||
counter: DefaultDict[int, List[Union[abcs.User, abcs.Chat]]] = defaultdict(list)
|
|
||||||
for user in users:
|
|
||||||
if (id := getattr(user, "id", None)) is not None:
|
|
||||||
counter[id].append(user)
|
|
||||||
for chat in chats:
|
|
||||||
if (id := getattr(chat, "id", None)) is not None:
|
|
||||||
counter[id].append(chat)
|
|
||||||
|
|
||||||
for k, v in counter.items():
|
|
||||||
if len(v) > 1:
|
|
||||||
for x in v:
|
|
||||||
print(x, file=sys.stderr)
|
|
||||||
|
|
||||||
raise RuntimeError(
|
|
||||||
f"chat identifier collision: {k}; please report this"
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def build_msg_map(
|
|
||||||
client: Client, messages: List[abcs.Message], chat_map: Dict[int, Chat]
|
|
||||||
) -> Dict[int, Message]:
|
|
||||||
return {
|
|
||||||
msg.id: msg
|
|
||||||
for msg in (Message._from_raw(client, m, chat_map) for m in messages)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def peer_id(peer: abcs.Peer) -> int:
|
|
||||||
if isinstance(peer, types.PeerUser):
|
|
||||||
return peer.user_id
|
|
||||||
elif isinstance(peer, types.PeerChat):
|
|
||||||
return peer.chat_id
|
|
||||||
elif isinstance(peer, types.PeerChannel):
|
|
||||||
return peer.channel_id
|
|
||||||
else:
|
|
||||||
raise RuntimeError("unexpected case")
|
|
||||||
|
|
||||||
|
|
||||||
def expand_peer(peer: abcs.Peer, *, broadcast: Optional[bool]) -> Chat:
|
|
||||||
if isinstance(peer, types.PeerUser):
|
|
||||||
return User._from_raw(types.UserEmpty(id=peer.user_id))
|
|
||||||
elif isinstance(peer, types.PeerChat):
|
|
||||||
return Group._from_raw(types.ChatEmpty(id=peer.chat_id))
|
|
||||||
elif isinstance(peer, types.PeerChannel):
|
|
||||||
if broadcast is None:
|
|
||||||
broadcast = True # assume broadcast by default (Channel type is more accurate than Group)
|
|
||||||
|
|
||||||
channel = types.ChannelForbidden(
|
|
||||||
broadcast=broadcast,
|
|
||||||
megagroup=not broadcast,
|
|
||||||
id=peer.channel_id,
|
|
||||||
access_hash=0,
|
|
||||||
title="",
|
|
||||||
until_date=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
return Channel._from_raw(channel) if broadcast else Group._from_raw(channel)
|
|
||||||
else:
|
|
||||||
raise RuntimeError("unexpected case")
|
|
||||||
|
|
||||||
|
|
||||||
def adapt_date(date: Optional[int]) -> Optional[datetime.datetime]:
|
|
||||||
return (
|
|
||||||
datetime.datetime.fromtimestamp(date, tz=datetime.timezone.utc)
|
|
||||||
if date is not None
|
|
||||||
else None
|
|
||||||
)
|
|
Loading…
Reference in New Issue
Block a user