diff --git a/lnbits/extensions/jukebox/static/js/index.js b/lnbits/extensions/jukebox/static/js/index.js index 30ce36178..9967612d6 100644 --- a/lnbits/extensions/jukebox/static/js/index.js +++ b/lnbits/extensions/jukebox/static/js/index.js @@ -177,8 +177,9 @@ new Vue({ }, getSpotifyTokens() { self = this - + var counter = 0 var timerId = setInterval(function () { + counter++ if (!self.jukeboxDialog.data.sp_user) { clearInterval(timerId) } @@ -217,7 +218,7 @@ new Vue({ clearInterval(timerId) self.closeFormDialog() } - else{ + else { self.step = 4 clearInterval(timerId) } diff --git a/lnbits/extensions/jukebox/templates/jukebox/jukebox.html b/lnbits/extensions/jukebox/templates/jukebox/jukebox.html index 25af9f43c..9aac2a249 100644 --- a/lnbits/extensions/jukebox/templates/jukebox/jukebox.html +++ b/lnbits/extensions/jukebox/templates/jukebox/jukebox.html @@ -28,6 +28,7 @@ v-model="playlist" :options="playlists" label="playlists" + @input="selectPlaylist()" > @@ -38,7 +39,13 @@ separator > - + {{ item.name }} - ({{ item.artist }}) @@ -62,6 +69,7 @@ :key="song.id" clickable v-ripple + @click="payForSong(song.id, song.name, song.artist, song.image)" > @@ -73,6 +81,43 @@ + + + + + + + + + {{ receive.name }} + {{ receive.artist }} + + + + + + Play for {% endraw %}{{ price }}{% raw %} sats + + + + + + + + + + + Copy invoice + + + {% endraw %} {% endblock %} {% block scripts %} @@ -85,20 +130,101 @@ mixins: [windowMixin], data() { return { - currentPlaylist: JSON.parse('{{ firstPlaylist | tojson }}'), - playlists: JSON.parse('{{ playlists | tojson }}'), + currentPlaylist: {}, + playlists: {}, playlist: '', heavyList: [], - queued: [] + queued: [], + receive: { + dialogues: { + first: false, + second: false + }, + paymentReq: '', + name: '', + artist: '', + image: '', + id: '', + showQR: false + } } }, computed: {}, - methods: {}, + methods: { + closeReceiveDialog() {}, + payForSong(song_id, name, artist, image) { + self = this + self.receive.name = name + self.receive.artist = artist + self.receive.image = image + self.receive.id = song_id + self.receive.dialogues.first = true + }, + getInvoice(song_id) { + LNbits.api + .request( + 'GET', + '/jukebox/api/v1/jukebox/jb/invoice/' + + '{{ juke_id }}' + + '/' + + song_id + ) + .then(function (response) { + console.log(response.data) + self.receive.paymentReq = response.data[1] + self.receive.dialogues.second = true + }) + .catch(err => { + LNbits.utils.notifyApiError(err) + }) + }, + selectPlaylist() { + self = this + LNbits.api + .request( + 'GET', + '/jukebox/api/v1/jukebox/jb/playlist/' + + '{{ juke_id }}' + + '/' + + self.playlist.split(',')[0].split('-')[1] + ) + .then(function (response) { + console.log(response.data) + self.currentPlaylist = response.data + console.log(self.currentPlaylist[2].id) + }) + .catch(err => { + LNbits.utils.notifyApiError(err) + }) + } + }, created() { - this.queued[0] = this.currentPlaylist[2] - this.queued[1] = this.currentPlaylist[5] - this.queued[2] = this.currentPlaylist[6] - this.queued[3] = this.currentPlaylist[7] + this.playlists = JSON.parse('{{ playlists | tojson }}') + + self = this + console.log( + '/jukebox/api/v1/jukebox/jb/' + + '{{ juke_id }}' + + '/' + + self.playlists[0].split(',')[0].split('-')[1] + + '/' + ) + LNbits.api + .request( + 'GET', + '/jukebox/api/v1/jukebox/jb/playlist/' + + '{{ juke_id }}' + + '/' + + self.playlists[0].split(',')[0].split('-')[1] + ) + .then(function (response) { + console.log(response.data) + self.currentPlaylist = response.data + console.log(self.currentPlaylist[2].id) + }) + .catch(err => { + LNbits.utils.notifyApiError(err) + }) } }) diff --git a/lnbits/extensions/jukebox/views.py b/lnbits/extensions/jukebox/views.py index 830480de1..306707858 100644 --- a/lnbits/extensions/jukebox/views.py +++ b/lnbits/extensions/jukebox/views.py @@ -1,18 +1,15 @@ import time from datetime import datetime -from quart import g, render_template, request +from quart import g, render_template, request, jsonify from http import HTTPStatus from lnbits.decorators import check_user_exists, validate_uuids from lnbits.core.models import Payment -from lnbits.core.crud import get_standalone_payment +import json from . import jukebox_ext from .crud import get_jukebox from urllib.parse import unquote -from .views_api import ( - api_get_jukebox_songs, -) @jukebox_ext.route("/") @@ -27,13 +24,13 @@ async def print_qr_codes(juke_id): jukebox = await get_jukebox(juke_id) if not jukebox: return "error" - firstPlaylist = await api_get_jukebox_songs( - juke_id, jukebox.sp_playlists.split(",")[0].split("-")[1] - ) - print(firstPlaylist) return await render_template( "jukebox/jukebox.html", playlists=jukebox.sp_playlists.split(","), - firstPlaylist=firstPlaylist, + juke_id=juke_id, + price=jukebox.price ) + + + diff --git a/lnbits/extensions/jukebox/views_api.py b/lnbits/extensions/jukebox/views_api.py index 6a0b3f514..1e2201ba9 100644 --- a/lnbits/extensions/jukebox/views_api.py +++ b/lnbits/extensions/jukebox/views_api.py @@ -3,6 +3,7 @@ from http import HTTPStatus from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore from base64 import urlsafe_b64encode import base64 +import json from lnbits.decorators import api_check_wallet_key, api_validate_post_request import httpx @@ -110,8 +111,9 @@ async def api_delete_item(juke_id): ######GET ACCESS TOKEN###### -@jukebox_ext.route("/api/v1/jukebox/jb//", methods=["GET"]) -async def api_get_jukebox_songs(sp_id, sp_playlist): + +@jukebox_ext.route("/api/v1/jukebox/jb/playlist//", methods=["GET"]) +async def api_get_jukebox_son(sp_id, sp_playlist): jukebox = await get_jukebox(sp_id) tracks = [] async with httpx.AsyncClient() as client: @@ -128,21 +130,23 @@ async def api_get_jukebox_songs(sp_id, sp_playlist): print("invalid") return False else: - return await api_get_jukebox_songs(sp_id, sp_playlist) - return r, HTTPStatus.OK + return await api_get_jukebox_son(sp_id, sp_playlist) + return r, HTTPStatus.OK for item in r.json()["items"]: tracks.append( { - "id": str(item["track"]["id"]), - "name": str(item["track"]["name"]), - "album": str(item["track"]["album"]["name"]), - "artist": str(item["track"]["artists"][0]["name"]), - "image": str(item["track"]["album"]["images"][0]["url"]), + 'id': item["track"]["id"], + 'name': item["track"]["name"], + 'album': item["track"]["album"]["name"], + 'artist': item["track"]["artists"][0]["name"], + 'image': item["track"]["album"]["images"][0]["url"] } ) except AssertionError: something = None - return tracks, HTTPStatus.OK + return jsonify([track for track in tracks]) + + # return jsonify([track for track in tracks]) async def api_get_token(sp_id): @@ -185,11 +189,43 @@ async def api_get_token(sp_id): ######GET INVOICE - -@jukebox_ext.route("/api/v1/jukebox/jb///", methods=["GET"]) -async def api_get_jukebox_invoice(sp_id, sp_song): +@jukebox_ext.route("/api/v1/jukebox/jb/invoice//", methods=["GET"]) +async def api_get_jukebox_invoice(sp_id, song_id): jukebox = await get_jukebox(sp_id) invoice = await create_invoice(wallet_id=jukebox.wallet,amount=jukebox.price,memo=jukebox.title) ####new table needed to store payment hashes - return invoice, HTTPStatus.OK + return jsonify(invoice) + + +@jukebox_ext.route("/api/v1/jukebox/jb/invoice/", methods=["GET"]) +async def api_get_jukebox_check_invoice(invoice_id): + async with httpx.AsyncClient() as client: + try: + r = await client.get( + "https://api.spotify.com/v1/me/player/queue" + sp_playlist + "/tracks", + timeout=40, + headers={"Authorization": "Bearer " + jukebox.sp_access_token}, + ) + if "items" not in r.json(): + if r.json()["error"]["status"] == 401: + token = await api_get_token(sp_id) + if token == False: + print("invalid") + return False + else: + return await api_get_jukebox_son(sp_id, sp_playlist) + return r, HTTPStatus.OK + for item in r.json()["items"]: + tracks.append( + { + 'id': item["track"]["id"], + 'name': item["track"]["name"], + 'album': item["track"]["album"]["name"], + 'artist': item["track"]["artists"][0]["name"], + 'image': item["track"]["album"]["images"][0]["url"] + } + ) + except AssertionError: + something = None + return jsonify(invoice) \ No newline at end of file