Implement media spoilers in friendly methods

May need a bit more testing, I can't test everything, apologies
This commit is contained in:
Nick80835 2023-04-21 21:39:43 -04:00
parent 9aad453e1a
commit 5c7782643d
3 changed files with 83 additions and 26 deletions

View File

@ -642,6 +642,7 @@ class MessageMethods:
schedule: 'hints.DateLike' = None, schedule: 'hints.DateLike' = None,
comment_to: 'typing.Union[int, types.Message]' = None, comment_to: 'typing.Union[int, types.Message]' = None,
nosound_video: bool = None, nosound_video: bool = None,
spoiler: typing.Union[bool, typing.Sequence[bool]] = None
) -> 'types.Message': ) -> 'types.Message':
""" """
Sends a message to the specified user, chat or channel. Sends a message to the specified user, chat or channel.
@ -764,6 +765,11 @@ class MessageMethods:
on non-video files. This is set to ``True`` for albums, as gifs on non-video files. This is set to ``True`` for albums, as gifs
cannot be sent in albums. cannot be sent in albums.
spoiler (`bool`, optional):
Whether or not to spoiler the media in the sent message. When sending an
album, this may be a list of booleans, which will be
assigned to the media pairwise.
Returns Returns
The sent `custom.Message <telethon.tl.custom.message.Message>`. The sent `custom.Message <telethon.tl.custom.message.Message>`.
@ -832,7 +838,7 @@ class MessageMethods:
schedule=schedule, supports_streaming=supports_streaming, schedule=schedule, supports_streaming=supports_streaming,
formatting_entities=formatting_entities, formatting_entities=formatting_entities,
comment_to=comment_to, background=background, comment_to=comment_to, background=background,
nosound_video=nosound_video, nosound_video=nosound_video, spoiler=spoiler
) )
entity = await self.get_input_entity(entity) entity = await self.get_input_entity(entity)
@ -1061,7 +1067,8 @@ class MessageMethods:
force_document: bool = False, force_document: bool = False,
buttons: typing.Optional['hints.MarkupLike'] = None, buttons: typing.Optional['hints.MarkupLike'] = None,
supports_streaming: bool = False, supports_streaming: bool = False,
schedule: 'hints.DateLike' = None schedule: 'hints.DateLike' = None,
spoiler: bool = None
) -> 'types.Message': ) -> 'types.Message':
""" """
Edits the given message to change its text or media. Edits the given message to change its text or media.
@ -1145,6 +1152,9 @@ class MessageMethods:
Note that this parameter will have no effect if you are Note that this parameter will have no effect if you are
trying to edit a message that was sent via inline bots. trying to edit a message that was sent via inline bots.
spoiler (`bool`, optional):
Whether or not to spoiler the media in the sent message.
Returns Returns
The edited `Message <telethon.tl.custom.message.Message>`, The edited `Message <telethon.tl.custom.message.Message>`,
unless `entity` was a :tl:`InputBotInlineMessageID` or :tl:`InputBotInlineMessageID64` in which unless `entity` was a :tl:`InputBotInlineMessageID` or :tl:`InputBotInlineMessageID64` in which
@ -1183,11 +1193,14 @@ class MessageMethods:
if formatting_entities is None: if formatting_entities is None:
text, formatting_entities = await self._parse_message_text(text, parse_mode) text, formatting_entities = await self._parse_message_text(text, parse_mode)
file_handle, media, image = await self._file_to_media(file, file_handle, media, image = await self._file_to_media(file,
supports_streaming=supports_streaming, supports_streaming=supports_streaming,
thumb=thumb, thumb=thumb,
attributes=attributes, attributes=attributes,
force_document=force_document) force_document=force_document,
spoiler=spoiler
)
if isinstance(entity, (types.InputBotInlineMessageID, types.InputBotInlineMessageID64)): if isinstance(entity, (types.InputBotInlineMessageID, types.InputBotInlineMessageID64)):
request = functions.messages.EditInlineBotMessageRequest( request = functions.messages.EditInlineBotMessageRequest(

View File

@ -118,6 +118,7 @@ class UploadMethods:
comment_to: 'typing.Union[int, types.Message]' = None, comment_to: 'typing.Union[int, types.Message]' = None,
ttl: int = None, ttl: int = None,
nosound_video: bool = None, nosound_video: bool = None,
spoiler: typing.Union[bool, typing.Sequence[bool]] = None,
**kwargs) -> 'types.Message': **kwargs) -> 'types.Message':
""" """
Sends message with the given file to the specified entity. Sends message with the given file to the specified entity.
@ -296,6 +297,11 @@ class UploadMethods:
on non-video files. This is set to ``True`` for albums, as gifs on non-video files. This is set to ``True`` for albums, as gifs
cannot be sent in albums. cannot be sent in albums.
spoiler (`bool`, optional):
Whether or not to spoiler the media in the sent message. When sending an
album, this may be a list of booleans, which will be
assigned to the media pairwise.
Returns Returns
The `Message <telethon.tl.custom.message.Message>` (or messages) The `Message <telethon.tl.custom.message.Message>` (or messages)
containing the sent file, or messages if a list of them was passed. containing the sent file, or messages if a list of them was passed.
@ -372,6 +378,11 @@ class UploadMethods:
else: else:
captions = [caption] captions = [caption]
if utils.is_list_like(spoiler):
spoilers = spoiler
else:
spoilers = [spoiler]
result = [] result = []
while file: while file:
result += await self._send_album( result += await self._send_album(
@ -380,9 +391,11 @@ class UploadMethods:
parse_mode=parse_mode, silent=silent, schedule=schedule, parse_mode=parse_mode, silent=silent, schedule=schedule,
supports_streaming=supports_streaming, clear_draft=clear_draft, supports_streaming=supports_streaming, clear_draft=clear_draft,
force_document=force_document, background=background, force_document=force_document, background=background,
spoiler=spoilers[:10]
) )
file = file[10:] file = file[10:]
captions = captions[10:] captions = captions[10:]
spoilers = spoilers[10:]
sent_count += 10 sent_count += 10
return result return result
@ -400,7 +413,7 @@ class UploadMethods:
attributes=attributes, allow_cache=allow_cache, thumb=thumb, attributes=attributes, allow_cache=allow_cache, thumb=thumb,
voice_note=voice_note, video_note=video_note, voice_note=voice_note, video_note=video_note,
supports_streaming=supports_streaming, ttl=ttl, supports_streaming=supports_streaming, ttl=ttl,
nosound_video=nosound_video, nosound_video=nosound_video, spoiler=spoiler
) )
# e.g. invalid cast from :tl:`MessageMediaWebPage` # e.g. invalid cast from :tl:`MessageMediaWebPage`
@ -420,7 +433,8 @@ class UploadMethods:
progress_callback=None, reply_to=None, progress_callback=None, reply_to=None,
parse_mode=(), silent=None, schedule=None, parse_mode=(), silent=None, schedule=None,
supports_streaming=None, clear_draft=None, supports_streaming=None, clear_draft=None,
force_document=False, background=None, ttl=None): force_document=False, background=None, ttl=None,
spoiler=None):
"""Specialized version of .send_file for albums""" """Specialized version of .send_file for albums"""
# We don't care if the user wants to avoid cache, we will use it # We don't care if the user wants to avoid cache, we will use it
# anyway. Why? The cached version will be exactly the same thing # anyway. Why? The cached version will be exactly the same thing
@ -439,6 +453,14 @@ class UploadMethods:
for c in reversed(caption): # Pop from the end (so reverse) for c in reversed(caption): # Pop from the end (so reverse)
captions.append(await self._parse_message_text(c or '', parse_mode)) captions.append(await self._parse_message_text(c or '', parse_mode))
if utils.is_list_like(spoiler):
spoilers = spoiler
else:
spoilers = [spoiler]
while len(spoilers) < len(files):
spoilers.append(None)
reply_to = utils.get_message_id(reply_to) reply_to = utils.get_message_id(reply_to)
used_callback = None if not progress_callback else ( used_callback = None if not progress_callback else (
@ -456,20 +478,27 @@ class UploadMethods:
fh, fm, _ = await self._file_to_media( fh, fm, _ = await self._file_to_media(
file, supports_streaming=supports_streaming, file, supports_streaming=supports_streaming,
force_document=force_document, ttl=ttl, force_document=force_document, ttl=ttl,
progress_callback=used_callback, nosound_video=True) progress_callback=used_callback, nosound_video=True,
spoiler=spoilers[sent_count])
if isinstance(fm, (types.InputMediaUploadedPhoto, types.InputMediaPhotoExternal)): if isinstance(fm, (types.InputMediaUploadedPhoto, types.InputMediaPhotoExternal)):
r = await self(functions.messages.UploadMediaRequest( r = await self(functions.messages.UploadMediaRequest(
entity, media=fm entity, media=fm
)) ))
fm = utils.get_input_media(r.photo) fm = utils.get_input_media(
r.photo,
spoiler=spoilers[sent_count]
)
elif isinstance(fm, types.InputMediaUploadedDocument): elif isinstance(fm, types.InputMediaUploadedDocument):
r = await self(functions.messages.UploadMediaRequest( r = await self(functions.messages.UploadMediaRequest(
entity, media=fm entity, media=fm
)) ))
fm = utils.get_input_media( fm = utils.get_input_media(
r.document, supports_streaming=supports_streaming) r.document,
supports_streaming=supports_streaming,
spoiler=spoilers[sent_count]
)
if captions: if captions:
caption, msg_entities = captions.pop() caption, msg_entities = captions.pop()
@ -686,7 +715,7 @@ class UploadMethods:
progress_callback=None, attributes=None, thumb=None, progress_callback=None, attributes=None, thumb=None,
allow_cache=True, voice_note=False, video_note=False, allow_cache=True, voice_note=False, video_note=False,
supports_streaming=False, mime_type=None, as_image=None, supports_streaming=False, mime_type=None, as_image=None,
ttl=None, nosound_video=None): ttl=None, nosound_video=None, spoiler=None):
if not file: if not file:
return None, None, None return None, None, None
@ -716,7 +745,8 @@ class UploadMethods:
voice_note=voice_note, voice_note=voice_note,
video_note=video_note, video_note=video_note,
supports_streaming=supports_streaming, supports_streaming=supports_streaming,
ttl=ttl ttl=ttl,
spoiler=spoiler
), as_image) ), as_image)
except TypeError: except TypeError:
# Can't turn whatever was given into media # Can't turn whatever was given into media
@ -735,13 +765,13 @@ class UploadMethods:
) )
elif re.match('https?://', file): elif re.match('https?://', file):
if as_image: if as_image:
media = types.InputMediaPhotoExternal(file, ttl_seconds=ttl) media = types.InputMediaPhotoExternal(file, ttl_seconds=ttl, spoiler=spoiler)
else: else:
media = types.InputMediaDocumentExternal(file, ttl_seconds=ttl) media = types.InputMediaDocumentExternal(file, ttl_seconds=ttl, spoiler=spoiler)
else: else:
bot_file = utils.resolve_bot_file_id(file) bot_file = utils.resolve_bot_file_id(file)
if bot_file: if bot_file:
media = utils.get_input_media(bot_file, ttl=ttl) media = utils.get_input_media(bot_file, ttl=ttl, spoiler=spoiler)
if media: if media:
pass # Already have media, don't check the rest pass # Already have media, don't check the rest
@ -751,7 +781,7 @@ class UploadMethods:
'an HTTP URL or a valid bot-API-like file ID'.format(file) 'an HTTP URL or a valid bot-API-like file ID'.format(file)
) )
elif as_image: elif as_image:
media = types.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl) media = types.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl, spoiler=spoiler)
else: else:
attributes, mime_type = utils.get_attributes( attributes, mime_type = utils.get_attributes(
file, file,
@ -782,7 +812,8 @@ class UploadMethods:
thumb=thumb, thumb=thumb,
force_file=force_document and not is_image, force_file=force_document and not is_image,
ttl_seconds=ttl, ttl_seconds=ttl,
nosound_video=nosound_video nosound_video=nosound_video,
spoiler=spoiler
) )
return file_handle, media, as_image return file_handle, media, as_image

View File

@ -430,7 +430,7 @@ def get_input_media(
media, *, media, *,
is_photo=False, attributes=None, force_document=False, is_photo=False, attributes=None, force_document=False,
voice_note=False, video_note=False, supports_streaming=False, voice_note=False, video_note=False, supports_streaming=False,
ttl=None ttl=None, spoiler=None
): ):
""" """
Similar to :meth:`get_input_peer`, but for media. Similar to :meth:`get_input_peer`, but for media.
@ -452,30 +452,38 @@ def get_input_media(
if isinstance(media, types.MessageMediaPhoto): if isinstance(media, types.MessageMediaPhoto):
return types.InputMediaPhoto( return types.InputMediaPhoto(
id=get_input_photo(media.photo), id=get_input_photo(media.photo),
ttl_seconds=ttl or media.ttl_seconds ttl_seconds=ttl or media.ttl_seconds,
spoiler=spoiler or media.spoiler
) )
if isinstance(media, (types.Photo, types.photos.Photo, types.PhotoEmpty)): if isinstance(media, (types.Photo, types.photos.Photo, types.PhotoEmpty)):
return types.InputMediaPhoto( return types.InputMediaPhoto(
id=get_input_photo(media), id=get_input_photo(media),
ttl_seconds=ttl ttl_seconds=ttl,
spoiler=spoiler
) )
if isinstance(media, types.MessageMediaDocument): if isinstance(media, types.MessageMediaDocument):
return types.InputMediaDocument( return types.InputMediaDocument(
id=get_input_document(media.document), id=get_input_document(media.document),
ttl_seconds=ttl or media.ttl_seconds ttl_seconds=ttl or media.ttl_seconds,
spoiler=spoiler or media.spoiler
) )
if isinstance(media, (types.Document, types.DocumentEmpty)): if isinstance(media, (types.Document, types.DocumentEmpty)):
return types.InputMediaDocument( return types.InputMediaDocument(
id=get_input_document(media), id=get_input_document(media),
ttl_seconds=ttl ttl_seconds=ttl,
spoiler=spoiler
) )
if isinstance(media, (types.InputFile, types.InputFileBig)): if isinstance(media, (types.InputFile, types.InputFileBig)):
if is_photo: if is_photo:
return types.InputMediaUploadedPhoto(file=media, ttl_seconds=ttl) return types.InputMediaUploadedPhoto(
file=media,
ttl_seconds=ttl,
spoiler=spoiler
)
else: else:
attrs, mime = get_attributes( attrs, mime = get_attributes(
media, media,
@ -486,8 +494,13 @@ def get_input_media(
supports_streaming=supports_streaming supports_streaming=supports_streaming
) )
return types.InputMediaUploadedDocument( return types.InputMediaUploadedDocument(
file=media, mime_type=mime, attributes=attrs, force_file=force_document, file=media,
ttl_seconds=ttl) mime_type=mime,
attributes=attrs,
force_file=force_document,
ttl_seconds=ttl,
spoiler=spoiler
)
if isinstance(media, types.MessageMediaGame): if isinstance(media, types.MessageMediaGame):
return types.InputMediaGame(id=types.InputGameID( return types.InputMediaGame(id=types.InputGameID(