77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
import os
|
|
import json
|
|
from http import HTTPStatus
|
|
import http.server
|
|
|
|
from yt_dlp import YoutubeDL
|
|
|
|
# https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#extract-audio
|
|
def download(url):
|
|
ydl_opts = {
|
|
'format': 'm4a/bestaudio/best',
|
|
'paths': {
|
|
'home': os.environ.get('DOWNLOAD_DIR', '.')
|
|
},
|
|
'postprocessors': [{
|
|
'key': 'FFmpegExtractAudio',
|
|
'preferredcodec': 'm4a'
|
|
}]
|
|
}
|
|
with YoutubeDL(ydl_opts) as ydl:
|
|
ydl.download(url)
|
|
|
|
class Handler(http.server.SimpleHTTPRequestHandler):
|
|
def __init__(self, pool, *args, **kwargs):
|
|
self.pool = pool
|
|
# https://stackoverflow.com/a/52046062/1040915
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def do_POST(self):
|
|
try:
|
|
content_length = self.headers['Content-Length']
|
|
if not content_length:
|
|
self.send_response(HTTPStatus.INTERNAL_SERVER_ERROR)
|
|
content = "Looks like you forgot to send a body".encode('utf-8')
|
|
self.send_header("Content-type", 'application/json')
|
|
self.send_header('Content-Length', len(content))
|
|
self.end_headers()
|
|
self.wfile.write(content)
|
|
return
|
|
|
|
data_string = self.rfile.read(int(content_length))
|
|
body = json.loads(data_string) # TODO - better error-handling here
|
|
url = body.get('url')
|
|
if not url:
|
|
self.send_response(HTTPStatus.INTERNAL_SERVER_ERROR)
|
|
content = "Looks like you forgot to send a `url` parameter".encode('utf-8')
|
|
self.send_header("Content-type", 'application/json')
|
|
self.send_header('Content-Length', len(content))
|
|
self.end_headers()
|
|
self.wfile.write(content)
|
|
return
|
|
|
|
self.send_response(HTTPStatus.ACCEPTED)
|
|
content = f'Accepted download request for {url}\n'.encode('utf-8')
|
|
self.send_header("Content-type", 'application/json')
|
|
self.send_header('Content-Length', len(content))
|
|
self.end_headers()
|
|
# TODO - check for success of kicking-off the thread
|
|
self.pool.apply_async(download, (url,))
|
|
self.wfile.write(content)
|
|
except Exception as e:
|
|
self.send_response(HTTPStatus.INTERNAL_SERVER_ERROR)
|
|
content = str(e).encode('utf-8')
|
|
print(e) # TODO - better logging!
|
|
self.send_header("Content-type", 'application/json')
|
|
self.send_header('Content-Length', len(content))
|
|
self.end_headers()
|
|
self.wfile.write(content)
|
|
|
|
def do_GET(self):
|
|
self.send_response(HTTPStatus.INTERNAL_SERVER_ERROR)
|
|
content = 'ERROR: Only HEAD requests are permitted\n'.encode('utf-8')
|
|
self.send_header("Content-type", 'application/json')
|
|
self.send_header('Content-Length', len(content))
|
|
self.end_headers()
|
|
self.wfile.write(content)
|