From bf11bbd8a6a5848dba91d4c8effbde053878514b Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Tue, 12 Feb 2019 11:33:06 +0100 Subject: [PATCH] Support sending bytes/stream as photos (improved _get_extension) Letting _get_extension work for photos even when the only information available is a stream or a few bytes allows sending arbitrary bytes as photos, if force_document was not set to True explicitly. --- telethon/client/uploads.py | 6 ++++++ telethon/utils.py | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/telethon/client/uploads.py b/telethon/client/uploads.py index fc9dffdd..a44c0806 100644 --- a/telethon/client/uploads.py +++ b/telethon/client/uploads.py @@ -337,6 +337,12 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods): else: file_name = str(file_id) + # If the file name lacks extension, add it if possible. + # Else Telegram complains with `PHOTO_EXT_INVALID_ERROR` + # even if the uploaded image is indeed a photo. + if not os.path.splitext(file_name)[-1]: + file_name += utils._get_extension(file) + # Determine whether the file is too big (over 10MB) or not # Telegram does make a distinction between smaller or larger files is_large = file_size > 10 * 1024 * 1024 diff --git a/telethon/utils.py b/telethon/utils.py index d43e2647..8e9d8a2f 100644 --- a/telethon/utils.py +++ b/telethon/utils.py @@ -4,6 +4,9 @@ to convert between an entity like a User, Chat, etc. into its Input version) """ import base64 import binascii +import imghdr +import inspect +import io import itertools import math import mimetypes @@ -16,7 +19,6 @@ from types import GeneratorType from .extensions import markdown, html from .helpers import add_surrogate, del_surrogate from .tl import types -import inspect try: import hachoir @@ -632,6 +634,12 @@ def _get_extension(file): """ if isinstance(file, str): return os.path.splitext(file)[-1] + elif isinstance(file, bytes): + kind = imghdr.what(io.BytesIO(file)) + return ('.' + kind) if kind else '' + elif isinstance(file, io.IOBase) and file.seekable(): + kind = imghdr.what(file) is not None + return ('.' + kind) if kind else '' elif getattr(file, 'name', None): return _get_extension(file.name) else: