Spaces:
Paused
Paused
| import traceback | |
| import math | |
| from aiohttp import web | |
| import config | |
| from pyrogram.file_id import FileId | |
| from aiohttp.http_exceptions import BadStatusLine | |
| from YukkiMusic import app, userbot | |
| from YukkiMusic.core.bot import YukkiBot | |
| from YukkiMusic.core.userbot import multi_clients, req_client | |
| from YukkiMusic.platforms.custom_dl import ByteStreamer | |
| class InvalidHash(Exception): | |
| message = "Invalid hash" | |
| class FIleNotFound(Exception): | |
| message = "File not found" | |
| class_cache={} | |
| async def media_streamer(request: web.Request, db_id: str): | |
| range_header = request.headers.get("Range", 0) | |
| #index = min(work_loads, key=work_loads.get) | |
| #faster_client = multi_clients[index] | |
| client=app | |
| #client = await req_client() | |
| #get_me = await app.get_me() | |
| #print(db_id,int(config.LOG_GROUP_ID),get_me) | |
| msg = await client.get_messages(int(config.LOG_GROUP_ID),int(db_id)) | |
| #print(msg) | |
| #tg_connect = ByteStreamer(client['client']) | |
| tg_connect = ByteStreamer(client) | |
| #class_cache[client['client']] = tg_connect | |
| #logging.debug("before calling get_file_properties") | |
| file_info = get_file_info(msg) | |
| #file_i = file_info['file']['file_id'] | |
| file_id = FileId.decode(file_info['file']['file_id']) | |
| #print(file_id) | |
| #logging.debug("after calling get_file_properties") | |
| file_size = file_info['file']['file_size'] | |
| if range_header: | |
| from_bytes, until_bytes = range_header.replace("bytes=", "").split("-") | |
| from_bytes = int(from_bytes) | |
| until_bytes = int(until_bytes) if until_bytes else file_size - 1 | |
| else: | |
| from_bytes = request.http_range.start or 0 | |
| until_bytes = (request.http_range.stop or file_size) - 1 | |
| if (until_bytes > file_size) or (from_bytes < 0) or (until_bytes | |
| < from_bytes): | |
| return web.Response( | |
| status=416, | |
| body="416: Range not satisfiable", | |
| headers={"Content-Range": f"bytes */{file_size}"}, | |
| ) | |
| chunk_size = 512 * 1024 | |
| until_bytes = min(until_bytes, file_size - 1) | |
| offset = from_bytes - (from_bytes % chunk_size) | |
| first_part_cut = from_bytes - offset | |
| last_part_cut = until_bytes % chunk_size + 1 | |
| req_length = until_bytes - from_bytes + 1 | |
| part_count = math.ceil(until_bytes / chunk_size) - math.floor( | |
| offset / chunk_size) | |
| body = tg_connect.yield_file(file_id, client, offset, first_part_cut, | |
| last_part_cut, part_count, chunk_size) | |
| mime_type = file_info['file']['mime_type'] | |
| file_name = get_name(msg) | |
| disposition = "attachment" | |
| # if "video/" in mime_type or "audio/" in mime_type: | |
| # disposition = "inline" | |
| return web.Response( | |
| status=206 if range_header else 200, | |
| body=body, | |
| headers={ | |
| "Content-Type": f"{mime_type}", | |
| "Content-Range": f"bytes {from_bytes}-{until_bytes}/{file_size}", | |
| "Content-Length": str(req_length), | |
| "Content-Disposition": f'{disposition}; filename="{file_name}"', | |
| "Accept-Ranges": "bytes", | |
| }, | |
| ) | |
| async def stream_handler(request: web.Request): | |
| try: | |
| path = request.match_info["path"] | |
| return await media_streamer(request, path) | |
| except InvalidHash as e: | |
| raise web.HTTPForbidden(text=e.message) | |
| except FIleNotFound as e: | |
| raise web.HTTPNotFound(text=e.message) | |
| except (AttributeError, BadStatusLine, ConnectionResetError): | |
| pass | |
| except Exception as e: | |
| traceback.print_exc() | |
| #logging.critical(e.with_traceback(None)) | |
| #logging.debug(traceback.format_exc()) | |
| raise web.HTTPInternalServerError(text=str(e)) | |
| TGFILEAPI = web.Application() | |
| TGFILEAPI.router.add_get('/{path}', stream_handler) | |