diff --git a/pyrogram/client.py b/pyrogram/client.py
index 28c65c16..df06e94c 100644
--- a/pyrogram/client.py
+++ b/pyrogram/client.py
@@ -47,6 +47,7 @@ from pyrogram.storage import Storage, FileStorage, MemoryStorage
from pyrogram.types import User, TermsOfService
from pyrogram.utils import ainput
from .dispatcher import Dispatcher
+from .file_id import FileId, FileType, ThumbnailSource
from .scaffold import Scaffold
log = logging.getLogger(__name__)
@@ -493,22 +494,11 @@ class Client(Methods, Scaffold):
final_file_path = ""
try:
- data, directory, file_name, progress, progress_args = packet
+ file_id, directory, file_name, file_size, progress, progress_args = packet
temp_file_path = await self.get_file(
- media_type=data.media_type,
- dc_id=data.dc_id,
- document_id=data.document_id,
- access_hash=data.access_hash,
- thumb_size=data.thumb_size,
- peer_id=data.peer_id,
- peer_type=data.peer_type,
- peer_access_hash=data.peer_access_hash,
- volume_id=data.volume_id,
- local_id=data.local_id,
- file_ref=data.file_ref,
- file_size=data.file_size,
- is_big=data.is_big,
+ file_id=file_id,
+ file_size=file_size,
progress=progress,
progress_args=progress_args
)
@@ -817,22 +807,13 @@ class Client(Methods, Scaffold):
async def get_file(
self,
- media_type: int,
- dc_id: int,
- document_id: int,
- access_hash: int,
- thumb_size: str,
- peer_id: int,
- peer_type: str,
- peer_access_hash: int,
- volume_id: int,
- local_id: int,
- file_ref: str,
+ file_id: FileId,
file_size: int,
- is_big: bool,
progress: callable,
progress_args: tuple = ()
) -> str:
+ dc_id = file_id.dc_id
+
async with self.media_sessions_lock:
session = self.media_sessions.get(dc_id, None)
@@ -874,49 +855,43 @@ class Client(Methods, Scaffold):
self.media_sessions[dc_id] = session
- file_ref = utils.decode_file_ref(file_ref)
+ file_type = file_id.file_type
- if media_type == 1:
- if peer_type == "user":
+ if file_type == FileType.CHAT_PHOTO:
+ if file_id.chat_id > 0:
peer = raw.types.InputPeerUser(
- user_id=peer_id,
- access_hash=peer_access_hash
- )
- elif peer_type == "chat":
- peer = raw.types.InputPeerChat(
- chat_id=peer_id
+ user_id=file_id.chat_id,
+ access_hash=file_id.chat_access_hash
)
else:
- peer = raw.types.InputPeerChannel(
- channel_id=peer_id,
- access_hash=peer_access_hash
- )
+ if file_id.chat_access_hash == 0:
+ peer = raw.types.InputPeerChat(
+ chat_id=file_id.chat_id
+ )
+ else:
+ peer = raw.types.InputPeerChannel(
+ channel_id=file_id.chat_id,
+ access_hash=file_id.chat_access_hash
+ )
location = raw.types.InputPeerPhotoFileLocation(
peer=peer,
- volume_id=volume_id,
- local_id=local_id,
- big=is_big or None
+ volume_id=file_id.volume_id,
+ local_id=file_id.local_id,
+ big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG
)
- elif media_type in (0, 2):
+ elif file_type in (FileType.THUMBNAIL, FileType.PHOTO):
location = raw.types.InputPhotoFileLocation(
- id=document_id,
- access_hash=access_hash,
- file_reference=file_ref,
- thumb_size=thumb_size
- )
- elif media_type == 14:
- location = raw.types.InputDocumentFileLocation(
- id=document_id,
- access_hash=access_hash,
- file_reference=file_ref,
- thumb_size=thumb_size
+ id=file_id.media_id,
+ access_hash=file_id.access_hash,
+ file_reference=file_id.file_reference,
+ thumb_size=file_id.thumbnail_size
)
else:
location = raw.types.InputDocumentFileLocation(
- id=document_id,
- access_hash=access_hash,
- file_reference=file_ref,
+ id=file_id.media_id,
+ access_hash=file_id.access_hash,
+ file_reference=file_id.file_reference,
thumb_size=""
)
diff --git a/pyrogram/methods/chats/set_chat_photo.py b/pyrogram/methods/chats/set_chat_photo.py
index 8ccb123c..0474fd18 100644
--- a/pyrogram/methods/chats/set_chat_photo.py
+++ b/pyrogram/methods/chats/set_chat_photo.py
@@ -22,6 +22,7 @@ from typing import Union, BinaryIO
from pyrogram import raw
from pyrogram import utils
from pyrogram.scaffold import Scaffold
+from pyrogram.file_id import FileType
class SetChatPhoto(Scaffold):
@@ -30,8 +31,7 @@ class SetChatPhoto(Scaffold):
chat_id: Union[int, str],
*,
photo: Union[str, BinaryIO] = None,
- video: Union[str, BinaryIO] = None,
- file_ref: str = None
+ video: Union[str, BinaryIO] = None
) -> bool:
"""Set a new chat photo or video (H.264/MPEG-4 AVC video, max 5 seconds).
@@ -45,19 +45,15 @@ class SetChatPhoto(Scaffold):
Unique identifier (int) or username (str) of the target chat.
photo (``str`` | ``BinaryIO``, *optional*):
- New chat photo. You can pass a :obj:`~pyrogram.types.Photo` file_id (in pair with a valid file_ref), a
- file path to upload a new photo from your local machine or a binary file-like object with its attribute
+ New chat photo. You can pass a :obj:`~pyrogram.types.Photo` file_id, a file path to upload a new photo
+ from your local machine or a binary file-like object with its attribute
".name" set for in-memory uploads.
video (``str`` | ``BinaryIO``, *optional*):
- New chat video. You can pass a :obj:`~pyrogram.types.Video` file_id (in pair with a valid file_ref), a
- file path to upload a new video from your local machine or a binary file-like object with its attribute
+ New chat video. You can pass a :obj:`~pyrogram.types.Video` file_id, a file path to upload a new video
+ from your local machine or a binary file-like object with its attribute
".name" set for in-memory uploads.
- file_ref (``str``, *optional*):
- A valid file reference obtained by a recently fetched media message.
- To be used in combination with a file_id in case a file reference is needed.
-
Returns:
``bool``: True on success.
@@ -71,14 +67,14 @@ class SetChatPhoto(Scaffold):
app.set_chat_photo(chat_id, photo="photo.jpg")
# Set chat photo using an exiting Photo file_id
- app.set_chat_photo(chat_id, photo=photo.file_id, file_ref=photo.file_ref)
+ app.set_chat_photo(chat_id, photo=photo.file_id)
# Set chat video using a local file
app.set_chat_photo(chat_id, video="video.mp4")
# Set chat photo using an exiting Video file_id
- app.set_chat_photo(chat_id, video=video.file_id, file_ref=video.file_ref)
+ app.set_chat_photo(chat_id, video=video.file_id)
"""
peer = await self.resolve_peer(chat_id)
@@ -89,7 +85,7 @@ class SetChatPhoto(Scaffold):
video=await self.save_file(video)
)
else:
- photo = utils.get_input_media_from_file_id(photo, file_ref, 2)
+ photo = utils.get_input_media_from_file_id(photo, FileType.PHOTO)
photo = raw.types.InputChatPhoto(id=photo.id)
else:
photo = raw.types.InputChatUploadedPhoto(
diff --git a/pyrogram/methods/messages/download_media.py b/pyrogram/methods/messages/download_media.py
index c6919809..c2d4d0b4 100644
--- a/pyrogram/methods/messages/download_media.py
+++ b/pyrogram/methods/messages/download_media.py
@@ -17,51 +17,22 @@
# along with Pyrogram. If not, see .
import asyncio
-import binascii
import os
-import struct
import time
from datetime import datetime
from typing import Union
from pyrogram import types
-from pyrogram import utils
-from pyrogram.errors import FileIdInvalid
+from pyrogram.file_id import FileId, FileType, PHOTO_TYPES
from pyrogram.scaffold import Scaffold
DEFAULT_DOWNLOAD_DIR = "downloads/"
-class FileData:
- def __init__(
- self, *, media_type: int = None, dc_id: int = None, document_id: int = None, access_hash: int = None,
- thumb_size: str = None, peer_id: int = None, peer_type: str = None, peer_access_hash: int = None,
- volume_id: int = None, local_id: int = None, is_big: bool = None, file_size: int = None, mime_type: str = None,
- file_name: str = None, date: int = None, file_ref: str = None
- ):
- self.media_type = media_type
- self.dc_id = dc_id
- self.document_id = document_id
- self.access_hash = access_hash
- self.thumb_size = thumb_size
- self.peer_id = peer_id
- self.peer_type = peer_type
- self.peer_access_hash = peer_access_hash
- self.volume_id = volume_id
- self.local_id = local_id
- self.is_big = is_big
- self.file_size = file_size
- self.mime_type = mime_type
- self.file_name = file_name
- self.date = date
- self.file_ref = file_ref
-
-
class DownloadMedia(Scaffold):
async def download_media(
self,
- message: Union["types.Message", str],
- file_ref: str = None,
+ media: Union["types.Message", str],
file_name: str = DEFAULT_DOWNLOAD_DIR,
block: bool = True,
progress: callable = None,
@@ -70,13 +41,9 @@ class DownloadMedia(Scaffold):
"""Download the media from a message.
Parameters:
- message (:obj:`~pyrogram.types.Message` | ``str``):
- Pass a Message containing the media, the media itself (message.audio, message.video, ...) or
- the file id as string.
-
- file_ref (``str``, *optional*):
- A valid file reference obtained by a recently fetched media message.
- To be used in combination with a file id in case a file reference is needed.
+ media (:obj:`~pyrogram.types.Message` | ``str``):
+ Pass a Message containing the media, the media itself (message.audio, message.video, ...) or a file id
+ as string.
file_name (``str``, *optional*):
A custom *file_name* to be used instead of the one provided by Telegram.
@@ -133,136 +100,63 @@ class DownloadMedia(Scaffold):
app.download_media(message, progress=progress)
"""
- error_message = "This message doesn't contain any downloadable media"
- available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note", "new_chat_photo")
+ available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note",
+ "new_chat_photo")
- media_file_name = None
- file_size = None
- mime_type = None
- date = None
-
- if isinstance(message, types.Message):
+ if isinstance(media, types.Message):
for kind in available_media:
- media = getattr(message, kind, None)
+ media = getattr(media, kind, None)
if media is not None:
break
else:
- raise ValueError(error_message)
- else:
- media = message
+ raise ValueError("This message doesn't contain any downloadable media")
if isinstance(media, str):
file_id_str = media
else:
file_id_str = media.file_id
- media_file_name = getattr(media, "file_name", "")
- file_size = getattr(media, "file_size", None)
- mime_type = getattr(media, "mime_type", None)
- date = getattr(media, "date", None)
- file_ref = getattr(media, "file_ref", None)
- data = FileData(
- file_name=media_file_name,
- file_size=file_size,
- mime_type=mime_type,
- date=date,
- file_ref=file_ref
- )
+ file_id_obj = FileId.decode(file_id_str)
- def get_existing_attributes() -> dict:
- return dict(filter(lambda x: x[1] is not None, data.__dict__.items()))
-
- try:
- decoded = utils.decode_file_id(file_id_str)
- media_type = decoded[0]
-
- if media_type == 1:
- unpacked = struct.unpack(".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -31,10 +30,11 @@ class Animation(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
width (``int``):
Animation width as defined by sender.
@@ -66,7 +66,7 @@ class Animation(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
width: int,
height: int,
duration: int,
@@ -79,7 +79,7 @@ class Animation(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.file_name = file_name
self.mime_type = mime_type
self.file_size = file_size
@@ -97,16 +97,17 @@ class Animation(Object):
file_name: str
) -> "Animation":
return Animation(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -31,14 +30,21 @@ class Audio(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
duration (``int``):
Duration of the audio in seconds as defined by sender.
+ performer (``str``, *optional*):
+ Performer of the audio as defined by sender or by audio tags.
+
+ title (``str``, *optional*):
+ Title of the audio as defined by sender or by audio tags.
+
file_name (``str``, *optional*):
Audio file name.
@@ -49,13 +55,7 @@ class Audio(Object):
File size.
date (``int``, *optional*):
- Date the audio was sent in Unix time.
-
- performer (``str``, *optional*):
- Performer of the audio as defined by sender or by audio tags.
-
- title (``str``, *optional*):
- Title of the audio as defined by sender or by audio tags.
+ Date the audio was originally sent, in Unix time.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Thumbnails of the music file album cover.
@@ -66,27 +66,27 @@ class Audio(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
duration: int,
+ performer: str = None,
+ title: str = None,
file_name: str = None,
mime_type: str = None,
file_size: int = None,
date: int = None,
- performer: str = None,
- title: str = None,
thumbs: List["types.Thumbnail"] = None
):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
+ self.duration = duration
+ self.performer = performer
+ self.title = title
self.file_name = file_name
self.mime_type = mime_type
self.file_size = file_size
self.date = date
- self.duration = duration
- self.performer = performer
- self.title = title
self.thumbs = thumbs
@staticmethod
@@ -97,16 +97,17 @@ class Audio(Object):
file_name: str
) -> "Audio":
return Audio(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -31,10 +30,11 @@ class Document(Object):
Parameters:
file_id (``str``):
- Unique file identifier.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
file_name (``str``, *optional*):
Original filename as defined by sender.
@@ -57,7 +57,7 @@ class Document(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
file_name: str = None,
mime_type: str = None,
file_size: int = None,
@@ -67,7 +67,7 @@ class Document(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.file_name = file_name
self.mime_type = mime_type
self.file_size = file_size
@@ -77,16 +77,17 @@ class Document(Object):
@staticmethod
def _parse(client, document: "raw.types.Document", file_name: str) -> "Document":
return Document(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource
from ..object import Object
@@ -31,10 +30,11 @@ class Photo(Object):
Parameters:
file_id (``str``):
- Unique identifier for this photo.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
width (``int``):
Photo width.
@@ -60,7 +60,7 @@ class Photo(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
width: int,
height: int,
file_size: int,
@@ -71,7 +71,7 @@ class Photo(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.width = width
self.height = height
self.file_size = file_size
@@ -82,18 +82,36 @@ class Photo(Object):
@staticmethod
def _parse(client, photo: "raw.types.Photo", ttl_seconds: int = None) -> "Photo":
if isinstance(photo, raw.types.Photo):
- big = list(filter(lambda p: isinstance(p, raw.types.PhotoSize), photo.sizes))[-1]
+ big = photo.sizes[-1]
+
+ if isinstance(big, raw.types.PhotoSizeProgressive):
+ big = raw.types.PhotoSize(
+ type=big.type,
+ location=big.location,
+ w=big.w,
+ h=big.h,
+ size=big.sizes[-1]
+ )
return Photo(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
from async_lru import alru_cache
@@ -25,7 +24,7 @@ import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram.errors import StickersetInvalid
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -34,10 +33,11 @@ class Sticker(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
width (``int``):
Sticker width.
@@ -77,7 +77,7 @@ class Sticker(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
width: int,
height: int,
is_animated: bool,
@@ -92,7 +92,7 @@ class Sticker(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.file_name = file_name
self.mime_type = mime_type
self.file_size = file_size
@@ -137,16 +137,17 @@ class Sticker(Object):
set_name = None
return Sticker(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import Union, List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource
from ..object import Object
@@ -31,7 +30,11 @@ class Thumbnail(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
+
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
width (``int``):
Photo width.
@@ -48,6 +51,7 @@ class Thumbnail(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
+ file_unique_id: str,
width: int,
height: int,
file_size: int
@@ -55,6 +59,7 @@ class Thumbnail(Object):
super().__init__(client)
self.file_id = file_id
+ self.file_unique_id = file_unique_id
self.width = width
self.height = height
self.file_size = file_size
@@ -66,10 +71,8 @@ class Thumbnail(Object):
) -> Union[List[Union["types.StrippedThumbnail", "Thumbnail"]], None]:
if isinstance(media, raw.types.Photo):
raw_thumbnails = media.sizes[:-1]
- media_type = 2
elif isinstance(media, raw.types.Document):
raw_thumbnails = media.thumbs
- media_type = 14
if not raw_thumbnails:
return None
@@ -78,6 +81,9 @@ class Thumbnail(Object):
thumbnails = []
+ file_type = FileType.PHOTO if isinstance(media, raw.types.Photo) else FileType.THUMBNAIL
+ thumbnail_file_type = file_type
+
for thumbnail in raw_thumbnails:
# TODO: Enable this
# if isinstance(thumbnail, types.PhotoStrippedSize):
@@ -85,14 +91,24 @@ class Thumbnail(Object):
if isinstance(thumbnail, raw.types.PhotoSize):
thumbnails.append(
Thumbnail(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -31,10 +30,11 @@ class Video(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
width (``int``):
Video width as defined by sender.
@@ -51,18 +51,18 @@ class Video(Object):
mime_type (``str``, *optional*):
Mime type of a file as defined by sender.
- supports_streaming (``bool``, *optional*):
- True, if the video was uploaded with streaming support.
-
file_size (``int``, *optional*):
File size.
- date (``int``, *optional*):
- Date the video was sent in Unix time.
+ supports_streaming (``bool``, *optional*):
+ True, if the video was uploaded with streaming support.
ttl_seconds (``int``. *optional*):
Time-to-live seconds, for secret photos.
+ date (``int``, *optional*):
+ Date the video was sent in Unix time.
+
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Video thumbnails.
"""
@@ -72,31 +72,31 @@ class Video(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
width: int,
height: int,
duration: int,
file_name: str = None,
mime_type: str = None,
- supports_streaming: bool = None,
file_size: int = None,
- date: int = None,
+ supports_streaming: bool = None,
ttl_seconds: int = None,
+ date: int = None,
thumbs: List["types.Thumbnail"] = None
):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.width = width
self.height = height
self.duration = duration
self.file_name = file_name
self.mime_type = mime_type
- self.supports_streaming = supports_streaming
self.file_size = file_size
- self.date = date
+ self.supports_streaming = supports_streaming
self.ttl_seconds = ttl_seconds
+ self.date = date
self.thumbs = thumbs
@staticmethod
@@ -108,16 +108,17 @@ class Video(Object):
ttl_seconds: int = None
) -> "Video":
return Video(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -31,10 +30,11 @@ class VideoNote(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
length (``int``):
Video width and height as defined by sender.
@@ -60,7 +60,7 @@ class VideoNote(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
length: int,
duration: int,
thumbs: List["types.Thumbnail"] = None,
@@ -71,7 +71,7 @@ class VideoNote(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.mime_type = mime_type
self.file_size = file_size
self.date = date
@@ -86,16 +86,17 @@ class VideoNote(Object):
video_attributes: "raw.types.DocumentAttributeVideo"
) -> "VideoNote":
return VideoNote(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
-
import pyrogram
from pyrogram import raw
-from pyrogram.utils import encode_file_id, encode_file_ref
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object
@@ -29,10 +27,11 @@ class Voice(Object):
Parameters:
file_id (``str``):
- Unique identifier for this file.
+ Identifier for this file, which can be used to download or reuse the file.
- file_ref (``str``):
- Up to date file reference.
+ file_unique_id (``str``):
+ Unique identifier for this file, which is supposed to be the same over time and for different accounts.
+ Can't be used to download or reuse the file.
duration (``int``):
Duration of the audio in seconds as defined by sender.
@@ -55,7 +54,7 @@ class Voice(Object):
*,
client: "pyrogram.Client" = None,
file_id: str,
- file_ref: str,
+ file_unique_id: str,
duration: int,
waveform: bytes = None,
mime_type: str = None,
@@ -65,7 +64,7 @@ class Voice(Object):
super().__init__(client)
self.file_id = file_id
- self.file_ref = file_ref
+ self.file_unique_id = file_unique_id
self.duration = duration
self.waveform = waveform
self.mime_type = mime_type
@@ -75,16 +74,17 @@ class Voice(Object):
@staticmethod
def _parse(client, voice: "raw.types.Document", attributes: "raw.types.DocumentAttributeAudio") -> "Voice":
return Voice(
- file_id=encode_file_id(
- pack(
- ".
-from struct import pack
from typing import Union
import pyrogram
from pyrogram import raw
-from pyrogram.utils import encode_file_id
+from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource
from ..object import Object
-from ... import utils
class ChatPhoto(Object):
@@ -34,9 +32,17 @@ class ChatPhoto(Object):
File identifier of small (160x160) chat photo.
This file_id can be used only for photo download and only for as long as the photo is not changed.
+ small_photo_unique_id (``str``):
+ Unique file identifier of small (160x160) chat photo, which is supposed to be the same over time and for
+ different accounts. Can't be used to download or reuse the file.
+
big_file_id (``str``):
File identifier of big (640x640) chat photo.
This file_id can be used only for photo download and only for as long as the photo is not changed.
+
+ big_photo_unique_id (``str``):
+ Unique file identifier of big (640x640) chat photo, which is supposed to be the same over time and for
+ different accounts. Can't be used to download or reuse the file.
"""
def __init__(
@@ -44,12 +50,17 @@ class ChatPhoto(Object):
*,
client: "pyrogram.Client" = None,
small_file_id: str,
- big_file_id: str
+ small_photo_unique_id: str,
+ big_file_id: str,
+ big_photo_unique_id: str
+
):
super().__init__(client)
self.small_file_id = small_file_id
+ self.small_photo_unique_id = small_photo_unique_id
self.big_file_id = big_file_id
+ self.big_photo_unique_id = big_photo_unique_id
@staticmethod
def _parse(
@@ -61,39 +72,40 @@ class ChatPhoto(Object):
if not isinstance(chat_photo, (raw.types.UserProfilePhoto, raw.types.ChatPhoto)):
return None
- if peer_access_hash is None:
- return None
-
- photo_id = getattr(chat_photo, "photo_id", 0)
- loc_small = chat_photo.photo_small
- loc_big = chat_photo.photo_big
-
- peer_type = utils.get_peer_type(peer_id)
-
- if peer_type == "user":
- x = 0
- elif peer_type == "chat":
- x = -1
- else:
- peer_id += 1000727379968
- x = -234
+ media_id = chat_photo.photo_id if isinstance(chat_photo, raw.types.UserProfilePhoto) else 0
return ChatPhoto(
- small_file_id=encode_file_id(
- pack(
- " bytes:
- s = base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
- r = b""
-
- major = s[-1]
- minor = s[-2] if major != 2 else 0
-
- assert minor in (0, 22, 24)
-
- skip = 2 if minor else 1
-
- i = 0
-
- while i < len(s) - skip:
- if s[i] != 0:
- r += bytes([s[i]])
- else:
- r += b"\x00" * s[i + 1]
- i += 1
-
- i += 1
-
- return r
-
-
-def encode_file_id(s: bytes) -> str:
- r = b""
- n = 0
-
- for i in s + bytes([22]) + bytes([4]):
- if i == 0:
- n += 1
- else:
- if n:
- r += b"\x00" + bytes([n])
- n = 0
-
- r += bytes([i])
-
- return base64.urlsafe_b64encode(r).decode().rstrip("=")
-
-
-def encode_file_ref(file_ref: bytes) -> str:
- return base64.urlsafe_b64encode(file_ref).decode().rstrip("=")
-
-
-def decode_file_ref(file_ref: str) -> bytes:
- if file_ref is None:
- return b""
-
- return base64.urlsafe_b64decode(file_ref + "=" * (-len(file_ref) % 4))
+from pyrogram.file_id import FileId, FileType, PHOTO_TYPES, DOCUMENT_TYPES
async def ainput(prompt: str = "", *, hide: bool = False):
@@ -102,52 +49,38 @@ def get_offset_date(dialogs):
def get_input_media_from_file_id(
- file_id_str: str,
- file_ref: str = None,
- expected_media_type: int = None
+ file_id: str,
+ expected_file_type: FileType = None
) -> Union["raw.types.InputMediaPhoto", "raw.types.InputMediaDocument"]:
- try:
- decoded = decode_file_id(file_id_str)
- except Exception:
- raise ValueError(f"Failed to decode file_id: {file_id_str}")
- else:
- media_type = decoded[0]
+ decoded = FileId.decode(file_id)
- if expected_media_type is not None:
- if media_type != expected_media_type:
- media_type_str = Scaffold.MEDIA_TYPE_ID.get(media_type, None)
- expected_media_type_str = Scaffold.MEDIA_TYPE_ID.get(expected_media_type, None)
+ file_type = decoded.file_type
- raise ValueError(f'Expected: "{expected_media_type_str}", got "{media_type_str}" file_id instead')
+ if expected_file_type is not None and file_type != expected_file_type:
+ raise ValueError(f'Expected: "{expected_file_type}", got "{file_type}" file_id instead')
- if media_type in (0, 1, 14):
- raise ValueError(f"This file_id can only be used for download: {file_id_str}")
+ if file_type in (FileType.THUMBNAIL, FileType.CHAT_PHOTO):
+ raise ValueError(f"This file_id can only be used for download: {file_id}")
- if media_type == 2:
- unpacked = struct.unpack(" List["types.Message"]: