mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-05 04:30:22 +03:00
Fixes
This commit is contained in:
parent
8de375323e
commit
1d4bd39307
|
@ -8,6 +8,7 @@ import asyncio
|
||||||
|
|
||||||
from .._crypto import AES
|
from .._crypto import AES
|
||||||
from .._misc import utils, helpers, requestiter, tlobject, hints
|
from .._misc import utils, helpers, requestiter, tlobject, hints
|
||||||
|
from ..types._custom import Message
|
||||||
from .. import errors, _tl
|
from .. import errors, _tl
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -267,7 +268,8 @@ async def download_media(
|
||||||
msg_data = None
|
msg_data = None
|
||||||
|
|
||||||
# TODO This won't work for messageService
|
# TODO This won't work for messageService
|
||||||
if isinstance(message, _tl.Message):
|
# TODO Handle _tl.Message
|
||||||
|
if isinstance(message, Message):
|
||||||
date = message.date
|
date = message.date
|
||||||
media = message.media
|
media = message.media
|
||||||
msg_data = (message.input_chat, message.id) if message.input_chat else None
|
msg_data = (message.input_chat, message.id) if message.input_chat else None
|
||||||
|
|
|
@ -489,7 +489,7 @@ async def send_message(
|
||||||
request = _tl.fn.messages.SendMessage(
|
request = _tl.fn.messages.SendMessage(
|
||||||
peer=entity,
|
peer=entity,
|
||||||
message=message._text,
|
message=message._text,
|
||||||
entities=formatting_entities,
|
entities=message._fmt_entities,
|
||||||
no_webpage=not link_preview,
|
no_webpage=not link_preview,
|
||||||
reply_to_msg_id=utils.get_message_id(reply_to),
|
reply_to_msg_id=utils.get_message_id(reply_to),
|
||||||
clear_draft=clear_draft,
|
clear_draft=clear_draft,
|
||||||
|
@ -508,7 +508,7 @@ async def send_message(
|
||||||
date=result.date,
|
date=result.date,
|
||||||
out=result.out,
|
out=result.out,
|
||||||
media=result.media,
|
media=result.media,
|
||||||
entities=result.entities,
|
entities=result._fmt_entities,
|
||||||
reply_markup=request.reply_markup,
|
reply_markup=request.reply_markup,
|
||||||
ttl_period=result.ttl_period
|
ttl_period=result.ttl_period
|
||||||
), {}, entity)
|
), {}, entity)
|
||||||
|
@ -579,35 +579,88 @@ async def forward_messages(
|
||||||
async def edit_message(
|
async def edit_message(
|
||||||
self: 'TelegramClient',
|
self: 'TelegramClient',
|
||||||
entity: 'typing.Union[hints.EntityLike, _tl.Message]',
|
entity: 'typing.Union[hints.EntityLike, _tl.Message]',
|
||||||
message: 'hints.MessageLike' = None,
|
message_id: 'hints.MessageLike' = None,
|
||||||
text: str = None,
|
text: str = None,
|
||||||
*,
|
*,
|
||||||
parse_mode: str = (),
|
# - Message contents
|
||||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
# Formatting
|
||||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
markdown: str = None,
|
||||||
link_preview: bool = True,
|
html: str = None,
|
||||||
file: 'hints.FileLike' = None,
|
formatting_entities: list = None,
|
||||||
thumb: 'hints.FileLike' = None,
|
link_preview: bool = (),
|
||||||
force_document: bool = False,
|
# Media
|
||||||
buttons: 'hints.MarkupLike' = None,
|
file: typing.Optional[hints.FileLike] = None,
|
||||||
|
file_name: str = None,
|
||||||
|
mime_type: str = None,
|
||||||
|
thumb: str = False,
|
||||||
|
force_file: bool = False,
|
||||||
|
file_size: int = None,
|
||||||
|
# Media attributes
|
||||||
|
duration: int = None,
|
||||||
|
width: int = None,
|
||||||
|
height: int = None,
|
||||||
|
title: str = None,
|
||||||
|
performer: str = None,
|
||||||
supports_streaming: bool = False,
|
supports_streaming: bool = False,
|
||||||
schedule: 'hints.DateLike' = None
|
video_note: bool = False,
|
||||||
|
voice_note: bool = False,
|
||||||
|
waveform: bytes = None,
|
||||||
|
# Additional parametrization
|
||||||
|
buttons: list = None,
|
||||||
|
ttl: int = None,
|
||||||
|
# - Send options
|
||||||
|
schedule: 'hints.DateLike' = None,
|
||||||
) -> '_tl.Message':
|
) -> '_tl.Message':
|
||||||
if formatting_entities is None:
|
if isinstance(text, str) or text is None:
|
||||||
text, formatting_entities = await self._parse_message_text(text, parse_mode)
|
message = InputMessage(
|
||||||
file_handle, media, image = await self._file_to_media(file,
|
text=text,
|
||||||
supports_streaming=supports_streaming,
|
markdown=markdown,
|
||||||
|
html=html,
|
||||||
|
formatting_entities=formatting_entities,
|
||||||
|
link_preview=link_preview,
|
||||||
|
file=file,
|
||||||
|
file_name=file_name,
|
||||||
|
mime_type=mime_type,
|
||||||
thumb=thumb,
|
thumb=thumb,
|
||||||
attributes=attributes,
|
force_file=force_file,
|
||||||
force_document=force_document)
|
file_size=file_size,
|
||||||
|
duration=duration,
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
title=title,
|
||||||
|
performer=performer,
|
||||||
|
supports_streaming=supports_streaming,
|
||||||
|
video_note=video_note,
|
||||||
|
voice_note=voice_note,
|
||||||
|
waveform=waveform,
|
||||||
|
silent=False,
|
||||||
|
buttons=buttons,
|
||||||
|
ttl=ttl,
|
||||||
|
)
|
||||||
|
elif isinstance(text, _custom.Message):
|
||||||
|
# TODO accept this as the first and only parameter
|
||||||
|
message = message._as_input()
|
||||||
|
elif not isinstance(text, InputMessage):
|
||||||
|
raise TypeError(f'text must be either str, Message or InputMessage, but got: {text!r}')
|
||||||
|
|
||||||
|
if message._file:
|
||||||
|
# TODO Properly implement allow_cache to reuse the sha256 of the file
|
||||||
|
# i.e. `None` was used
|
||||||
|
|
||||||
|
# TODO album
|
||||||
|
if message._file._should_upload_thumb():
|
||||||
|
message._file._set_uploaded_thumb(await self.upload_file(message._file._thumb))
|
||||||
|
|
||||||
|
if message._file._should_upload_file():
|
||||||
|
message._file._set_uploaded_file(await self.upload_file(message._file._file))
|
||||||
|
|
||||||
if isinstance(message, _tl.InputBotInlineMessageID):
|
if isinstance(message, _tl.InputBotInlineMessageID):
|
||||||
request = _tl.fn.messages.EditInlineBotMessage(
|
request = _tl.fn.messages.EditInlineBotMessage(
|
||||||
id=message,
|
id=message_id,
|
||||||
message=text,
|
message=message._text,
|
||||||
no_webpage=not link_preview,
|
no_webpage=not link_preview,
|
||||||
entities=formatting_entities,
|
entities=message._fmt_entities,
|
||||||
media=media,
|
media=message._file._media,
|
||||||
reply_markup=_custom.button.build_reply_markup(buttons)
|
reply_markup=_custom.button.build_reply_markup(buttons)
|
||||||
)
|
)
|
||||||
# Invoke `messages.editInlineBotMessage` from the right datacenter.
|
# Invoke `messages.editInlineBotMessage` from the right datacenter.
|
||||||
|
@ -622,17 +675,13 @@ async def edit_message(
|
||||||
else:
|
else:
|
||||||
return await self(request)
|
return await self(request)
|
||||||
|
|
||||||
entity = await self.get_input_entity(entity)
|
message_id = utils.get_message_id(message_id)
|
||||||
|
|
||||||
request = _tl.fn.messages.EditMessage(
|
request = _tl.fn.messages.EditMessage(
|
||||||
peer=entity,
|
entity, message_id, no_webpage=not link_preview, message=message._text,
|
||||||
id=utils.get_message_id(message),
|
media=message._file._media if message._file else None, reply_markup=message._reply_markup, entities=message._fmt_entities, schedule_date=schedule
|
||||||
message=text,
|
|
||||||
no_webpage=not link_preview,
|
|
||||||
entities=formatting_entities,
|
|
||||||
media=media,
|
|
||||||
reply_markup=_custom.button.build_reply_markup(buttons),
|
|
||||||
schedule_date=schedule
|
|
||||||
)
|
)
|
||||||
|
|
||||||
msg = self._get_response_message(request, await self(request), entity)
|
msg = self._get_response_message(request, await self(request), entity)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import typing
|
||||||
from ..errors._custom import MultiError
|
from ..errors._custom import MultiError
|
||||||
from ..errors._rpcbase import RpcError, ServerError, FloodError, InvalidDcError, UnauthorizedError
|
from ..errors._rpcbase import RpcError, ServerError, FloodError, InvalidDcError, UnauthorizedError
|
||||||
from .._misc import helpers, utils, hints
|
from .._misc import helpers, utils, hints
|
||||||
from .._sessions.types import Entity
|
from .._sessions.types import Entity, get_peer_canonical_entity_type
|
||||||
from .. import errors, _tl
|
from .. import errors, _tl
|
||||||
|
|
||||||
_NOT_A_REQUEST = lambda: TypeError('You can only invoke requests, not types!')
|
_NOT_A_REQUEST = lambda: TypeError('You can only invoke requests, not types!')
|
||||||
|
@ -235,8 +235,10 @@ async def get_input_entity(
|
||||||
# Next in priority is having a peer (or its ID) cached in-memory
|
# Next in priority is having a peer (or its ID) cached in-memory
|
||||||
try:
|
try:
|
||||||
# 0x2d45687 == crc32(b'Peer')
|
# 0x2d45687 == crc32(b'Peer')
|
||||||
if isinstance(peer, int) or peer.SUBCLASS_OF_ID == 0x2d45687:
|
# TODO: FIXME: This logic is incorrect - Peers are unhashable and the cache should be sorted by Entity.ty
|
||||||
return self._entity_cache[peer]
|
# if isinstance(peer, int) or peer.SUBCLASS_OF_ID == 0x2d45687:
|
||||||
|
# return self._entity_cache[peer]
|
||||||
|
pass
|
||||||
except (AttributeError, KeyError):
|
except (AttributeError, KeyError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -250,13 +252,14 @@ async def get_input_entity(
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
entity = await self.session.get_entity(None, peer_id)
|
entity_type = get_peer_canonical_entity_type(peer)
|
||||||
|
entity = await self.session.get_entity(entity_type, peer_id)
|
||||||
if entity:
|
if entity:
|
||||||
if entity.ty in (Entity.USER, Entity.BOT):
|
if entity_type == Entity.USER:
|
||||||
return _tl.InputPeerUser(entity.id, entity.access_hash)
|
return _tl.InputPeerUser(entity.id, entity.access_hash)
|
||||||
elif entity.ty in (Entity.GROUP):
|
elif entity_type == Entity.GROUP:
|
||||||
return _tl.InputPeerChat(peer.chat_id)
|
return _tl.InputPeerChat(peer.chat_id)
|
||||||
elif entity.ty in (Entity.CHANNEL, Entity.MEGAGROUP, Entity.GIGAGROUP):
|
elif entity_type == Entity.CHANNEL:
|
||||||
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
||||||
|
|
||||||
# Only network left to try
|
# Only network left to try
|
||||||
|
|
|
@ -7,14 +7,12 @@ from ..types import _custom
|
||||||
|
|
||||||
Phone = str
|
Phone = str
|
||||||
Username = str
|
Username = str
|
||||||
PeerID = int
|
|
||||||
Entity = typing.Union[_tl.User, _tl.Chat, _tl.Channel]
|
Entity = typing.Union[_tl.User, _tl.Chat, _tl.Channel]
|
||||||
FullEntity = typing.Union[_tl.UserFull, _tl.messages.ChatFull, _tl.ChatFull, _tl.ChannelFull]
|
FullEntity = typing.Union[_tl.UserFull, _tl.messages.ChatFull, _tl.ChatFull, _tl.ChannelFull]
|
||||||
|
|
||||||
EntityLike = typing.Union[
|
EntityLike = typing.Union[
|
||||||
Phone,
|
Phone,
|
||||||
Username,
|
Username,
|
||||||
PeerID,
|
|
||||||
_tl.TypePeer,
|
_tl.TypePeer,
|
||||||
_tl.TypeInputPeer,
|
_tl.TypeInputPeer,
|
||||||
Entity,
|
Entity,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .types import DataCenter, ChannelState, SessionState, Entity
|
from .types import DataCenter, ChannelState, SessionState, Entity, get_entity_type_group
|
||||||
from .abstract import Session
|
from .abstract import Session
|
||||||
from .._misc import utils, tlobject
|
from .._misc import utils, tlobject
|
||||||
from .. import _tl
|
from .. import _tl
|
||||||
|
@ -34,11 +34,11 @@ class MemorySession(Session):
|
||||||
return list(self.channel_states.values())
|
return list(self.channel_states.values())
|
||||||
|
|
||||||
async def insert_entities(self, entities: List[Entity]):
|
async def insert_entities(self, entities: List[Entity]):
|
||||||
self.entities.update((e.id, (e.ty, e.access_hash)) for e in entities)
|
self.entities.update(((get_peer_canonical_entity_type(e.ty), e.id), e.access_hash) for e in entities)
|
||||||
|
|
||||||
async def get_entity(self, ty: Optional[int], id: int) -> Optional[Entity]:
|
async def get_entity(self, ty: int, id: int) -> Optional[Entity]:
|
||||||
try:
|
try:
|
||||||
ty, access_hash = self.entities[id]
|
access_hash = self.entities[get_peer_canonical_entity_type(ty), id]
|
||||||
return Entity(ty, id, access_hash)
|
return Entity(ty, id, access_hash)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple, Union
|
||||||
|
from .. import _tl
|
||||||
|
from .._misc import hints, utils
|
||||||
|
|
||||||
|
|
||||||
class DataCenter:
|
class DataCenter:
|
||||||
|
@ -155,3 +157,21 @@ def get_entity_type_group(ty: int, *, _mapping={
|
||||||
except KeyError:
|
except KeyError:
|
||||||
ty = chr(ty) if isinstance(ty, int) else ty
|
ty = chr(ty) if isinstance(ty, int) else ty
|
||||||
raise ValueError(f'entity type {ty!r} is not valid')
|
raise ValueError(f'entity type {ty!r} is not valid')
|
||||||
|
|
||||||
|
|
||||||
|
def get_peer_canonical_entity_type(peer: Union[
|
||||||
|
_tl.TypePeer,
|
||||||
|
_tl.TypeInputPeer,
|
||||||
|
hints.Entity,
|
||||||
|
hints.FullEntity,
|
||||||
|
], *, _mapping={
|
||||||
|
_tl.PeerUser: Entity.USER,
|
||||||
|
_tl.PeerChat: Entity.GROUP,
|
||||||
|
_tl.PeerChannel: Entity.CHANNEL,
|
||||||
|
}) -> int:
|
||||||
|
peer = utils.get_peer(peer)
|
||||||
|
try:
|
||||||
|
return _mapping[type(peer)]
|
||||||
|
except KeyError:
|
||||||
|
# Safe to log full peer since only contains the ID
|
||||||
|
raise ValueError(f'Unexpected peer {peer!r}')
|
||||||
|
|
|
@ -90,8 +90,9 @@ class InputFile:
|
||||||
elif isinstance(thumb, (_tl.InputFile, _tl.InputFileBig)):
|
elif isinstance(thumb, (_tl.InputFile, _tl.InputFileBig)):
|
||||||
self._uploaded_thumb = (thumb, time.time())
|
self._uploaded_thumb = (thumb, time.time())
|
||||||
|
|
||||||
else:
|
elif thumb:
|
||||||
raise TypeError(f'thumb must be a file to upload, but got: {thumb!r}')
|
raise TypeError(f'thumb must be a file to upload, but got: {thumb!r}')
|
||||||
|
# else: it's falsey, ignore it
|
||||||
|
|
||||||
# document parameters (only if it's our file, i.e. there's no media ready yet)
|
# document parameters (only if it's our file, i.e. there's no media ready yet)
|
||||||
if self._media:
|
if self._media:
|
||||||
|
|
|
@ -160,7 +160,7 @@ class Message(ChatGetter, SenderGetter):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return None if media.CONSTRUCTOR_ID == 0x3ded6320 else media
|
return None if media is None or media.CONSTRUCTOR_ID == 0x3ded6320 else media
|
||||||
|
|
||||||
@media.setter
|
@media.setter
|
||||||
def media(self, value):
|
def media(self, value):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user