removed display queue because spotify doesn't support

This commit is contained in:
benarc 2021-06-01 21:19:41 +01:00
parent 5052826bc2
commit ba7bd91140
8 changed files with 128 additions and 158 deletions

View file

@ -6,6 +6,7 @@ from lnbits.helpers import urlsafe_short_hash
async def create_jukebox(
inkey: str,
user: str,
wallet: str,
title: str,
@ -84,42 +85,7 @@ async def delete_jukebox(juke_id: str):
async def create_jukebox_payment(
song_id: str,
payment_hash: str
) -> Jukebox:
result = await db.execute(
"""
INSERT INTO jukebox_payment (payment_hash, song_id, paid)
VALUES (?, ?, ?)
""",
(
payment_hash,
song_id,
False,
),
)
jukebox_payment = await get_jukebox_payment(payment_hash)
assert jukebox_payment, "Newly created Jukebox Payment couldn't be retrieved"
return jukebox_payment
async def update_jukebox_payment(payment_hash: str, **kwargs) -> Optional[JukeboxPayment]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(
f"UPDATE jukebox_payment SET {q} WHERE payment_hash = ?", (*kwargs.values(), payment_hash)
)
return await get_jukebox_payment(payment_hash)
async def get_jukebox_payment(payment_hash: str) -> Optional[JukeboxPayment]:
row = await db.fetchone("SELECT * FROM jukebox_payment WHERE payment_hash = ?", (payment_hash,))
return JukeboxPayment(**row) if row else None
##################################SONGS QUEUED
async def create_jukebox_queue(
song_id: str,
payment_hash: str
) -> Jukebox:
) -> JukeboxPayment:
result = await db.execute(
"""
INSERT INTO jukebox_payment (payment_hash, song_id, paid)

View file

@ -9,6 +9,7 @@ async def m001_initial(db):
user TEXT,
title TEXT,
wallet TEXT,
inkey TEXT,
sp_user TEXT NOT NULL,
sp_secret TEXT NOT NULL,
sp_access_token TEXT,
@ -32,16 +33,4 @@ async def m002_initial(db):
paid BOOL
);
"""
)
async def m003_initial(db):
"""
Initial jukebox_queue table.
"""
await db.execute(
"""
CREATE TABLE jukebox_queue (
jukebox_id TEXT PRIMARY KEY,
queue TEXT
);
"""
)

View file

@ -12,6 +12,7 @@ class Jukebox(NamedTuple):
user: str
title: str
wallet: str
inkey: str
sp_user: str
sp_secret: str
sp_access_token: str
@ -32,12 +33,4 @@ class JukeboxPayment(NamedTuple):
@classmethod
def from_row(cls, row: Row) -> "JukeboxPayment":
return cls(**dict(row))
class JukeboxQueue(NamedTuple):
jukebox_id: str
queue: str
@classmethod
def from_row(cls, row: Row) -> "JukeboxQueue":
return cls(**dict(row))

View file

@ -168,12 +168,12 @@ new Vue({
authAccess() {
self = this
self.requestAuthorization()
self.getSpotifyTokens()
self.$q.notify({
spinner: true,
message: 'Processing',
timeout: 10000
})
self.getSpotifyTokens()
},
getSpotifyTokens() {
self = this
@ -195,6 +195,7 @@ new Vue({
if (self.jukeboxDialog.data.sp_access_token) {
self.refreshPlaylists()
self.refreshDevices()
setTimeout(function () {}, 2000)
if (self.devices.length < 1 && self.playlists.length < 1) {
self.$q.notify({
spinner: true,
@ -217,8 +218,7 @@ new Vue({
})
clearInterval(timerId)
self.closeFormDialog()
}
else {
} else {
self.step = 4
clearInterval(timerId)
}
@ -228,7 +228,7 @@ new Vue({
.catch(err => {
LNbits.utils.notifyApiError(err)
})
}, 5000)
}, 3000)
},
requestAuthorization() {
self = this
@ -267,9 +267,12 @@ new Vue({
)
.then(function (response) {
console.log(response.data)
if (self.jukeboxDialog.data.sp_playlists && self.jukeboxDialog.data.sp_devices) {
if (
self.jukeboxDialog.data.sp_playlists &&
self.jukeboxDialog.data.sp_devices
) {
self.getJukeboxes()
// self.JukeboxLinks.push(mapJukebox(response.data))
// self.JukeboxLinks.push(mapJukebox(response.data))
}
})
},

View file

@ -230,11 +230,20 @@
<q-step :name="3" title="Add Redirect URI" icon="link" :done="step > 3">
<img src="/jukebox/static/spotapi1.gif" />
In the app go to edit-settings, set the redirect URI to this link
<br /><small
>{% raw %}{{ locationcb }}{{ jukeboxDialog.data.sp_id }}{% endraw
%}</small
<br /><q-btn
dense
outline
unelevated
color="green-7"
size="xs"
@click="copyText(locationcb + jukeboxDialog.data.sp_id, 'Link copied to clipboard!')"
><small style="font-size: 60%"
>{% raw %}{{ locationcb }}{{ jukeboxDialog.data.sp_id }}{% endraw
%}</small
><q-tooltip> Click to copy URL </q-tooltip></q-btn
>
Setting can be found
<br />
Settings can be found
<a
target="_blank"
color="green-7"

View file

@ -6,15 +6,12 @@
<p style="font-size: 22px">Currently playing</p>
<div class="row">
<div class="col-4">
<img style="width: 100px" :src="currentPlaylist[0].image" />
<img style="width: 100px" :src="currentPlay.image" />
</div>
<div class="col-8">
<strong style="font-size: 20px"
>{{ currentPlaylist[0].name }}</strong
<strong style="font-size: 20px">{{ currentPlay.name }}</strong
><br />
<strong style="font-size: 15px"
>{{ currentPlaylist[0].artist }}</strong
>
<strong style="font-size: 15px">{{ currentPlay.artist }}</strong>
</div>
</div>
</q-card-section>
@ -57,30 +54,7 @@
</q-card-section>
</q-card>
</div>
<div class="col-12 col-sm-6 col-md-5 col-lg-4 q-gutter-y-md">
<q-card class="q-pa-lg">
<q-card-section class="q-pa-none">
<p style="font-size: 21px">Queued</p>
<br />
<q-list bordered separator>
<q-item
bordered
v-for="song in queued"
:key="song.id"
clickable
v-ripple
@click="payForSong(song.id, song.name, song.artist, song.image)"
>
<q-item-section prepend>
<img style="width: 50px" :src="song.image" />
</q-item-section>
<q-item-section>{{ song.name }} ({{ song.artist }})</q-item-section>
</q-item>
</q-list>
</q-card-section>
</q-card>
</div>
<q-dialog v-model="receive.dialogues.first" position="top">
<q-card class="q-pa-lg lnbits__dialog-card">
<q-card-section class="q-pa-none">
@ -130,11 +104,15 @@
mixins: [windowMixin],
data() {
return {
currentPlaylist: {},
currentPlaylist: [],
currentlyPlaying: {},
cancelListener: () => {},
playlists: {},
playlist: '',
heavyList: [],
queued: [],
selectedWallet: {
inkey: '{{ inkey }}'
},
receive: {
dialogues: {
first: false,
@ -150,8 +128,19 @@
}
}
},
computed: {},
computed: {
currentPlay() {
return this.currentlyPlaying
}
},
methods: {
startPaymentNotifier() {
this.cancelListener()
this.cancelListener = LNbits.events.onInvoicePaid(
this.selectedWallet,
payment => console.log(payment)
)
},
cancelPayment: function () {
this.paymentReq = null
clearInterval(this.paymentDialog.checker)
@ -185,37 +174,24 @@
self.receive.paymentReq = response.data[0][1]
self.receive.paymentHash = response.data[0][0]
self.receive.dialogues.second = true
pChecker = setInterval(function () {
axios
.get(
'/jukebox/api/v1/jukebox/jb/invoicecheck/' +
self.receive.paymentHash +
'/{{ juke_id }}'
)
.then(function (res) {
console.log(res.data)
if (res.data.status == true) {
console.log('pooooooo')
// self.cancelPayment()
clearInterval(pChecker)
self.$q.notify({
type: 'positive',
message: 'Payment received!',
icon: null
})
self.receive.dialogues.second = false
}
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
}, 5000)
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
},
getCurrent() {
axios
.get('/jukebox/api/v1/jukebox/jb/currently/{{juke_id}}')
.then(function (res) {
if (res.data.id) {
console.log(res.data)
self.currentlyPlaying = res.data
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
selectPlaylist() {
self = this
LNbits.api
@ -234,19 +210,14 @@
.catch(err => {
LNbits.utils.notifyApiError(err)
})
}
},
currentSong() {}
},
created() {
this.getCurrent()
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',
@ -263,6 +234,7 @@
.catch(err => {
LNbits.utils.notifyApiError(err)
})
this.startPaymentNotifier()
}
})
</script>

View file

@ -29,7 +29,8 @@ async def print_qr_codes(juke_id):
"jukebox/jukebox.html",
playlists=jukebox.sp_playlists.split(","),
juke_id=juke_id,
price=jukebox.price
price=jukebox.price,
inkey=jukebox.inkey
)

View file

@ -89,9 +89,9 @@ async def api_check_credentials_check(sp_id):
)
async def api_create_update_jukebox(juke_id=None):
if juke_id:
jukebox = await update_jukebox(juke_id=juke_id, **g.data)
jukebox = await update_jukebox(juke_id=juke_id, inkey = g.wallet.inkey, **g.data)
else:
jukebox = await create_jukebox(**g.data)
jukebox = await create_jukebox(inkey = g.wallet.inkey, **g.data)
return jsonify(jukebox._asdict()), HTTPStatus.CREATED
@ -190,7 +190,7 @@ async def api_get_token(sp_id):
return True
######GET INVOICE
######GET INVOICE STUFF
@jukebox_ext.route("/api/v1/jukebox/jb/invoice/<sp_id>/<song_id>", methods=["GET"])
async def api_get_jukebox_invoice(sp_id, song_id):
@ -200,39 +200,76 @@ async def api_get_jukebox_invoice(sp_id, song_id):
jukebox_payment = await create_jukebox_payment(song_id,invoice[0])
print(jukebox_payment)
####new table needed to store payment hashes
return jsonify(invoice, jukebox_payment)
@jukebox_ext.route("/api/v1/jukebox/jb/invoicecheck/<payment_hash>/<sp_id>", methods=["GET"])
async def api_get_jukebox_check_invoice(sp_id, payment_hash):
@jukebox_ext.route("/api/v1/jukebox/jb/invoicepaid/<payment_hash>/<sp_id>", methods=["GET"])
async def api_get_jukebox_invoice_paid(sp_id, payment_hash):
jukebox = await get_jukebox(sp_id)
status = await check_invoice_status(jukebox.wallet, payment_hash)
is_paid = not status.pending
if is_paid:
jukebox_payment = await update_jukebox_payment(payment_hash, paid = True)
print("https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" + jukebox_payment.song_id + "&device_id=" + jukebox.sp_device)
async with httpx.AsyncClient() as client:
jukebox_payment = await update_jukebox_payment(payment_hash, paid = True)
print("https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" + jukebox_payment.song_id + "&device_id=" + jukebox.sp_device)
async with httpx.AsyncClient() as client:
try:
r = await client.get(
"https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" + jukebox_payment.song_id + "&device_id=" + jukebox.sp_device,
timeout=40,
headers={"Authorization": "Bearer " + jukebox.sp_access_token},
)
if r.json()["error"]["status"] == 401:
token = await api_get_token(sp_id)
if token == False:
print("invalid")
return jsonify({"error": "Something went wrong"})
else:
return await api_get_jukebox_invoice_paid(sp_id, payment_hash)
if r.json()["error"]["status"] == 400:
return jsonify({"error": "Something went wrong"})
return jsonify(r), HTTPStatus.OK
except AssertionError:
something = None
return jsonify({"error": "Something went wrong"})
if not is_paid:
return jsonify({"status": False})
return jsonify({"error": "Something went wrong"})
############################GET TRACKS
@jukebox_ext.route("/api/v1/jukebox/jb/currently/<sp_id>", methods=["GET"])
async def api_get_jukebox_currently(sp_id):
jukebox = await get_jukebox(sp_id)
async with httpx.AsyncClient() as client:
try:
r = await client.get(
"https://api.spotify.com/v1/me/player/currently-playing?market=ES",
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"]
}
return track, HTTPStatus.OK
except AssertionError:
something = None
try:
r = await client.get(
"https://api.spotify.com/v1/me/player/queue?uri=spotify%3Atrack%3A" + jukebox_payment.song_id + "&device_id=" + jukebox.sp_device,
timeout=40,
headers={"Authorization": "Bearer " + jukebox.sp_access_token},
)
if r.json()["error"]["status"] == 401:
token = await api_get_token(sp_id)
if token == False:
print("invalid")
return jsonify({"error": "Something went wrong"})
else:
return await api_get_jukebox_check_invoice(sp_id, payment_hash)
if r.json()["error"]["status"] == 400:
return await api_get_jukebox_currently(sp_id)
elif r.json()["error"]["status"] == 400:
return jsonify({"error": "Something went wrong"})
return r, HTTPStatus.OK
except AssertionError:
something = None
except ValueError:
return jsonify({"error": "Something went wrong"})
if not is_paid:
return jsonify({"status": False})
except AssertionError:
something = None
return jsonify({"error": "Something went wrong"})
return jsonify({"error": "Something went wrong"})