import asyncio import json import secrets import time import websockets import response import ydl_pool import ydl_wrap # TODO: config HOST = '127.0.0.1' PORT = 5678 def generate_key() -> str: return hex(time.time_ns()) + secrets.token_hex(2) async def handler(socket: websockets.WebSocketServerProtocol) -> None: ydls = ydl_pool.Downloaders() async for message in socket: try: data = json.loads(message) match data['action']: case 'list': # list tracks in album await socket.send(response.ok_playlist( await ydl_wrap.get_playlist_items( ydls.get_ydl(data['site']), data['url'], ) )) case 'download': # download by URL # TODO: send all yt-dlp's output to client await socket.send(response.ok_download( await ydl_wrap.download( ydls.get_ydl(data['site']), data['url'], data.get('items'), ) )) # TODO: cancellation case _: raise ValueError('invalid "action" field value') except websockets.ConnectionClosed: break except Exception as ex: if not socket.closed: await socket.send(response.error(ex)) ydls.cleanup() async def main() -> None: async with websockets.serve(handler, HOST, PORT): await asyncio.Future() if __name__ == '__main__': asyncio.run(main())