Merge pull request #220 from talvasconcelos/fix/issue#213

This commit is contained in:
fiatjaf 2021-06-20 21:11:58 -03:00 committed by GitHub
commit 8dc25fbe50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 68 deletions

View File

@ -10,3 +10,8 @@ lnticket_ext: Blueprint = Blueprint(
from .views_api import * # noqa
from .views import * # noqa
from .tasks import register_listeners
from lnbits.tasks import record_async
lnticket_ext.record(record_async(register_listeners))

View File

@ -0,0 +1,36 @@
import json
import trio # type: ignore
from lnbits.core.models import Payment
from lnbits.core.crud import create_payment
from lnbits.core import db as core_db
from lnbits.tasks import register_invoice_listener, internal_invoice_paid
from lnbits.helpers import urlsafe_short_hash
from .crud import get_ticket, set_ticket_paid
async def register_listeners():
invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
register_invoice_listener(invoice_paid_chan_send)
await wait_for_paid_invoices(invoice_paid_chan_recv)
async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel):
async for payment in invoice_paid_chan:
await on_invoice_paid(payment)
async def on_invoice_paid(payment: Payment) -> None:
if "lnticket" != payment.extra.get("tag"):
# not a lnticket invoice
return
ticket = await get_ticket(payment.checking_id)
if not ticket:
print("this should never happen", payment)
return
await payment.set_pending(False)
await set_ticket_paid(payment.payment_hash)
_ticket = await get_ticket(payment.checking_id)
print('ticket', _ticket)

View File

@ -77,7 +77,7 @@
{% endblock %} {% block scripts %}
<script>
console.log('{{ form_costpword }}')
//console.log('{{ form_costpword }}')
Vue.component(VueQrcode.name, VueQrcode)
new Vue({
@ -99,7 +99,11 @@
show: false,
status: 'pending',
paymentReq: null
}
},
wallet: {
inkey: ''
},
cancelListener: () => {}
}
},
computed: {
@ -128,12 +132,35 @@
},
closeReceiveDialog: function () {
var checker = this.receive.paymentChecker
var checker = this.startPaymentNotifier
dismissMsg()
clearInterval(paymentChecker)
setTimeout(function () {}, 10000)
},
startPaymentNotifier() {
this.cancelListener()
this.cancelListener = LNbits.events.onInvoicePaid(
this.wallet,
payment => {
this.receive = {
show: false,
status: 'complete',
paymentReq: null
}
dismissMsg()
this.formDialog.data.name = ''
this.formDialog.data.email = ''
this.formDialog.data.text = ''
this.$q.notify({
type: 'positive',
message: 'Sent, thank you!',
icon: 'thumb_up'
})
}
)
},
Invoice: function () {
var self = this
axios
@ -158,39 +185,15 @@
status: 'pending',
paymentReq: self.paymentReq
}
paymentChecker = setInterval(function () {
axios
.get('/lnticket/api/v1/tickets/' + self.paymentCheck)
.then(function (res) {
if (res.data.paid) {
clearInterval(paymentChecker)
self.receive = {
show: false,
status: 'complete',
paymentReq: null
}
dismissMsg()
self.formDialog.data.name = ''
self.formDialog.data.email = ''
self.formDialog.data.text = ''
self.$q.notify({
type: 'positive',
message: 'Sent, thank you!',
icon: 'thumb_up'
})
}
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
}, 2000)
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
}
},
created() {
this.wallet.inkey = '{{form_wallet}}'
this.startPaymentNotifier()
}
})
</script>

View File

@ -90,6 +90,16 @@
<div class="col">
<h5 class="text-subtitle1 q-my-none">Tickets</h5>
</div>
<!-- <div class="col-auto">
<q-btn
flat
color="grey"
icon="autorenew"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
@click="getTickets"
><q-tooltip> Refresh Tickets </q-tooltip></q-btn
>
</div> -->
<div class="col-auto">
<q-btn flat color="grey" @click="exportticketsCSV"
>Export to CSV</q-btn
@ -230,7 +240,7 @@
</div>
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script>
var mapLNTicket = function(obj) {
const mapLNTicket = function (obj) {
obj.date = Quasar.utils.date.formatDate(
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
@ -243,7 +253,7 @@
new Vue({
el: '#vue',
mixins: [windowMixin],
data: function() {
data: function () {
return {
forms: [],
tickets: [],
@ -290,11 +300,12 @@
formDialog: {
show: false,
data: {}
}
},
cancelListener: () => {}
}
},
methods: {
getTickets: function() {
getTickets: function () {
var self = this
LNbits.api
@ -303,40 +314,43 @@
'/lnticket/api/v1/tickets?all_wallets',
this.g.user.wallets[0].inkey
)
.then(function(response) {
self.tickets = response.data.map(function(obj) {
return mapLNTicket(obj)
})
.then(function (response) {
self.tickets = response.data
.map(function (obj) {
if (!obj?.paid) return
return mapLNTicket(obj)
})
.filter(v => v)
})
},
deleteTicket: function(ticketId) {
deleteTicket: function (ticketId) {
var self = this
var tickets = _.findWhere(this.tickets, {id: ticketId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this ticket')
.onOk(function() {
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/lnticket/api/v1/tickets/' + ticketId,
_.findWhere(self.g.user.wallets, {id: tickets.wallet}).inkey
)
.then(function(response) {
self.tickets = _.reject(self.tickets, function(obj) {
.then(function (response) {
self.tickets = _.reject(self.tickets, function (obj) {
return obj.id == ticketId
})
})
.catch(function(error) {
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportticketsCSV: function() {
exportticketsCSV: function () {
LNbits.utils.exportCSV(this.ticketsTable.columns, this.tickets)
},
getForms: function() {
getForms: function () {
var self = this
LNbits.api
@ -345,16 +359,17 @@
'/lnticket/api/v1/forms?all_wallets',
this.g.user.wallets[0].inkey
)
.then(function(response) {
self.forms = response.data.map(function(obj) {
.then(function (response) {
self.forms = response.data.map(function (obj) {
return mapLNTicket(obj)
})
})
},
sendFormData: function() {
sendFormData: function () {
var wallet = _.findWhere(this.g.user.wallets, {
id: this.formDialog.data.wallet
})
this.formDialog.data.inkey = wallet.inkey
var data = this.formDialog.data
if (data.id) {
@ -364,22 +379,23 @@
}
},
createForm: function(wallet, data) {
createForm: function (wallet, data) {
var self = this
console.log('create', data)
LNbits.api
.request('POST', '/lnticket/api/v1/forms', wallet.inkey, data)
.then(function(response) {
.then(function (response) {
self.forms.push(mapLNTicket(response.data))
self.formDialog.show = false
self.formDialog.data = {}
})
.catch(function(error) {
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
updateformDialog: function(formId) {
updateformDialog: function (formId) {
var link = _.findWhere(this.forms, {id: formId})
console.log(link.id)
this.formDialog.data.id = link.id
this.formDialog.data.wallet = link.wallet
this.formDialog.data.name = link.name
@ -387,10 +403,9 @@
this.formDialog.data.costpword = link.costpword
this.formDialog.show = true
},
updateForm: function(wallet, data) {
updateForm: function (wallet, data) {
var self = this
console.log(data)
console.log('update', data)
LNbits.api
.request(
'PUT',
@ -398,50 +413,67 @@
wallet.inkey,
data
)
.then(function(response) {
self.forms = _.reject(self.forms, function(obj) {
.then(function (response) {
self.forms = _.reject(self.forms, function (obj) {
return obj.id == data.id
})
self.forms.push(mapLNTicket(response.data))
self.formDialog.show = false
self.formDialog.data = {}
})
.catch(function(error) {
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
deleteForm: function(formsId) {
deleteForm: function (formsId) {
var self = this
var forms = _.findWhere(this.forms, {id: formsId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this form link?')
.onOk(function() {
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/lnticket/api/v1/forms/' + formsId,
_.findWhere(self.g.user.wallets, {id: forms.wallet}).inkey
)
.then(function(response) {
self.forms = _.reject(self.forms, function(obj) {
.then(function (response) {
self.forms = _.reject(self.forms, function (obj) {
return obj.id == formsId
})
})
.catch(function(error) {
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
})
},
exportformsCSV: function() {
exportformsCSV: function () {
LNbits.utils.exportCSV(this.formsTable.columns, this.forms)
},
startPaymentNotifier() {
this.cancelListener()
this.cancelListener = LNbits.events.onInvoicePaid(
this.g.user.wallets[0],
payment => {
this.getTickets()
this.$q.notify({
type: 'positive',
message: 'New ticket arrived!',
icon: 'textsms'
})
}
)
}
},
created: function() {
created: function () {
if (this.g.user.wallets.length) {
this.getTickets()
this.getForms()
this.startPaymentNotifier()
}
}
})

View File

@ -1,5 +1,6 @@
from quart import g, abort, render_template
from lnbits.core.crud import get_wallet
from lnbits.decorators import check_user_exists, validate_uuids
from http import HTTPStatus
@ -20,10 +21,13 @@ async def display(form_id):
if not form:
abort(HTTPStatus.NOT_FOUND, "LNTicket does not exist.")
wallet = await get_wallet(form.wallet)
return await render_template(
"lnticket/display.html",
form_id=form.id,
form_name=form.name,
form_desc=form.description,
form_costpword=form.costpword,
form_wallet=wallet.inkey
)