Spaces:
Configuration error
Configuration error
File size: 3,796 Bytes
00c68f3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
import math, asyncio, subprocess
from telethon import TelegramClient
from aiohttp import web
import logging
logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
class Download:
client: TelegramClient
route: str
offset: int
handler: None
file: None
limit: int
file_size: float
def __init__(self, handler):
self.handler = handler
self.file = handler.message.media
self.file_size = handler.message.file.size
self.limit = handler.sanity.limit
self.offset = handler.sanity.offset
self.client = handler.client
self.mime_type = handler.message.file.mime_type
async def download(self):
part_size = int(512 * 1024) * 2
first_part_cut = self.offset % part_size
first_part = math.floor(self.offset / part_size)
last_part_cut = part_size - (self.limit % part_size)
last_part = math.ceil(self.limit / part_size)
part_count = math.ceil(self.file_size / part_size)
part = first_part
try:
async for chunk in self.client.iter_download(
self.file, offset=first_part * part_size, request_size=part_size
):
if part == first_part:
yield chunk[first_part_cut:]
elif part == last_part:
yield chunk[:last_part_cut]
else:
yield chunk
logging.debug(f"Part {part}/{last_part} (total {part_count}) served!")
part += 1
logging.debug("serving finished")
except (GeneratorExit, StopAsyncIteration, asyncio.CancelledError):
logging.debug("file serve interrupted")
raise
except Exception as e:
print(e)
logging.debug("file serve errored", exc_info=True)
async def handle_request(self):
headers = {
"content-type": self.mime_type,
"content-range": f"bytes {self.offset}-{self.limit-1}/{self.file_size}",
"content-length": str(self.limit - self.offset),
"accept-ranges": "bytes",
"content-transfer-encoding": "Binary",
"content-disposition": f'{self.handler.route}; filename="{self.handler.message.file.name}"',
}
logging.info(
f"Serving file in {self.handler.message.file.name}) ; Range: {self.offset} - {self.limit}"
)
if self.handler.head:
body = None
else:
body = self.download()
# if body:
# ffmpeg = "ffmpeg"
# cmd = [
# ffmpeg,
# "ffmpeg",
# "-i",
# "pipe:0",
# "-c",
# "copy",
# "-re",
# "pipe:1",
# ]
# ffmpeg_cmd = subprocess.Popen(
# cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False
# )
# body = await body.__anext__()
# ffmpeg_cmd.stdin.write(body.tobytes())
# ffmpeg_cmd.stdin.close()
# body = b""
# while True:
# print(body)
# output = ffmpeg_cmd.stdout.read()
# if len(output) > 0:
# body += output
# ffmpeg_cmd.stdout.close()
# else:
# error_msg = ffmpeg_cmd.poll()
# if error_msg is not None:
# break
return web.Response(
body=body, headers=headers, status=206 if self.offset else 200
)
|