2023-09-20 14:43:59 +03:00
|
|
|
import asyncio
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
from ast import literal_eval
|
|
|
|
|
|
|
|
import uvicorn
|
|
|
|
from aio_pika import connect, Message, DeliveryMode
|
|
|
|
from fastapi import FastAPI, Request, Form, HTTPException
|
|
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
|
|
from starlette.responses import JSONResponse, FileResponse, StreamingResponse
|
|
|
|
from starlette.templating import Jinja2Templates
|
|
|
|
|
|
|
|
from src.core.redis_client import RedisClient
|
|
|
|
|
|
|
|
app = FastAPI(
|
|
|
|
title="video_downloader", openapi_url=f"/api/v1/openapi.json"
|
|
|
|
)
|
|
|
|
|
|
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
|
|
app.add_middleware(
|
|
|
|
CORSMiddleware,
|
|
|
|
allow_origins=["*"],
|
|
|
|
allow_credentials=True,
|
|
|
|
allow_methods=["*"],
|
|
|
|
allow_headers=["*"],
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/")
|
|
|
|
async def index(request: Request):
|
|
|
|
return templates.TemplateResponse("index.html", {"request": request})
|
|
|
|
|
|
|
|
|
|
|
|
@app.post('/submit/')
|
|
|
|
async def get_url_for_download_video(request: Request, link: str = Form(...)):
|
|
|
|
connection = await connect("amqp://guest:guest@localhost/")
|
|
|
|
|
|
|
|
async with connection:
|
|
|
|
# Creating a channel
|
|
|
|
channel = await connection.channel()
|
|
|
|
body = [
|
|
|
|
|
|
|
|
{
|
|
|
|
"link": link,
|
|
|
|
"parser": "base",
|
|
|
|
"format": "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
|
|
|
|
"merge_output_format": "mp4",
|
|
|
|
"outtmpl": f"downloads/%(extractor_key)s/%(id)s_%(width)sp.%(ext)s",
|
|
|
|
}, ]
|
|
|
|
# Sending the message
|
|
|
|
for link in body:
|
|
|
|
if "mail" in link["link"]:
|
|
|
|
link["parser"] = "MyMailRu"
|
|
|
|
elif "yappy" in link["link"]:
|
|
|
|
link["parser"] = "Yappy"
|
|
|
|
message = Message(
|
|
|
|
json.dumps(link, indent=4).encode('utf-8'), delivery_mode=DeliveryMode.PERSISTENT,
|
|
|
|
)
|
|
|
|
await channel.default_exchange.publish(
|
|
|
|
message,
|
|
|
|
routing_key='hello',
|
|
|
|
)
|
|
|
|
|
|
|
|
print(f" [x] Sent '{link}'")
|
|
|
|
red = RedisClient()
|
|
|
|
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
mes = await red.get_task_done_queue()
|
|
|
|
task = literal_eval(list(mes)[0].decode('utf-8'))
|
|
|
|
if task["link"] == link["link"]:
|
|
|
|
await red.del_task_from_task_done_queue(task)
|
|
|
|
break
|
|
|
|
await asyncio.sleep(5)
|
|
|
|
except (AttributeError, IndexError):
|
|
|
|
await asyncio.sleep(5)
|
|
|
|
continue
|
|
|
|
link_to_download_video = str(request.base_url) + "get/?file_path=" + task["result"]
|
|
|
|
|
|
|
|
return JSONResponse({"result": link_to_download_video})
|
|
|
|
|
|
|
|
|
|
|
|
@app.get('/get/', response_class=FileResponse, status_code=200)
|
|
|
|
async def download_video(file_path):
|
|
|
|
base = os.path.dirname(os.path.dirname(os.path.abspath(file_path)))
|
|
|
|
base_download_dir = os.path.join(base, os.pardir, os.pardir, "downloads")
|
|
|
|
|
|
|
|
def iterfile():
|
|
|
|
with open(base_download_dir + f'/{file_path}', mode="rb") as file_like:
|
|
|
|
yield from file_like
|
|
|
|
|
|
|
|
return StreamingResponse(iterfile(), media_type="video/mp4")
|
|
|
|
|
|
|
|
|
2023-09-20 15:00:41 +03:00
|
|
|
uvicorn.run("src.web.main:app", host="localhost", log_level="info")
|