added loader, added video format check, fix video download
This commit is contained in:
parent
acc48c7bc8
commit
e89855d91a
@ -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")
|
||||||
|
@ -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")
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user