2020-08-10 09:27:52 +02:00
|
|
|
import math
|
|
|
|
import logging
|
|
|
|
import asyncio
|
|
|
|
|
2020-09-01 09:29:32 +02:00
|
|
|
from telethon import TelegramClient, utils
|
2020-08-10 09:27:52 +02:00
|
|
|
from telethon.sessions import StringSession
|
|
|
|
|
|
|
|
class Client(TelegramClient):
|
|
|
|
|
|
|
|
def __init__(self, session_string, *args, **kwargs):
|
|
|
|
super().__init__(StringSession(session_string), *args, **kwargs)
|
|
|
|
self.log = logging.getLogger(__name__)
|
2020-12-12 15:16:44 +01:00
|
|
|
|
2020-08-10 09:27:52 +02:00
|
|
|
|
|
|
|
async def download(self, file, file_size, offset, limit):
|
2020-09-01 09:29:32 +02:00
|
|
|
part_size_kb = utils.get_appropriated_part_size(file_size)
|
|
|
|
part_size = int(part_size_kb * 1024)
|
2020-08-10 09:27:52 +02:00
|
|
|
first_part_cut = offset % part_size
|
|
|
|
first_part = math.floor(offset / part_size)
|
|
|
|
last_part_cut = part_size - (limit % part_size)
|
|
|
|
last_part = math.ceil(limit / part_size)
|
|
|
|
part_count = math.ceil(file_size / part_size)
|
|
|
|
part = first_part
|
|
|
|
try:
|
2020-09-01 09:29:32 +02:00
|
|
|
async for chunk in self.iter_download(file, offset=first_part * part_size, request_size=part_size):
|
2020-08-10 09:27:52 +02:00
|
|
|
if part == first_part:
|
|
|
|
yield chunk[first_part_cut:]
|
2020-12-12 15:16:44 +01:00
|
|
|
elif part == last_part-1:
|
2020-08-10 09:27:52 +02:00
|
|
|
yield chunk[:last_part_cut]
|
|
|
|
else:
|
|
|
|
yield chunk
|
2020-08-11 08:29:09 +02:00
|
|
|
self.log.debug(f"Part {part}/{last_part} (total {part_count}) served!")
|
2020-08-10 09:27:52 +02:00
|
|
|
part += 1
|
2020-08-11 08:29:09 +02:00
|
|
|
self.log.debug("serving finished")
|
2020-08-10 09:27:52 +02:00
|
|
|
except (GeneratorExit, StopAsyncIteration, asyncio.CancelledError):
|
2020-08-11 08:29:09 +02:00
|
|
|
self.log.debug("file serve interrupted")
|
2020-08-10 09:27:52 +02:00
|
|
|
raise
|
|
|
|
except Exception:
|
2020-08-11 08:29:09 +02:00
|
|
|
self.log.debug("file serve errored", exc_info=True)
|