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 .._misc import utils, helpers, requestiter, tlobject, hints
|
||||
from ..types._custom import Message
|
||||
from .. import errors, _tl
|
||||
|
||||
try:
|
||||
|
@ -267,7 +268,8 @@ async def download_media(
|
|||
msg_data = None
|
||||
|
||||
# TODO This won't work for messageService
|
||||
if isinstance(message, _tl.Message):
|
||||
# TODO Handle _tl.Message
|
||||
if isinstance(message, Message):
|
||||
date = message.date
|
||||
media = message.media
|
||||
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(
|
||||
peer=entity,
|
||||
message=message._text,
|
||||
entities=formatting_entities,
|
||||
entities=message._fmt_entities,
|
||||
no_webpage=not link_preview,
|
||||
reply_to_msg_id=utils.get_message_id(reply_to),
|
||||
clear_draft=clear_draft,
|
||||
|
@ -508,7 +508,7 @@ async def send_message(
|
|||
date=result.date,
|
||||
out=result.out,
|
||||
media=result.media,
|
||||
entities=result.entities,
|
||||
entities=result._fmt_entities,
|
||||
reply_markup=request.reply_markup,
|
||||
ttl_period=result.ttl_period
|
||||
), {}, entity)
|
||||
|
@ -579,35 +579,88 @@ async def forward_messages(
|
|||
async def edit_message(
|
||||
self: 'TelegramClient',
|
||||
entity: 'typing.Union[hints.EntityLike, _tl.Message]',
|
||||
message: 'hints.MessageLike' = None,
|
||||
message_id: 'hints.MessageLike' = None,
|
||||
text: str = None,
|
||||
*,
|
||||
parse_mode: str = (),
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
link_preview: bool = True,
|
||||
file: 'hints.FileLike' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
force_document: bool = False,
|
||||
buttons: 'hints.MarkupLike' = None,
|
||||
# - Message contents
|
||||
# Formatting
|
||||
markdown: str = None,
|
||||
html: str = None,
|
||||
formatting_entities: list = None,
|
||||
link_preview: bool = (),
|
||||
# Media
|
||||
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,
|
||||
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':
|
||||
if formatting_entities is None:
|
||||
text, formatting_entities = await self._parse_message_text(text, parse_mode)
|
||||
file_handle, media, image = await self._file_to_media(file,
|
||||
supports_streaming=supports_streaming,
|
||||
if isinstance(text, str) or text is None:
|
||||
message = InputMessage(
|
||||
text=text,
|
||||
markdown=markdown,
|
||||
html=html,
|
||||
formatting_entities=formatting_entities,
|
||||
link_preview=link_preview,
|
||||
file=file,
|
||||
file_name=file_name,
|
||||
mime_type=mime_type,
|
||||
thumb=thumb,
|
||||
attributes=attributes,
|
||||
force_document=force_document)
|
||||
force_file=force_file,
|
||||
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):
|
||||
request = _tl.fn.messages.EditInlineBotMessage(
|
||||
id=message,
|
||||
message=text,
|
||||
id=message_id,
|
||||
message=message._text,
|
||||
no_webpage=not link_preview,
|
||||
entities=formatting_entities,
|
||||
media=media,
|
||||
entities=message._fmt_entities,
|
||||
media=message._file._media,
|
||||
reply_markup=_custom.button.build_reply_markup(buttons)
|
||||
)
|
||||
# Invoke `messages.editInlineBotMessage` from the right datacenter.
|
||||
|
@ -622,17 +675,13 @@ async def edit_message(
|
|||
else:
|
||||
return await self(request)
|
||||
|
||||
entity = await self.get_input_entity(entity)
|
||||
message_id = utils.get_message_id(message_id)
|
||||
|
||||
request = _tl.fn.messages.EditMessage(
|
||||
peer=entity,
|
||||
id=utils.get_message_id(message),
|
||||
message=text,
|
||||
no_webpage=not link_preview,
|
||||
entities=formatting_entities,
|
||||
media=media,
|
||||
reply_markup=_custom.button.build_reply_markup(buttons),
|
||||
schedule_date=schedule
|
||||
entity, message_id, no_webpage=not link_preview, message=message._text,
|
||||
media=message._file._media if message._file else None, reply_markup=message._reply_markup, entities=message._fmt_entities, schedule_date=schedule
|
||||
)
|
||||
|
||||
msg = self._get_response_message(request, await self(request), entity)
|
||||
return msg
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import typing
|
|||
from ..errors._custom import MultiError
|
||||
from ..errors._rpcbase import RpcError, ServerError, FloodError, InvalidDcError, UnauthorizedError
|
||||
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
|
||||
|
||||
_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
|
||||
try:
|
||||
# 0x2d45687 == crc32(b'Peer')
|
||||
if isinstance(peer, int) or peer.SUBCLASS_OF_ID == 0x2d45687:
|
||||
return self._entity_cache[peer]
|
||||
# TODO: FIXME: This logic is incorrect - Peers are unhashable and the cache should be sorted by Entity.ty
|
||||
# if isinstance(peer, int) or peer.SUBCLASS_OF_ID == 0x2d45687:
|
||||
# return self._entity_cache[peer]
|
||||
pass
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
|
||||
|
@ -250,13 +252,14 @@ async def get_input_entity(
|
|||
except TypeError:
|
||||
pass
|
||||
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.ty in (Entity.USER, Entity.BOT):
|
||||
if entity_type == Entity.USER:
|
||||
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)
|
||||
elif entity.ty in (Entity.CHANNEL, Entity.MEGAGROUP, Entity.GIGAGROUP):
|
||||
elif entity_type == Entity.CHANNEL:
|
||||
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
||||
|
||||
# Only network left to try
|
||||
|
|
|
@ -7,14 +7,12 @@ from ..types import _custom
|
|||
|
||||
Phone = str
|
||||
Username = str
|
||||
PeerID = int
|
||||
Entity = typing.Union[_tl.User, _tl.Chat, _tl.Channel]
|
||||
FullEntity = typing.Union[_tl.UserFull, _tl.messages.ChatFull, _tl.ChatFull, _tl.ChannelFull]
|
||||
|
||||
EntityLike = typing.Union[
|
||||
Phone,
|
||||
Username,
|
||||
PeerID,
|
||||
_tl.TypePeer,
|
||||
_tl.TypeInputPeer,
|
||||
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 .._misc import utils, tlobject
|
||||
from .. import _tl
|
||||
|
@ -34,11 +34,11 @@ class MemorySession(Session):
|
|||
return list(self.channel_states.values())
|
||||
|
||||
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:
|
||||
ty, access_hash = self.entities[id]
|
||||
access_hash = self.entities[get_peer_canonical_entity_type(ty), id]
|
||||
return Entity(ty, id, access_hash)
|
||||
except KeyError:
|
||||
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:
|
||||
|
@ -155,3 +157,21 @@ def get_entity_type_group(ty: int, *, _mapping={
|
|||
except KeyError:
|
||||
ty = chr(ty) if isinstance(ty, int) else ty
|
||||
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)):
|
||||
self._uploaded_thumb = (thumb, time.time())
|
||||
|
||||
else:
|
||||
elif thumb:
|
||||
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)
|
||||
if self._media:
|
||||
|
|
|
@ -160,7 +160,7 @@ class Message(ChatGetter, SenderGetter):
|
|||
except AttributeError:
|
||||
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
|
||||
def media(self, value):
|
||||
|
|
Loading…
Reference in New Issue
Block a user