Migrate resolve_bot_file_id to using tg_file_id as dependency.

This commit is contained in:
luckydonald 2020-11-07 22:03:54 +01:00
parent bd49e2cee5
commit 78a9b7f4d5

View File

@ -15,8 +15,10 @@ import os
import pathlib
import re
import struct
from tg_file_id.file_id import FileId, DocumentFileId, PhotoFileId
from collections import namedtuple
from mimetypes import guess_extension
from typing import Union
from types import GeneratorType
from .extensions import markdown, html
@ -1101,104 +1103,85 @@ def resolve_bot_file_id(file_id):
For thumbnails, the photo ID and hash will always be zero.
"""
data = _rle_decode(_decode_telegram_base64(file_id))
if not data:
if not file_id:
return None
# This isn't officially documented anywhere, but
# we assume the last byte is some kind of "version".
data, version = data[:-1], data[-1]
if version not in (2, 4):
# end if
if isinstance(file_id, str):
file = FileId.from_file_id(file_id)
elif not isinstance(file_id, FileId):
return None
# end if
if (version == 2 and len(data) == 24) or (version == 4 and len(data) == 25):
if version == 2:
file_type, dc_id, media_id, access_hash = struct.unpack('<iiqq', data)
# elif version == 4:
else:
# TODO Figure out what the extra byte means
file_type, dc_id, media_id, access_hash, _ = struct.unpack('<iiqqb', data)
if not (1 <= dc_id <= 5):
# Valid `file_id`'s must have valid DC IDs. Since this method is
# called when sending a file and the user may have entered a path
# they believe is correct but the file doesn't exist, this method
# may detect a path as "valid" bot `file_id` even when it's not.
# By checking the `dc_id`, we greatly reduce the chances of this
# happening.
return None
if isinstance(file, DocumentFileId):
attributes = []
if file_type == 3 or file_type == 9:
if file.type_id in (FileId.TYPE_VOICE, FileId.TYPE_AUDIO):
attributes.append(types.DocumentAttributeAudio(
duration=0,
voice=file_type == 3
voice=file.type_id == FileId.TYPE_VOICE
))
elif file_type == 4 or file_type == 13:
elif file.type_id == FileId.TYPE_VIDEO or file.type_id == FileId.TYPE_VIDEO_NOTE:
attributes.append(types.DocumentAttributeVideo(
duration=0,
w=0,
h=0,
round_message=file_type == 13
round_message=file.type_id == FileId.TYPE_VIDEO_NOTE
))
# elif file_type == 5: # other, cannot know which
elif file_type == 8:
# elif file.type_id == FieldId.TYPE_DOCUMENT: # other, cannot know which --> no attribute
elif file.type_id == FileId.TYPE_STICKER:
attributes.append(types.DocumentAttributeSticker(
alt='',
stickerset=types.InputStickerSetEmpty()
))
elif file_type == 10:
elif file.type_id == FileId.TYPE_ANIMATION:
attributes.append(types.DocumentAttributeAnimated())
# end if
return types.Document(
id=media_id,
access_hash=access_hash,
id=file.id,
access_hash=file.access_hash,
date=None,
mime_type='',
size=0,
thumbs=None,
dc_id=dc_id,
dc_id=file.dc_id,
attributes=attributes,
file_reference=b''
file_reference=file.file_reference if file.has_reference else b''
)
elif (version == 2 and len(data) == 44) or (version == 4 and len(data) in (49, 77)):
if version == 2:
(file_type, dc_id, media_id, access_hash,
volume_id, secret, local_id) = struct.unpack('<iiqqqqi', data)
# else version == 4:
elif len(data) == 49:
# TODO Figure out what the extra five bytes mean
(file_type, dc_id, media_id, access_hash,
volume_id, secret, local_id, _) = struct.unpack('<iiqqqqi5s', data)
elif len(data) == 77:
# See #1613.
(file_type, dc_id, _, media_id, access_hash, volume_id, _, local_id, _) = struct.unpack('<ii28sqqq12sib', data)
else:
return None
elif not isinstance(file, PhotoFileId): # e.g. WebLocationFileId
return None
# end if
if not (1 <= dc_id <= 5):
return None
# okey, so we're dealing with a photo.
assert isinstance(file, PhotoFileId)
photo_size = 's' if file.id or file.access_hash else 'x'
# Thumbnails (small) always have ID 0; otherwise size 'x'
photo_size = 's' if media_id or access_hash else 'x'
return types.Photo(
id=media_id,
access_hash=access_hash,
file_reference=b'',
date=None,
sizes=[types.PhotoSize(
foto_size = file.photosize
if isinstance(foto_size, (PhotoFileId.PhotosizeSourceLegacy, PhotoFileId.PhotosizeSourceThumbnail, PhotoFileId.PhotosizeSourceDialogPhotoSmall, PhotoFileId.PhotosizeSourceDialogPhotoBig, PhotoFileId.PhotosizeSourceStickersetThumbnail)):
sizes = [
types.PhotoSize(
type=photo_size,
location=types.FileLocationToBeDeprecated(
volume_id=volume_id,
local_id=local_id
volume_id=foto_size.volume_id,
local_id=foto_size.location_local_id,
),
w=0,
h=0,
size=0
)],
dc_id=dc_id,
has_stickers=None
)
)
]
else:
sizes = []
# end if
return types.Photo(
id=file.id,
access_hash=file.access_hash,
file_reference=file.file_reference,
date=None,
sizes=sizes,
dc_id=file.dc_id,
has_stickers=None
)
def pack_bot_file_id(file):