| 13 | |
| 14 | |
| 15 | class ByteStreamer: |
| 16 | def __init__(self, client: Client): |
| 17 | """A custom class that holds the cache of a specific client and class functions. |
| 18 | attributes: |
| 19 | client: the client that the cache is for. |
| 20 | cached_file_ids: a dict of cached file IDs. |
| 21 | cached_file_properties: a dict of cached file properties. |
| 22 | |
| 23 | functions: |
| 24 | generate_file_properties: returns the properties for a media of a specific message contained in Tuple. |
| 25 | generate_media_session: returns the media session for the DC that contains the media file. |
| 26 | yield_file: yield a file from telegram servers for streaming. |
| 27 | |
| 28 | This is a modified version of the <https://github.com/eyaadh/megadlbot_oss/blob/master/mega/telegram/utils/custom_download.py> |
| 29 | Thanks to Eyaadh <https://github.com/eyaadh> |
| 30 | """ |
| 31 | self.clean_timer = 30 * 60 |
| 32 | self.client: Client = client |
| 33 | self.cached_file_ids: Dict[int, FileId] = {} |
| 34 | asyncio.create_task(self.clean_cache()) |
| 35 | |
| 36 | async def get_file_properties(self, id: int) -> FileId: |
| 37 | """ |
| 38 | Returns the properties of a media of a specific message in a FIleId class. |
| 39 | if the properties are cached, then it'll return the cached results. |
| 40 | or it'll generate the properties from the Message ID and cache them. |
| 41 | """ |
| 42 | if id not in self.cached_file_ids: |
| 43 | await self.generate_file_properties(id) |
| 44 | logging.debug(f"Cached file properties for message with ID {id}") |
| 45 | return self.cached_file_ids[id] |
| 46 | |
| 47 | async def generate_file_properties(self, id: int) -> FileId: |
| 48 | """ |
| 49 | Generates the properties of a media file on a specific message. |
| 50 | returns ths properties in a FIleId class. |
| 51 | """ |
| 52 | file_id = await get_file_ids(self.client, Var.BIN_CHANNEL, id) |
| 53 | logging.debug(f"Generated file ID and Unique ID for message with ID {id}") |
| 54 | if not file_id: |
| 55 | logging.debug(f"Message with ID {id} not found") |
| 56 | raise FIleNotFound |
| 57 | self.cached_file_ids[id] = file_id |
| 58 | logging.debug(f"Cached media message with ID {id}") |
| 59 | return self.cached_file_ids[id] |
| 60 | |
| 61 | async def generate_media_session(self, client: Client, file_id: FileId) -> Session: |
| 62 | """ |
| 63 | Generates the media session for the DC that contains the media file. |
| 64 | This is required for getting the bytes from Telegram servers. |
| 65 | """ |
| 66 | |
| 67 | media_session = client.media_sessions.get(file_id.dc_id, None) |
| 68 | |
| 69 | if media_session is None: |
| 70 | if file_id.dc_id != await client.storage.dc_id(): |
| 71 | media_session = Session( |
| 72 | client, |