From 430cbb8275076bf21ec5c87f9891183ae079edd3 Mon Sep 17 00:00:00 2001 From: Ben Arc Date: Mon, 7 Jun 2021 14:44:50 +0100 Subject: [PATCH] Added backend websocket and queue maker --- lnbits/extensions/jukebox/views.py | 37 +++++++++++++++++-- lnbits/extensions/jukebox/views_api.py | 49 ++++++-------------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/lnbits/extensions/jukebox/views.py b/lnbits/extensions/jukebox/views.py index 2ef275b77..23673bafd 100644 --- a/lnbits/extensions/jukebox/views.py +++ b/lnbits/extensions/jukebox/views.py @@ -1,8 +1,8 @@ import time from datetime import datetime -from quart import g, render_template, request, jsonify +from quart import g, render_template, request, jsonify, websocket from http import HTTPStatus - +import trio from lnbits.decorators import check_user_exists, validate_uuids from lnbits.core.models import Payment @@ -30,8 +30,39 @@ async def print_qr_codes(juke_id): playlists=jukebox.sp_playlists.split(","), juke_id=juke_id, price=jukebox.price, - inkey=jukebox.inkey + inkey=jukebox.inkey, ) +##################WEBSOCKET ROUTES######################## + +connected_websockets = set() + + +def collect_websocket(func): + @wraps(func) + async def wrapper(*args, **kwargs): + global connected_websockets + send_channel, receive_channel = trio.open_memory_channel(0) + connected_websockets.add(send_channel) + try: + return await func(receive_channel, *args, **kwargs) + finally: + connected_websockets.remove(send_channel) + + return wrapper + + +@jukebox_ext.websocket("/ws") +@collect_websocket +async def wss(receive_channel): + while True: + data = await receive_channel.receive() + await websocket.send(data) + + +async def broadcast(message): + print(connected_websockets) + for queue in connected_websockets: + await queue.send(f"{message}") diff --git a/lnbits/extensions/jukebox/views_api.py b/lnbits/extensions/jukebox/views_api.py index 67d6b8e64..72438784b 100644 --- a/lnbits/extensions/jukebox/views_api.py +++ b/lnbits/extensions/jukebox/views_api.py @@ -10,6 +10,7 @@ import time from lnbits.decorators import api_check_wallet_key, api_validate_post_request import httpx from . import jukebox_ext +from .views import broadcast from .crud import ( create_jukebox, update_jukebox, @@ -121,7 +122,7 @@ async def api_delete_item(juke_id): @jukebox_ext.route( "/api/v1/jukebox/jb/playlist//", methods=["GET"] ) -async def api_get_jukebox_son(juke_id, sp_playlist): +async def api_get_jukebox_song(juke_id, sp_playlist): jukebox = await get_jukebox(juke_id) tracks = [] async with httpx.AsyncClient() as client: @@ -138,7 +139,7 @@ async def api_get_jukebox_son(juke_id, sp_playlist): return False else: - return await api_get_jukebox_son(juke_id, sp_playlist) + return await api_get_jukebox_song(juke_id, sp_playlist) return r, HTTPStatus.OK for item in r.json()["items"]: tracks.append( @@ -155,9 +156,6 @@ async def api_get_jukebox_son(juke_id, sp_playlist): return jsonify([track for track in tracks]) -# return jsonify([track for track in tracks]) - - async def api_get_token(juke_id): jukebox = await get_jukebox(juke_id) @@ -221,12 +219,10 @@ async def api_get_jukebox_invoice_paid(payment_hash, juke_id): jukebox_payment = await update_jukebox_payment(payment_hash, paid=True) else: return jsonify({"error": "Invoice not paid"}) + queue = await add_to_song_queue(jukebox_payment.song_id, jukebox_payment.juke_id) + return queue -# if not is_paid: -# return jsonify({"status": False}) -# return jsonify({"error": "Something went wrong"}) - ############################QUEUE SONG @@ -245,7 +241,7 @@ async def add_to_song_queue(song_id, juke_id): async with httpx.AsyncClient() as client: r = await client.post( "https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" - + jukebox_payment.song_id + + queued[0] + "&device_id=" + jukebox.sp_device.split("-")[1], timeout=40, @@ -256,36 +252,11 @@ async def add_to_song_queue(song_id, juke_id): queued = queued[1:] jukebox = await update_jukebox(juke_id=juke_id, queue=queued) queued = jukebox.queue + broadcast( + json.dumps({"juke_id": juke_id, "queue": queued, "current": song}) + ) jukebox = await update_jukebox(juke_id=juke_id, last_checked=time.time()) - - # if current track playing isnt at the front of the queue, add it to queue - - print(jukebox) - paid = await check_invoice_status(jukebox.wallet, payment_hash) - if paid: - jukebox_payment = await update_jukebox_payment(payment_hash, paid=True) - else: - return jsonify({"error": "Invoice not paid"}) - async with httpx.AsyncClient() as client: - - r = await client.post( - "https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" - + jukebox_payment.song_id - + "&device_id=" - + jukebox.sp_device.split("-")[1], - timeout=40, - headers={"Authorization": "Bearer " + jukebox.sp_access_token}, - ) - print(r) - if r.json()["error"]["status"] == 401: - token = await api_get_token(juke_id) - if token == False: - return jsonify({"error": "Something went wrong"}) - else: - return await api_get_jukebox_invoice_paid(juke_id, payment_hash) - if r.json()["error"]["status"] == 400: - return jsonify({"error": "Something went wrong"}) - return jsonify(r), HTTPStatus.OK + return jsonify(jukebox), HTTPStatus.OK ############################GET TRACKS