From 40616ba7046a62496a09bb0820d11a81df6d84f8 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Fri, 9 Jun 2017 11:12:56 +0200 Subject: [PATCH] Support arbitrary file objects for .download_file() and update README --- README.rst | 10 ++++------ telethon/telegram_bare_client.py | 23 +++++++++++++++-------- telethon/telegram_client.py | 12 +++++++++--- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index 046072f8..c9f8576c 100755 --- a/README.rst +++ b/README.rst @@ -138,6 +138,10 @@ disconnects the client. Another common one is the ``RPCError``, which usually has descriptive information on what went wrong. However, you may encounter something strange. If you don't manage to solve it, please open an issue. +Unless you know what you're doing, you should download media by always using the ``.download_file()`` +function, which supports a ``str`` or a file handle as parameters. Otherwise, ``.invoke()`` may raise +``InvalidDCError`` which you will have to handle, and in turn call ``.invoke_on_dc()`` manually. + Advanced uses ============= @@ -241,9 +245,3 @@ Once this is done, pass the proxy settings to the ``TelegramClient`` constructor The ``proxy=`` argument should be a tuple, a list or a dict, consisting of parameters described `here `_. - -Disclaimer -========== - -This project was originally an implementation from TLSharp (a C# library for the Telegram API), -but since then, the project has evolved a lot on its own. \ No newline at end of file diff --git a/telethon/telegram_bare_client.py b/telethon/telegram_bare_client.py index 4097e1a7..d9057dfe 100644 --- a/telethon/telegram_bare_client.py +++ b/telethon/telegram_bare_client.py @@ -283,11 +283,11 @@ class TelegramBareClient: def download_file(self, input_location, - file_path, + file, part_size_kb=None, file_size=None, progress_callback=None): - """Downloads the given InputFileLocation to file_path. + """Downloads the given InputFileLocation to file (a stream or str). If 'progress_callback' is not None, it should be a function that takes two parameters, (bytes_downloaded, total_bytes). Note that @@ -303,11 +303,15 @@ class TelegramBareClient: if part_size % 1024 != 0: raise ValueError('The part size must be evenly divisible by 1024.') - # Ensure that we'll be able to download the media - utils.ensure_parent_dir_exists(file_path) + if isinstance(file, str): + # Ensure that we'll be able to download the media + utils.ensure_parent_dir_exists(file) + f = open(file, 'wb') + else: + f = file - offset_index = 0 - with open(file_path, 'wb') as file: + try: + offset_index = 0 while True: offset = offset_index * part_size result = self.invoke( @@ -319,8 +323,11 @@ class TelegramBareClient: if not result.bytes: return result.type # Return some extra information - file.write(result.bytes) + f.write(result.bytes) if progress_callback: - progress_callback(file.tell(), file_size) + progress_callback(f.tell(), file_size) + finally: + if isinstance(file, str): + f.close() # endregion diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py index 7247be38..421ad923 100644 --- a/telethon/telegram_client.py +++ b/telethon/telegram_client.py @@ -723,16 +723,22 @@ class TelegramClient(TelegramBareClient): def download_file(self, input_location, - file_path, + file, part_size_kb=None, file_size=None, progress_callback=None, on_dc=None): + """Downloads the given InputFileLocation to file (a stream or str). + + If 'progress_callback' is not None, it should be a function that + takes two parameters, (bytes_downloaded, total_bytes). Note that + 'total_bytes' simply equals 'file_size', and may be None. + """ if on_dc is None: try: super(TelegramClient, self).download_file( input_location, - file_path, + file, part_size_kb=part_size_kb, file_size=file_size, progress_callback=progress_callback @@ -744,7 +750,7 @@ class TelegramClient(TelegramBareClient): client = self._get_exported_client(on_dc) client.download_file( input_location, - file_path, + file, part_size_kb=part_size_kb, file_size=file_size, progress_callback=progress_callback