Add support for in-memory uploads in send_media_group (#519)

* Add support for in-memory uploads for send_media_group

* update input_media_photo docs

* update type hints

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
This commit is contained in:
Dan 2021-06-01 13:57:31 +02:00
parent 0d12d8c1bb
commit 523ed3e7cb
6 changed files with 232 additions and 125 deletions

View File

@ -116,7 +116,7 @@ class SaveFile(Scaffold):
else:
raise ValueError("Invalid file. Expected a file path as string or a binary (not text) file pointer")
file_name = fp.name
file_name = getattr(fp, "name", "file.jpg")
fp.seek(0, os.SEEK_END)
file_size = fp.tell()
@ -148,7 +148,6 @@ class SaveFile(Scaffold):
for session in pool:
await session.start()
with fp:
fp.seek(part_size * file_part)
while True:
@ -222,3 +221,6 @@ class SaveFile(Scaffold):
for session in pool:
await session.stop()
if isinstance(path, (str, PurePath)):
fp.close()

View File

@ -19,7 +19,6 @@
import logging
import os
import re
import io
from typing import Union, List
from pyrogram import raw
@ -88,7 +87,8 @@ class SendMediaGroup(Scaffold):
for i in media:
if isinstance(i, types.InputMediaPhoto):
if os.path.isfile(i.media) or isinstance(i.media, io.IOBase):
if isinstance(i.media, str):
if os.path.isfile(i.media):
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
@ -124,8 +124,26 @@ class SendMediaGroup(Scaffold):
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.PHOTO)
else:
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedPhoto(
file=await self.save_file(i.media)
)
)
)
media = raw.types.InputMediaPhoto(
id=raw.types.InputPhoto(
id=media.photo.id,
access_hash=media.photo.access_hash,
file_reference=media.photo.file_reference
)
)
elif isinstance(i, types.InputMediaVideo):
if os.path.isfile(i.media) or isinstance(i.media, io.IOBase):
if isinstance(i.media, str):
if os.path.isfile(i.media):
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
@ -172,7 +190,36 @@ class SendMediaGroup(Scaffold):
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.VIDEO)
else:
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
mime_type=self.guess_mime_type(getattr(i.media, "name", "video.mp4")) or "video/mp4",
attributes=[
raw.types.DocumentAttributeVideo(
supports_streaming=i.supports_streaming or None,
duration=i.duration,
w=i.width,
h=i.height
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "video.mp4"))
]
)
)
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
)
elif isinstance(i, types.InputMediaAudio):
if isinstance(i.media, str):
if os.path.isfile(i.media):
media = await self.send(
raw.functions.messages.UploadMedia(
@ -219,7 +266,35 @@ class SendMediaGroup(Scaffold):
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.AUDIO)
else:
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(getattr(i.media, "name", "audio.mp3")) or "audio/mpeg",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
attributes=[
raw.types.DocumentAttributeAudio(
duration=i.duration,
performer=i.performer,
title=i.title
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "audio.mp3"))
]
)
)
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
)
elif isinstance(i, types.InputMediaDocument):
if isinstance(i.media, str):
if os.path.isfile(i.media):
media = await self.send(
raw.functions.messages.UploadMedia(
@ -261,6 +336,32 @@ class SendMediaGroup(Scaffold):
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.DOCUMENT)
else:
media = await self.send(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(
getattr(i.media, "name", "file.zip")
) or "application/zip",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
attributes=[
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "file.zip"))
]
)
)
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
)
else:
raise ValueError(f"{i.__class__.__name__} is not a supported type for send_media_group")
multi_media.append(
raw.types.InputSingleMedia(

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, List
from typing import Optional, List, Union, BinaryIO
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
@ -30,6 +30,7 @@ class InputMediaAnimation(InputMedia):
Animation to send.
Pass a file_id as string to send a file that exists on the Telegram servers or
pass a file path as string to upload a new file that exists on your local machine or
pass a binary file-like object with its attribute .name set for in-memory uploads or
pass an HTTP URL as a string for Telegram to get an animation from the Internet.
thumb (``str``, *optional*):
@ -64,7 +65,7 @@ class InputMediaAnimation(InputMedia):
def __init__(
self,
media: str,
media: Union[str, BinaryIO],
thumb: str = None,
caption: str = "",
parse_mode: Optional[str] = object,

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, List
from typing import Optional, List, BinaryIO, Union
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
@ -32,6 +32,7 @@ class InputMediaAudio(InputMedia):
Audio to send.
Pass a file_id as string to send an audio that exists on the Telegram servers or
pass a file path as string to upload a new audio that exists on your local machine or
pass a binary file-like object with its attribute .name set for in-memory uploads or
pass an HTTP URL as a string for Telegram to get an audio file from the Internet.
thumb (``str``, *optional*):
@ -66,7 +67,7 @@ class InputMediaAudio(InputMedia):
def __init__(
self,
media: str,
media: Union[str, BinaryIO],
thumb: str = None,
caption: str = "",
parse_mode: Optional[str] = object,

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, List
from typing import Optional, List, Union, BinaryIO
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
@ -30,6 +30,7 @@ class InputMediaDocument(InputMedia):
File to send.
Pass a file_id as string to send a file that exists on the Telegram servers or
pass a file path as string to upload a new file that exists on your local machine or
pass a binary file-like object with its attribute .name set for in-memory uploads or
pass an HTTP URL as a string for Telegram to get a file from the Internet.
thumb (``str``):
@ -55,7 +56,7 @@ class InputMediaDocument(InputMedia):
def __init__(
self,
media: str,
media: Union[str, BinaryIO],
thumb: str = None,
caption: str = "",
parse_mode: Optional[str] = object,

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, List
from typing import Optional, List, Union, BinaryIO
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
@ -31,6 +31,7 @@ class InputMediaVideo(InputMedia):
Video to send.
Pass a file_id as string to send a video that exists on the Telegram servers or
pass a file path as string to upload a new video that exists on your local machine or
pass a binary file-like object with its attribute .name set for in-memory uploads or
pass an HTTP URL as a string for Telegram to get a video from the Internet.
thumb (``str``):
@ -68,7 +69,7 @@ class InputMediaVideo(InputMedia):
def __init__(
self,
media: str,
media: Union[str, BinaryIO],
thumb: str = None,
caption: str = "",
parse_mode: Optional[str] = object,