ONesVC_bot / YukkiMusic /server /routes_TGFileAPI.py
BinaryONe
Refresh Update
2f67506
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)