mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-31 16:07:44 +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