Support arbitrary file objects for .download_file() and update README

This commit is contained in:
Lonami Exo 2017-06-09 11:12:56 +02:00
parent 40f4c2533a
commit 40616ba704
3 changed files with 28 additions and 17 deletions

View File

@ -138,6 +138,10 @@ disconnects the client.
Another common one is the ``RPCError``, which usually has descriptive information on what went wrong. 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. 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 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 The ``proxy=`` argument should be a tuple, a list or a dict, consisting of parameters described
`here <https://github.com/Anorov/PySocks#usage-1>`_. `here <https://github.com/Anorov/PySocks#usage-1>`_.
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.

View File

@ -283,11 +283,11 @@ class TelegramBareClient:
def download_file(self, def download_file(self,
input_location, input_location,
file_path, file,
part_size_kb=None, part_size_kb=None,
file_size=None, file_size=None,
progress_callback=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 If 'progress_callback' is not None, it should be a function that
takes two parameters, (bytes_downloaded, total_bytes). Note that takes two parameters, (bytes_downloaded, total_bytes). Note that
@ -303,11 +303,15 @@ class TelegramBareClient:
if part_size % 1024 != 0: if part_size % 1024 != 0:
raise ValueError('The part size must be evenly divisible by 1024.') raise ValueError('The part size must be evenly divisible by 1024.')
# Ensure that we'll be able to download the media if isinstance(file, str):
utils.ensure_parent_dir_exists(file_path) # 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 try:
with open(file_path, 'wb') as file: offset_index = 0
while True: while True:
offset = offset_index * part_size offset = offset_index * part_size
result = self.invoke( result = self.invoke(
@ -319,8 +323,11 @@ class TelegramBareClient:
if not result.bytes: if not result.bytes:
return result.type # Return some extra information return result.type # Return some extra information
file.write(result.bytes) f.write(result.bytes)
if progress_callback: if progress_callback:
progress_callback(file.tell(), file_size) progress_callback(f.tell(), file_size)
finally:
if isinstance(file, str):
f.close()
# endregion # endregion

View File

@ -723,16 +723,22 @@ class TelegramClient(TelegramBareClient):
def download_file(self, def download_file(self,
input_location, input_location,
file_path, file,
part_size_kb=None, part_size_kb=None,
file_size=None, file_size=None,
progress_callback=None, progress_callback=None,
on_dc=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: if on_dc is None:
try: try:
super(TelegramClient, self).download_file( super(TelegramClient, self).download_file(
input_location, input_location,
file_path, file,
part_size_kb=part_size_kb, part_size_kb=part_size_kb,
file_size=file_size, file_size=file_size,
progress_callback=progress_callback progress_callback=progress_callback
@ -744,7 +750,7 @@ class TelegramClient(TelegramBareClient):
client = self._get_exported_client(on_dc) client = self._get_exported_client(on_dc)
client.download_file( client.download_file(
input_location, input_location,
file_path, file,
part_size_kb=part_size_kb, part_size_kb=part_size_kb,
file_size=file_size, file_size=file_size,
progress_callback=progress_callback progress_callback=progress_callback