diff --git a/lnbits/extensions/jukebox/crud.py b/lnbits/extensions/jukebox/crud.py
index 272d3e1a..074791c1 100644
--- a/lnbits/extensions/jukebox/crud.py
+++ b/lnbits/extensions/jukebox/crud.py
@@ -3,6 +3,7 @@ from typing import List, Optional
from . import db
from .models import Jukebox, JukeboxPayment
from lnbits.helpers import urlsafe_short_hash
+import json
async def create_jukebox(
@@ -21,8 +22,8 @@ async def create_jukebox(
juke_id = urlsafe_short_hash()
result = await db.execute(
"""
- INSERT INTO jukebox (id, user, title, wallet, sp_user, sp_secret, sp_access_token, sp_refresh_token, sp_device, sp_playlists, price, profit, queue)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT INTO jukebox (id, user, title, wallet, sp_user, sp_secret, sp_access_token, sp_refresh_token, sp_device, sp_playlists, price, profit)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
juke_id,
@@ -37,7 +38,6 @@ async def create_jukebox(
sp_playlists,
int(price),
0,
- "[]",
),
)
jukebox = await get_jukebox(juke_id)
diff --git a/lnbits/extensions/jukebox/migrations.py b/lnbits/extensions/jukebox/migrations.py
index 94662014..7d4fe2e3 100644
--- a/lnbits/extensions/jukebox/migrations.py
+++ b/lnbits/extensions/jukebox/migrations.py
@@ -17,9 +17,7 @@ async def m001_initial(db):
sp_device TEXT,
sp_playlists TEXT,
price INTEGER,
- profit INTEGER,
- queue TEXT,
- last_checked TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now'))
+ profit INTEGER
);
"""
)
diff --git a/lnbits/extensions/jukebox/models.py b/lnbits/extensions/jukebox/models.py
index e88f5896..1d57a028 100644
--- a/lnbits/extensions/jukebox/models.py
+++ b/lnbits/extensions/jukebox/models.py
@@ -21,8 +21,6 @@ class Jukebox(NamedTuple):
sp_playlists: str
price: int
profit: int
- queue: list
- last_checked: int
@classmethod
def from_row(cls, row: Row) -> "Jukebox":
diff --git a/lnbits/extensions/jukebox/static/js/index.js b/lnbits/extensions/jukebox/static/js/index.js
index c162bf51..64e056b9 100644
--- a/lnbits/extensions/jukebox/static/js/index.js
+++ b/lnbits/extensions/jukebox/static/js/index.js
@@ -199,7 +199,7 @@ new Vue({
console.log(self.devices)
console.log("this.devices")
setTimeout(function () {
- if (self.devices.length < 1 && self.playlists.length < 1) {
+ if (self.devices.length < 1 || self.playlists.length < 1) {
self.$q.notify({
spinner: true,
color: 'red',
diff --git a/lnbits/extensions/jukebox/templates/jukebox/jukebox.html b/lnbits/extensions/jukebox/templates/jukebox/jukebox.html
index 2cafd32a..6db64018 100644
--- a/lnbits/extensions/jukebox/templates/jukebox/jukebox.html
+++ b/lnbits/extensions/jukebox/templates/jukebox/jukebox.html
@@ -9,8 +9,7 @@
- {{ currentPlay.name }}
+ {{ currentPlay.name }}
{{ currentPlay.artist }}
@@ -20,29 +19,15 @@
Pick a song
-
+
+
-
+
-
+
{{ item.name }} - ({{ item.artist }})
@@ -70,8 +55,7 @@
- Play for {% endraw %}{{ price }}{% raw %} sats
+ Play for {% endraw %}{{ price }}{% raw %} sats
@@ -79,16 +63,10 @@
-
+
- Copy invoice
+ Copy invoice
@@ -106,7 +84,7 @@
return {
currentPlaylist: [],
currentlyPlaying: {},
- cancelListener: () => {},
+ cancelListener: () => { },
playlists: {},
playlist: '',
heavyList: [],
@@ -133,13 +111,6 @@
}
},
methods: {
- startPaymentNotifier() {
- this.cancelListener()
- this.cancelListener = LNbits.events.onInvoicePaid(
- this.selectedWallet,
- payment => console.log(payment)
- )
- },
cancelPayment: function () {
this.paymentReq = null
clearInterval(this.paymentDialog.checker)
@@ -147,7 +118,7 @@
this.paymentDialog.dismissMsg()
}
},
- closeReceiveDialog() {},
+ closeReceiveDialog() { },
payForSong(song_id, name, artist, image) {
self = this
self.receive.name = name
@@ -162,78 +133,86 @@
.request(
'GET',
'/jukebox/api/v1/jukebox/jb/invoice/' +
- '{{ juke_id }}' +
- '/' +
- song_id
+ '{{ juke_id }}' +
+ '/' +
+ song_id
)
.then(function (response) {
self.receive.paymentReq = response.data[0][1]
self.receive.paymentHash = response.data[0][0]
self.receive.dialogues.second = true
- var refreshIntervalId = setInterval(function () {
- self.checkInvoice(self.receive.paymentHash)
- if(self.paid){
+
+ var paymentChecker = setInterval(function () {
+ if (!self.paid) {
+ self.checkInvoice(self.receive.paymentHash, '{{ juke_id }}')
+ }
+ if (self.paid) {
+ clearInterval(paymentChecker)
+ self.paid = true
self.receive.dialogues.first = false
self.receive.dialogues.second = false
self.$q.notify({
- message:
+ message:
'Processing',
- })
- console.log('/api/v1/jukebox/jb/invoicepaid/' + self.receive.paymentHash + '/{{ juke_id }}')
+ })
LNbits.api
- .request(
- 'GET',
- '/jukebox/api/v1/jukebox/jb/invoicep/{{ juke_id }}/' + self.receive.paymentHash)
- .then(function (response) {
- self.$q.notify({
- color: 'green',
- message:
- 'Success! "' + self.receive.name + '" will be played soon',
- timeout: 2000
+ .request(
+ 'GET',
+ '/jukebox/api/v1/jukebox/jb/invoicep/' + song_id + '/{{ juke_id }}/' + self.receive.paymentHash)
+ .then(function (response1) {
+ console.log(response1)
+ if (response1.data[2] == song_id) {
+
+ self.$q.notify({
+ color: 'green',
+ message:
+ 'Success! "' + self.receive.name + '" will be played soon',
+ timeout: 2000
+ })
+
+ self.paid = false
+ response1 = []
+ }
})
- clearInterval(refreshIntervalId)
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
-
- }
- }, 2000)
+ .catch(err => {
+
+ LNbits.utils.notifyApiError(err)
+ self.paid = false
+ response1 = []
+ })
+ }
+ }, 4000)
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
},
- checkInvoice: function (paymentHash) {
+ checkInvoice(juke_id, paymentHash) {
+
var self = this
LNbits.api
.request(
'GET',
- '/public/v1/payment/' + paymentHash,
+ '/jukebox/api/v1/jukebox/jb/checkinvoice/' + juke_id + '/' + paymentHash,
'filla'
)
.then(function (response) {
- console.log(response)
- if (response) {
- self.paid = true
- return
- }
- else{
- self.paid = false
- return
- }
+ console.log(response.data.paid)
+ self.paid = response.data.paid
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
getCurrent() {
- axios
- .get('/jukebox/api/v1/jukebox/jb/currently/{{juke_id}}')
+
+ LNbits.api
+ .request(
+ 'GET',
+ '/jukebox/api/v1/jukebox/jb/currently/{{juke_id}}')
.then(function (res) {
if (res.data.id) {
- console.log(res.data)
self.currentlyPlaying = res.data
}
})
@@ -247,20 +226,18 @@
.request(
'GET',
'/jukebox/api/v1/jukebox/jb/playlist/' +
- '{{ juke_id }}' +
- '/' +
- self.playlist.split(',')[0].split('-')[1]
+ '{{ 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)
})
},
- currentSong() {}
+ currentSong() { }
},
created() {
this.getCurrent()
@@ -271,28 +248,19 @@
.request(
'GET',
'/jukebox/api/v1/jukebox/jb/playlist/' +
- '{{ juke_id }}' +
- '/' +
- self.playlists[0].split(',')[0].split('-')[1]
+ '{{ 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)
})
// this.startPaymentNotifier()
- },
- mounted() {
- self = this
- self.selectedWallet['inkey'] = '{{ inkey }}'
- LNbits.events.onInvoicePaid(self.selectedWallet, payment =>
- console.log(payment)
- )
}
})
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/lnbits/extensions/jukebox/views.py b/lnbits/extensions/jukebox/views.py
index 9223a1b9..665c6821 100644
--- a/lnbits/extensions/jukebox/views.py
+++ b/lnbits/extensions/jukebox/views.py
@@ -33,37 +33,3 @@ async def print_qr_codes(juke_id):
price=jukebox.price,
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 c76c35e5..29799acb 100644
--- a/lnbits/extensions/jukebox/views_api.py
+++ b/lnbits/extensions/jukebox/views_api.py
@@ -5,12 +5,12 @@ from base64 import urlsafe_b64encode
import base64
import json
import time
-
+from lnbits.core.crud import get_wallet
+from lnbits.core.services import create_invoice, check_invoice_status
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,
@@ -133,10 +133,9 @@ async def api_get_jukebox_song(juke_id, sp_playlist):
headers={"Authorization": "Bearer " + jukebox.sp_access_token},
)
if "items" not in r.json():
- if r.json()["error"]["status"] == 401:
+ if r.status_code == 401:
token = await api_get_token(juke_id)
if token == False:
-
return False
else:
return await api_get_jukebox_song(juke_id, sp_playlist)
@@ -208,60 +207,107 @@ async def api_get_jukebox_invoice(juke_id, song_id):
return jsonify(invoice, jukebox_payment)
-@jukebox_ext.route("/api/v1/jukebox/jb/invoicep//", methods=["GET"])
-async def api_get_jukebox_invoice_paid(juke_id, pay_hash):
+@jukebox_ext.route(
+ "/api/v1/jukebox/jb/checkinvoice//", methods=["GET"]
+)
+async def api_get_jukebox_invoice_check(pay_hash, juke_id):
jukebox = await get_jukebox(juke_id)
- print(jukebox)
- paid = await check_invoice_status(jukebox.wallet, pay_hash)
- if paid.paid:
- jukebox_payment = await update_jukebox_payment(pay_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
+ try:
+ status = await check_invoice_status(jukebox.wallet, pay_hash)
+ is_paid = not status.pending
+ except Exception as exc:
+ return jsonify({"paid": False}), HTTPStatus.OK
+ if is_paid:
+ wallet = await get_wallet(jukebox.wallet)
+ payment = await wallet.get_payment(pay_hash)
+ await payment.set_pending(False)
+ await update_jukebox_payment(pay_hash, paid=True)
+ return jsonify({"paid": True}), HTTPStatus.OK
+ return jsonify({"paid": False}), HTTPStatus.OK
-@jukebox_ext.route("/api/v1/jukebox/jb/invoicep/", methods=["GET"])
-async def api_get_jukebox_invoice_cunt(cunt):
-
- return cunt
-
-
-############################QUEUE SONG
-
-
-async def add_to_song_queue(song_id, juke_id):
+@jukebox_ext.route(
+ "/api/v1/jukebox/jb/invoicep///", methods=["GET"]
+)
+async def api_get_jukebox_invoice_paid(song_id, juke_id, pay_hash):
jukebox = await get_jukebox(juke_id)
- queue = jukebox.queue
- print(queue[0])
- queue.append(song_id)
- # Add song to back of queue
- jukebox = await update_jukebox(juke_id=juke_id, queue=queue)
- # while loop for all tracks. Check 25 secs has passsed since last check.
- queued = jukebox.queue
- while len(queued) > 0:
- if (time.time() - jukebox.last_checked) > 25000:
- song = await api_get_jukebox_currently(juke_id)
- if song.track.id != queued[0]:
+ jukebox_payment = await get_jukebox_payment(pay_hash)
+ if jukebox_payment.paid:
+ async with httpx.AsyncClient() as client:
+ r = await client.get(
+ "https://api.spotify.com/v1/me/player/currently-playing?market=ES",
+ timeout=40,
+ headers={"Authorization": "Bearer " + jukebox.sp_access_token},
+ )
+ if r.status_code == 204:
+ async with httpx.AsyncClient() as client:
+ uri = ["spotify:track:" + song_id]
+ r = await client.put(
+ "https://api.spotify.com/v1/me/player/play?device_id="
+ + jukebox.sp_device.split("-")[1],
+ json={"uris": uri},
+ timeout=40,
+ headers={"Authorization": "Bearer " + jukebox.sp_access_token},
+ )
+ if r.status_code == 204:
+ return jsonify(jukebox_payment), HTTPStatus.OK
+ elif r.status_code == 401 or r.status_code == 403:
+ token = await api_get_token(juke_id)
+ if token == False:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.FORBIDDEN,
+ )
+ else:
+ return api_get_jukebox_invoice_paid(
+ song_id, juke_id, pay_hash
+ )
+ else:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.FORBIDDEN,
+ )
+ elif r.status_code == 200:
async with httpx.AsyncClient() as client:
r = await client.post(
"https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A"
- + queued[0]
+ + song_id
+ "&device_id="
+ jukebox.sp_device.split("-")[1],
timeout=40,
headers={"Authorization": "Bearer " + jukebox.sp_access_token},
)
- print(r)
- else:
- 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())
- return jsonify(jukebox), HTTPStatus.OK
+ if r.status_code == 204:
+ return jsonify(jukebox_payment), HTTPStatus.OK
+
+ elif r.status_code == 401 or r.status_code == 403:
+ token = await api_get_token(juke_id)
+ if token == False:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.OK,
+ )
+ else:
+ return await api_get_jukebox_invoice_paid(
+ song_id, juke_id, pay_hash
+ )
+ else:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.OK,
+ )
+ elif r.status_code == 401 or r.status_code == 403:
+ token = await api_get_token(juke_id)
+ if token == False:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.OK,
+ )
+ else:
+ return await api_get_jukebox_invoice_paid(
+ song_id, juke_id, pay_hash
+ )
+ return jsonify({"error": "Invoice not paid"}), HTTPStatus.OK
############################GET TRACKS
@@ -277,32 +323,29 @@ async def api_get_jukebox_currently(juke_id):
timeout=40,
headers={"Authorization": "Bearer " + jukebox.sp_access_token},
)
- try:
- if r.json()["item"]:
- track = {
- "id": r.json()["item"]["id"],
- "name": r.json()["item"]["name"],
- "album": r.json()["item"]["album"]["name"],
- "artist": r.json()["item"]["artists"][0]["name"],
- "image": r.json()["item"]["album"]["images"][0]["url"],
- }
+ if r.status_code == 204:
+ return jsonify({"error": "Nothing"}), HTTPStatus.OK
+ elif r.status_code == 200:
+ response = r.json()
+ response["item"]
+ track = {
+ "id": response["item"]["id"],
+ "name": response["item"]["name"],
+ "album": response["item"]["album"]["name"],
+ "artist": response["item"]["artists"][0]["name"],
+ "image": response["item"]["album"]["images"][0]["url"],
+ }
return track, HTTPStatus.OK
- except AssertionError:
- something = None
- try:
- 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_currently(juke_id)
- elif r.json()["error"]["status"] == 400:
- return jsonify({"error": "Something went wrong"})
- except ValueError:
- return jsonify({"error": "Something went wrong"})
-
+ elif r.status_code == 401:
+ token = await api_get_token(juke_id)
+ if token == False:
+ return (
+ jsonify({"error": "Invoice not paid"}),
+ HTTPStatus.FORBIDDEN,
+ )
+ else:
+ return await api_get_jukebox_currently(juke_id)
+ else:
+ return jsonify("Something went wrong"), HTTPStatus.NOT_FOUND
except AssertionError:
- something = None
- return jsonify({"error": "Something went wrong"})
- return jsonify({"error": "Something went wrong"})
+ return jsonify("Something went wrong"), HTTPStatus.NOT_FOUND