mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-22 17:36:34 +03:00
Make sending files a lot more friendly with a simple .send_file()
This commit is contained in:
parent
81ccd21cdb
commit
4234efcc86
|
@ -315,6 +315,10 @@ class TelegramBareClient:
|
|||
"""Uploads the specified file_path and returns a handle (an instance
|
||||
of InputFile or InputFileBig, as required) which can be later used.
|
||||
|
||||
Uploading a file will simply return a "handle" to the file stored
|
||||
remotely in the Telegram servers, which can be later used on. This
|
||||
will NOT upload the file to your own chat.
|
||||
|
||||
If 'progress_callback' is not None, it should be a function that
|
||||
takes two parameters, (bytes_uploaded, total_bytes).
|
||||
|
||||
|
@ -322,6 +326,7 @@ class TelegramBareClient:
|
|||
part_size_kb = get_appropriated_part_size(file_size)
|
||||
file_name = path.basename(file_path)
|
||||
"""
|
||||
# TODO Support both streams and bytes instead just "file_path"
|
||||
file_size = path.getsize(file_path)
|
||||
if not part_size_kb:
|
||||
part_size_kb = get_appropriated_part_size(file_size)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import errno
|
||||
import os
|
||||
from datetime import timedelta
|
||||
from mimetypes import guess_type
|
||||
from threading import Event, RLock, Thread
|
||||
|
@ -126,6 +126,9 @@ class TelegramClient(TelegramBareClient):
|
|||
self._updates_thread = None
|
||||
self._phone_code_hashes = {}
|
||||
|
||||
# Uploaded files cache so subsequent calls are instant
|
||||
self._upload_cache = {}
|
||||
|
||||
# endregion
|
||||
|
||||
# region Connecting
|
||||
|
@ -475,53 +478,86 @@ class TelegramClient(TelegramBareClient):
|
|||
|
||||
# region Uploading files
|
||||
|
||||
def send_photo_file(self, input_file, entity, caption=''):
|
||||
"""Sends a previously uploaded input_file
|
||||
(which should be a photo) to the given entity (or input peer)"""
|
||||
self.send_media_file(
|
||||
InputMediaUploadedPhoto(input_file, caption), entity)
|
||||
def send_file(self, entity, file, caption='',
|
||||
force_document=False, callback=None):
|
||||
"""Sends a file to the specified entity.
|
||||
The file may either be a path, a byte array, or a stream.
|
||||
|
||||
def send_document_file(self, input_file, entity, caption=''):
|
||||
"""Sends a previously uploaded input_file
|
||||
(which should be a document) to the given entity.
|
||||
An optional caption can also be specified for said file.
|
||||
|
||||
If "force_document" is False, the file will be sent as a photo
|
||||
if it's recognised to have a common image format (e.g. .png, .jpg).
|
||||
|
||||
Otherwise, the file will always be sent as an uncompressed document.
|
||||
|
||||
Subsequent calls with the very same file will result in
|
||||
immediate uploads, unless .clear_file_cache() is called.
|
||||
|
||||
If "progress_callback" is not None, it should be a function that
|
||||
takes two parameters, (bytes_uploaded, total_bytes).
|
||||
|
||||
The entity may be a phone or an username at the expense of
|
||||
some performance loss.
|
||||
"""
|
||||
as_photo = False
|
||||
if isinstance(file, str):
|
||||
lowercase_file = file.lower()
|
||||
as_photo = any(
|
||||
lowercase_file.endswith(ext)
|
||||
for ext in ('.png', '.jpg', '.gif', '.jpeg')
|
||||
)
|
||||
|
||||
# Determine mime-type and attributes
|
||||
# Take the first element by using [0] since it returns a tuple
|
||||
mime_type = guess_type(input_file.name)[0]
|
||||
attributes = [
|
||||
DocumentAttributeFilename(input_file.name)
|
||||
# TODO If the input file is an audio, find out:
|
||||
# Performer and song title and add DocumentAttributeAudio
|
||||
]
|
||||
# Ensure we have a mime type, any; but it cannot be None
|
||||
# 'The "octet-stream" subtype is used to indicate that a body
|
||||
# contains arbitrary binary data.'
|
||||
if not mime_type:
|
||||
mime_type = 'application/octet-stream'
|
||||
self.send_media_file(
|
||||
InputMediaUploadedDocument(
|
||||
file=input_file,
|
||||
file_hash = hash(file)
|
||||
if file_hash in self._upload_cache:
|
||||
file_handle = self._upload_cache[file_hash]
|
||||
else:
|
||||
file_handle = self.upload_file(file, progress_callback=callback)
|
||||
self._upload_cache[file_hash] = file_handle
|
||||
|
||||
if as_photo and not force_document:
|
||||
media = InputMediaUploadedPhoto(file_handle, caption)
|
||||
else:
|
||||
mime_type = None
|
||||
if isinstance(file, str):
|
||||
# Determine mime-type and attributes
|
||||
# Take the first element by using [0] since it returns a tuple
|
||||
mime_type = guess_type(file)[0]
|
||||
attributes = [
|
||||
DocumentAttributeFilename(os.path.abspath(file))
|
||||
# TODO If the input file is an audio, find out:
|
||||
# Performer and song title and add DocumentAttributeAudio
|
||||
]
|
||||
else:
|
||||
attributes = [DocumentAttributeFilename('unnamed')]
|
||||
|
||||
# Ensure we have a mime type, any; but it cannot be None
|
||||
# 'The "octet-stream" subtype is used to indicate that a body
|
||||
# contains arbitrary binary data.'
|
||||
if not mime_type:
|
||||
mime_type = 'application/octet-stream'
|
||||
|
||||
media = InputMediaUploadedDocument(
|
||||
file=file_handle,
|
||||
mime_type=mime_type,
|
||||
attributes=attributes,
|
||||
caption=caption),
|
||||
entity)
|
||||
caption=caption
|
||||
)
|
||||
|
||||
def send_media_file(self, input_media, entity):
|
||||
"""Sends any input_media (contact, document, photo...)
|
||||
to the given entity.
|
||||
|
||||
The entity may be a phone or an username at the expense of
|
||||
some performance loss.
|
||||
"""
|
||||
# Once the media type is properly specified and the file uploaded,
|
||||
# send the media message to the desired entity.
|
||||
self(SendMediaRequest(
|
||||
peer=self._get_entity(entity),
|
||||
media=input_media
|
||||
media=media
|
||||
))
|
||||
|
||||
def clear_file_cache(self):
|
||||
"""Calls to .send_file() will cache the remote location of the
|
||||
uploaded files so that subsequent files can be immediate, so
|
||||
uploading the same file path will result in using the cached
|
||||
version. To avoid this a call to this method should be made.
|
||||
"""
|
||||
self._upload_cache.clear()
|
||||
|
||||
# endregion
|
||||
|
||||
# region Downloading media requests
|
||||
|
@ -723,6 +759,9 @@ class TelegramClient(TelegramBareClient):
|
|||
If the entity is neither, and it's not a TLObject, an
|
||||
error will be raised.
|
||||
"""
|
||||
# TODO Maybe cache both the contacts and the entities.
|
||||
# If an user cannot be found, force a cache update through
|
||||
# a public method (since users may change their username)
|
||||
if isinstance(entity, TLObject):
|
||||
return entity
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user