yt-dlp-aas/handler.py
2024-11-03 14:02:10 -08:00

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)