added loader, added video format check, fix video download

This commit is contained in:
Dantenerosas 2023-08-15 01:38:45 +03:00 committed by nikili0n
parent acc48c7bc8
commit e89855d91a
4 changed files with 67 additions and 18 deletions

View File

@ -2,6 +2,7 @@ import os
from fastapi import APIRouter, Form, HTTPException from fastapi import APIRouter, Form, HTTPException
from starlette.requests import Request from starlette.requests import Request
from fastapi.responses import JSONResponse
from starlette.responses import HTMLResponse, FileResponse from starlette.responses import HTMLResponse, FileResponse
from starlette.templating import Jinja2Templates from starlette.templating import Jinja2Templates
@ -25,25 +26,22 @@ async def get_url_for_download_video(request: Request, link: str = Form(...)):
ydl_opts = { ydl_opts = {
"forceurl": True, "forceurl": True,
'outtmpl': f'downloads/%(extractor_key)s/{file_name}.%(ext)s' 'outtmpl': f'downloads/%(extractor_key)s/{file_name}.%(ext)s'
# "username": "garick.badalov@yandex.ru",
# "password": "garik876.",
} }
downloader = VideoDownloader(link=link, ydl_opts=ydl_opts) downloader = VideoDownloader(link=link, ydl_opts=ydl_opts)
try: try:
result = downloader.download() result = downloader.download()
file_path = str(request.base_url) + f"{file_name}.mp4" link_to_download_video = str(request.base_url) + f"{file_name}.{result['formats'][-1]['ext']}"
except SiteNotImplementedException as ex: except SiteNotImplementedException as ex:
raise HTTPException( raise HTTPException(
status_code=400, status_code=400,
detail=ex.message detail=ex.message
) )
return templates.TemplateResponse("index.html", {"request": request, "result": file_path}) return JSONResponse({"result": link_to_download_video})
@main_router.get('/{file_path}', response_class=FileResponse) @main_router.get('/{file_path}', response_class=FileResponse)
async def download_video(request: Request, file_path): async def download_video(file_path):
base = os.path.dirname(os.path.dirname(os.path.abspath(file_path))) base = os.path.dirname(os.path.dirname(os.path.abspath(file_path)))
BASE_DOWNLOAD_DIR = os.path.join(base, "src", "downloads") base_download_dir = os.path.join(base, "src", "downloads")
BASE_YOUTUBE_DIR = os.path.join(BASE_DOWNLOAD_DIR, "Youtube") youtube_dir = os.path.join(base_download_dir, "Youtube")
return BASE_YOUTUBE_DIR + f'/{file_path}' return FileResponse(youtube_dir + f'/{file_path}', media_type="multipart/form-data")

View File

@ -12,7 +12,7 @@ from src.exceptions.download_exceptions import SiteNotImplementedException
class VideoDownloader: class VideoDownloader:
SUPPORTING_WEBSITES = [ SUPPORTING_WEBSITES = [
"ok.ru", "vk.com", "www.youtube.com" "ok.ru", "vk.com", "www.youtube.com",
] ]
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DOWNLOAD_DIR = os.path.join(BASE_DIR, "downloads") BASE_DOWNLOAD_DIR = os.path.join(BASE_DIR, "downloads")

View File

@ -1,9 +1,8 @@
import uvicorn import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from src.api.api_v1.endpoints.main import main_router from api.api_v1.endpoints.main import main_router
app = FastAPI( app = FastAPI(
title="PythonProject", openapi_url=f"/api/v1/openapi.json" title="PythonProject", openapi_url=f"/api/v1/openapi.json"

View File

@ -5,10 +5,9 @@
<title>Video Downloading</title> <title>Video Downloading</title>
</head> </head>
<style> <style>
.custom-btn { .custom-btn {
width: 130px; width: 145px;
height: 40px; height: 60px;
color: #fff; color: #fff;
border-radius: 5px; border-radius: 5px;
padding: 10px 25px; padding: 10px 25px;
@ -48,16 +47,69 @@
font-size: 1.5em; /* Размер шрифта */ font-size: 1.5em; /* Размер шрифта */
word-wrap: break-word; /* Перенос слов */ word-wrap: break-word; /* Перенос слов */
} }
@keyframes spinner-border {
100% {
transform: rotate(360deg);
}
}
.submit-spinner {
display: inline-block;
width: 1rem;
height: 1rem;
vertical-align: -0.125em;
border: 0.2em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: .75s linear infinite spinner-border;
animation: .75s linear infinite spinner-border;
}
.submit-spinner_hide {
display: none;
}
</style> </style>
<body> <body>
<form method="post" action="/submit"> <form method="post" action="/submit" id="download">
<input type="text" name="link"> <input type="text" name="link">
<button type="submit" class="custom-btn btn-1">Download</button> <button type="submit" class="custom-btn btn-1"><span class="submit-spinner submit-spinner_hide"></span> Download</button>
</form> </form>
<div class="col"> <div class="col">
<p> Ссылка для скачивания:</p> <p> Ссылка для скачивания:</p>
<br> <br>
<a href={{result}}>{{result}}</a> <a id="result" href=""></a>
<div class="loader">
<div class="loader_inner"></div>
</div>
</div> </div>
</body> </body>
<script>
function sendForm() {
const xhr = new XMLHttpRequest();
xhr.open('POST', document.forms.download.action);
xhr.responseType = 'json';
xhr.onload = () => {
document.forms.download.querySelector('[type="submit"]').disabled = false;
document.forms.download.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
if (xhr.status !== 200) {
return;
}
const response = xhr.response;
result.innerHTML = xhr.response.result;
result.href = xhr.response.result;
}
xhr.onerror = () => {
document.forms.download.querySelector('[type="submit"]').disabled = false;
document.forms.download.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
};
document.forms.download.querySelector('[type="submit"]').disabled = true;
document.forms.download.querySelector('.submit-spinner').classList.remove('submit-spinner_hide');
xhr.send(new FormData(document.forms.download));
}
// при отправке формы
document.forms.download.addEventListener('submit', (e) => {
e.preventDefault();
sendForm();
});
</script>
</html> </html>