Creates invoice

This commit is contained in:
Ben Arc 2021-05-12 15:47:21 +01:00
parent e726d752d8
commit f43c227b95
4 changed files with 195 additions and 35 deletions

View file

@ -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)
}

View file

@ -28,6 +28,7 @@
v-model="playlist"
:options="playlists"
label="playlists"
@input="selectPlaylist()"
></q-select>
</q-card-section>
<q-card-section class="q-pa-none">
@ -38,7 +39,13 @@
separator
>
<template v-slot="{ item, index }">
<q-item :key="index" dense clickable v-ripple>
<q-item
:key="index"
dense
clickable
v-ripple
@click="payForSong(item.id, item.name, item.artist, item.image)"
>
<q-item-section>
<q-item-label>
{{ item.name }} - ({{ item.artist }})
@ -62,6 +69,7 @@
: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" />
@ -73,6 +81,43 @@
</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">
<div class="row">
<div class="col-4">
<img style="width: 100px" :src="receive.image" />
</div>
<div class="col-8">
<strong style="font-size: 20px">{{ receive.name }}</strong><br />
<strong style="font-size: 15px">{{ receive.artist }}</strong>
</div>
</div>
</q-card-section>
<br />
<div class="row q-mt-lg q-gutter-sm">
<q-btn outline color="grey" @click="getInvoice(receive.id)"
>Play for {% endraw %}{{ price }}{% raw %} sats
</q-btn>
</div>
</q-card>
</q-dialog>
<q-dialog v-model="receive.dialogues.second" position="top">
<q-card class="q-pa-lg lnbits__dialog-card">
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
<qrcode
:value="'lightning:' + receive.paymentReq"
:options="{width: 800}"
class="rounded-borders"
></qrcode>
</q-responsive>
<div class="row q-mt-lg q-gutter-sm">
<q-btn outline color="grey" @click="copyText(receive.paymentReq)"
>Copy invoice</q-btn
>
</div>
</q-card>
</q-dialog>
</div>
{% endraw %} {% endblock %} {% block scripts %}
<script src="{{ url_for('static', filename='vendor/vue-qrcode@1.0.2/vue-qrcode.min.js') }}"></script>
@ -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)
})
}
})
</script>

View file

@ -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
)

View file

@ -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/<sp_id>/<sp_playlist>", methods=["GET"])
async def api_get_jukebox_songs(sp_id, sp_playlist):
@jukebox_ext.route("/api/v1/jukebox/jb/playlist/<sp_id>/<sp_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/<sp_id>/<sp_song>/", methods=["GET"])
async def api_get_jukebox_invoice(sp_id, sp_song):
@jukebox_ext.route("/api/v1/jukebox/jb/invoice/<sp_id>/<song_id>", 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/<invoice_id>", 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)