This commit is contained in:
Dagger 2022-05-23 13:47:35 -04:00
parent 7167ddceb1
commit da8439daea
5 changed files with 154 additions and 0 deletions

50
app.py Normal file
View 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
View 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

Binary file not shown.

71
templates/base.html Normal file
View 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

File diff suppressed because one or more lines are too long