git
This commit is contained in:
parent
7167ddceb1
commit
da8439daea
50
app.py
Normal file
50
app.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from fastapi import FastAPI, Request, Form
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Oki.cx is a API for Converting Youtube Videos to MP4 & MP3. ▶️
|
||||||
|
|
||||||
|
## Requests
|
||||||
|
|
||||||
|
You can Requst a **MP4** File.
|
||||||
|
You can Requst a **MP3** File.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from starlette.templating import Jinja2Templates
|
||||||
|
|
||||||
|
import models
|
||||||
|
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title="Oki.cx - YouTube Converter",
|
||||||
|
description=description,
|
||||||
|
version="0.1",
|
||||||
|
terms_of_service="http://oki.cx/youtube-converter/tos",
|
||||||
|
contact={
|
||||||
|
"name": "oki.cx",
|
||||||
|
"email": "cody@oki.cx",
|
||||||
|
},
|
||||||
|
license_info={
|
||||||
|
"name": "MIT License",
|
||||||
|
"url": "https://gitlab.oki.cx/mrpvtdagger/oki.cx-youtube-converter/-/raw/main/LICENSE",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def home(request: Request):
|
||||||
|
return templates.TemplateResponse("base.html",{"request": request, "is_hidden": "is-hidden"})
|
||||||
|
|
||||||
|
@app.post("/")
|
||||||
|
def download(request: Request, link: str = Form(...), media_format: str = Form(...)):
|
||||||
|
response = models.convert_video(link, media_format)
|
||||||
|
return templates.TemplateResponse("base.html",{"request": request, "is_hidden": "", "url": response["url"], "title": response["title"], "filename": response["filename"], "thumbnail": response["thumbnail"]})
|
||||||
|
|
||||||
|
@app.post("/json")
|
||||||
|
def download(request: Request, link: str = Form(...), media_format: str = Form(...)):
|
||||||
|
response = models.convert_video(link, media_format)
|
||||||
|
return {"title": response["title"], "url": response["url"], "title": response["title"], "filename": response["filename"], "thumbnail": response["thumbnail"]}
|
||||||
|
|
||||||
|
@app.get("/delete/{filename}")
|
||||||
|
def delete(request: Request, filename: str):
|
||||||
|
models.delete_file(filename)
|
||||||
|
return templates.TemplateResponse("base.html",{"request": request, "is_hidden": "is-hidden"})
|
32
models.py
Normal file
32
models.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from pytube import YouTube
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import os
|
||||||
|
|
||||||
|
def convert_video(link, media_format):
|
||||||
|
def randmname(size=6, chars=string.ascii_lowercase + string.digits):
|
||||||
|
return ''.join(random.choice(chars) for _ in range(size))
|
||||||
|
rand_filename = f"{randmname(25)}.{media_format.lower()}"
|
||||||
|
|
||||||
|
stream_filter = ""
|
||||||
|
if media_format == "mp4":
|
||||||
|
stream_filter = "progressive=True, file_extension=mp4"
|
||||||
|
elif media_format == "mp3":
|
||||||
|
stream_filter = "only_audio=True"
|
||||||
|
|
||||||
|
|
||||||
|
yt = YouTube(link)
|
||||||
|
yt.streams.filter(stream_filter).order_by('resolution').desc().first().download(filename=rand_filename, output_path="files/ytdl")
|
||||||
|
|
||||||
|
cdn_url = {
|
||||||
|
"url": f"https://cdn.oki.cx/files/{rand_filename}",
|
||||||
|
"title": yt.title,
|
||||||
|
"thumbnail": f"{yt.thumbnail_url}",
|
||||||
|
"filename": rand_filename
|
||||||
|
}
|
||||||
|
|
||||||
|
return cdn_url
|
||||||
|
|
||||||
|
def delete_file(filename):
|
||||||
|
os.remove(f"files/ytdl/{filename}")
|
||||||
|
|
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
71
templates/base.html
Normal file
71
templates/base.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Oki.cx - Youtube Converter</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.7.0" integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo" crossorigin="anonymous" defer></script>
|
||||||
|
<script src="//code.iconify.design/1/1.0.6/iconify.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="padding p-4 has-text-centered">
|
||||||
|
<p class="title is-1">Oki.cx Youtube Converter</p>
|
||||||
|
<p class="subtitle is-4">Free and <a href="https://gitlab.oki.cx/mrpvtdagger/oki.cx-youtube-converter">Open Source <span class="iconify" data-icon="mdi-gitlab"></span> </a></br> With a <a href="/docs">API</a></br><strong>Personal use only!</strong></p>
|
||||||
|
</div>
|
||||||
|
<section class="section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-half">
|
||||||
|
<form id="form" action="/" method="post">
|
||||||
|
<div class="field has-addons has-addons-center pb pb-4">
|
||||||
|
<p class="control">
|
||||||
|
<span class="select">
|
||||||
|
<select name="media_format">
|
||||||
|
<option>MP4</option>
|
||||||
|
<option>MP3</option>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p class="control is-expanded">
|
||||||
|
<input name="link" class="input" type="text" placeholder="URL to Youtube Video">
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<a id="convert" class="button is-link" onclick="document.getElementById('convert').classList.add('is-loading');document.getElementById('form').submit();">Convert</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-two-fifths">
|
||||||
|
<div class="card {{is_hidden}}">
|
||||||
|
<div class="card-image">
|
||||||
|
<figure class="image is-4by3">
|
||||||
|
<img src="{{thumbnail}}">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="content">
|
||||||
|
<div class="is-size-4">{{title}}</div>
|
||||||
|
<br>
|
||||||
|
<div class="is-size-7">{{filename}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a href="{{url}}" class="card-footer-item" target="_blank" download>Save</a>
|
||||||
|
<a href="delete/{{filename}}" class="card-footer-item has-text-danger">Delete from Server</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="padding p-4 subtitle is-7 has-text-centered">By clicking <strong>"Convert"</strong> you agree to using this for personal use only</a>.</p>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
templates/htmx.js
Normal file
1
templates/htmx.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user