diff --git a/__pycache__/crud.cpython-39.pyc b/__pycache__/crud.cpython-39.pyc index a347eeb..2e195a0 100644 Binary files a/__pycache__/crud.cpython-39.pyc and b/__pycache__/crud.cpython-39.pyc differ diff --git a/__pycache__/lnurl.cpython-39.pyc b/__pycache__/lnurl.cpython-39.pyc index 8daa7b9..f5cae4b 100644 Binary files a/__pycache__/lnurl.cpython-39.pyc and b/__pycache__/lnurl.cpython-39.pyc differ diff --git a/__pycache__/migrations.cpython-39.pyc b/__pycache__/migrations.cpython-39.pyc index 68fa251..57756e2 100644 Binary files a/__pycache__/migrations.cpython-39.pyc and b/__pycache__/migrations.cpython-39.pyc differ diff --git a/__pycache__/models.cpython-39.pyc b/__pycache__/models.cpython-39.pyc index 711b944..40cedbd 100644 Binary files a/__pycache__/models.cpython-39.pyc and b/__pycache__/models.cpython-39.pyc differ diff --git a/__pycache__/views.cpython-39.pyc b/__pycache__/views.cpython-39.pyc index 1195067..ad52342 100644 Binary files a/__pycache__/views.cpython-39.pyc and b/__pycache__/views.cpython-39.pyc differ diff --git a/__pycache__/views_api.cpython-39.pyc b/__pycache__/views_api.cpython-39.pyc index 66c302c..848aa24 100644 Binary files a/__pycache__/views_api.cpython-39.pyc and b/__pycache__/views_api.cpython-39.pyc differ diff --git a/crud.py b/crud.py index 4179d49..778555c 100644 --- a/crud.py +++ b/crud.py @@ -5,7 +5,8 @@ from lnbits.helpers import urlsafe_short_hash from . import db from .models import CreateTempData, Temp from loguru import logger - +from fastapi import Request +from lnurl import encode as lnurl_encode async def create_temp(wallet_id: str, data: CreateTempData) -> Temp: temp_id = urlsafe_short_hash() @@ -31,7 +32,7 @@ async def get_temp(temp_id: str) -> Optional[Temp]: row = await db.fetchone("SELECT * FROM tempextension.temp WHERE id = ?", (temp_id,)) return Temp(**row) if row else None -async def get_temps(wallet_ids: Union[str, List[str]]) -> List[Temp]: +async def get_temps(wallet_ids: Union[str, List[str]], req: Request) -> List[Temp]: if isinstance(wallet_ids, str): wallet_ids = [wallet_ids] @@ -39,7 +40,12 @@ async def get_temps(wallet_ids: Union[str, List[str]]) -> List[Temp]: rows = await db.fetchall( f"SELECT * FROM tempextension.temp WHERE wallet IN ({q})", (*wallet_ids,) ) - return [Temp(**row) for row in rows] + tempRows = [Temp(**row) for row in rows] + logger.debug(req.url_for("temp.api_lnurl_pay", temp_id=row.id)) + for row in tempRows: + row.lnurlpay = req.url_for("temp.api_lnurl_pay", temp_id=row.id) + row.lnurlwithdraw = req.url_for("temp.api_lnurl_withdraw", temp_id=row.id) + return tempRows async def update_temp(temp_id: str, **kwargs) -> Temp: q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) diff --git a/lnurl.py b/lnurl.py index aecaead..ecb0045 100644 --- a/lnurl.py +++ b/lnurl.py @@ -15,7 +15,9 @@ from lnbits.core.services import create_invoice ################################################# @temp_ext.get( - "/api/v1/lnurl/pay/{temp_id}", status_code=HTTPStatus.OK + "/api/v1/lnurl/pay/{temp_id}", + status_code=HTTPStatus.OK, + name="temp.api_lnurl_pay", ) async def api_lnurl_pay( request: Request, @@ -67,7 +69,9 @@ async def api_lnurl_pay_cb( @temp_ext.get( - "/api/v1/lnurl/withdraw/{temp_id}", status_code=HTTPStatus.OK + "/api/v1/lnurl/withdraw/{temp_id}", + status_code=HTTPStatus.OK, + name="temp.api_lnurl_withdraw", ) async def api_lnurl_pay( request: Request, @@ -77,7 +81,7 @@ async def api_lnurl_pay( if not temp: return {"status": "ERROR", "reason": "No temp found"} return { - "callback": str(request.url_for("temp.api_lnurl_pay_callback", temp_id=temp_id)), + "callback": str(request.url_for("temp.api_lnurl_withdraw_callback", temp_id=temp_id)), "maxSendable": temp.lnurlwithdrawamount, "minSendable": temp.lnurlwithdrawamount, "k1": "", @@ -89,7 +93,7 @@ async def api_lnurl_pay( @temp_ext.get( "/api/v1/lnurl/pay/cb/{temp_id}", status_code=HTTPStatus.OK, - name="temp.api_lnurl_pay_callback", + name="temp.api_lnurl_withdraw_callback", ) async def api_lnurl_pay_cb( request: Request, diff --git a/migrations.py b/migrations.py index c77f42e..961b933 100644 --- a/migrations.py +++ b/migrations.py @@ -26,4 +26,28 @@ async def m002_addtip_wallet(db): """ ALTER TABLE tempextension.temp ADD lnurlwithdrawamount INTEGER DEFAULT 0; """ + ) + +# Here we add another field to the database, always add never edit! + +async def m004_addtip_wallet(db): + """ + Add total to templates table + """ + await db.execute( + """ + ALTER TABLE tempextension.temp ADD lnurlwithdraw TEXT; + """ + ) + +# Here we add another field to the database + +async def m005_addtip_wallet(db): + """ + Add total to templates table + """ + await db.execute( + """ + ALTER TABLE tempextension.temp ADD lnurlpay TEXT; + """ ) \ No newline at end of file diff --git a/models.py b/models.py index ae031ff..c2cdf60 100644 --- a/models.py +++ b/models.py @@ -1,8 +1,13 @@ +# Models for retrieving data from the database +# Includes some classmethods where we can add some logic to the data + from sqlite3 import Row from typing import Optional, List from pydantic import BaseModel +from fastapi import Request from lnbits.lnurl import encode as lnurl_encode +from urllib.parse import urlparse class CreateTempData(BaseModel): wallet: Optional[str] @@ -18,6 +23,8 @@ class Temp(BaseModel): total: Optional[int] lnurlpayamount: Optional[int] lnurlwithdrawamount: Optional[int] + lnurlpay: str + lnurlwithdraw: str @classmethod def from_row(cls, row: Row) -> "Temp": diff --git a/templates/temp/index.html b/templates/temp/index.html index 2662be2..2ef805b 100644 --- a/templates/temp/index.html +++ b/templates/temp/index.html @@ -29,12 +29,10 @@ :pagination.sync="tempsTable.pagination" > - + ${ col.label } - LNURL-pay - LNURL-withdraw @@ -46,27 +44,42 @@ :props="props" > ${ col.value } + + - - + > + + Open public page + + Click to copy${props.row.id.substring(0,6)}... + + + @@ -151,11 +164,11 @@ - +

- ${ urlDialog.data.name }
${ + ${ urlDialog.data.lnurlpay }
${ urlDialog.data.shareUrl }

@@ -163,7 +176,7 @@ Copy URL Close @@ -199,18 +212,6 @@ align: 'left', label: 'Wallet', field: 'wallet' - }, - { - name: 'lnurlwithdrawamount', - align: 'left', - label: 'LNURL Withdraw amount', - field: 'lnurlwithdrawamount' - }, - { - name: 'lnurlpayamount', - align: 'left', - label: 'LNURL Pay amount', - field: 'lnurlpayamount' } ], pagination: { @@ -379,141 +380,6 @@ disabled: false } }, - deleteItem(id) { - const [tempId, itemId] = id.split(':') - const temp = _.findWhere(this.temps, {id: tempId}) - const wallet = _.findWhere(this.g.user.wallets, { - id: temp.wallet - }) - LNbits.utils - .confirmDialog('Are you sure you want to delete this item?') - .onOk(() => { - temp.itemsMap.delete(id) - const data = { - items: [...temp.itemsMap.values()] - } - this.updateTempItems(temp.id, wallet, data) - }) - }, - addItems() { - const temp = _.findWhere(this.temps, {id: this.formDialog.data.temp}) - const wallet = _.findWhere(this.g.user.wallets, { - id: temp.wallet - }) - if (this.formDialog.data.id) { - temp.itemsMap.set(this.formDialog.data.id, this.formDialog.data) - } - const data = { - items: this.formDialog.data.id - ? [...temp.itemsMap.values()] - : [...temp.items, this.formDialog.data] - } - this.updateTempItems(temp.id, wallet, data) - }, - deleteAllItems(tempId) { - const temp = _.findWhere(this.temps, {id: tempId}) - const wallet = _.findWhere(this.g.user.wallets, { - id: temp.wallet - }) - LNbits.utils - .confirmDialog('Are you sure you want to delete ALL items?') - .onOk(() => { - temp.itemsMap.clear() - const data = { - items: [] - } - this.updateTempItems(temp.id, wallet, data) - }) - }, - updateTempItems(tempId, wallet, data) { - LNbits.api - .request( - 'PUT', - `/temp/api/v1/temps/${tempId}/items`, - wallet.adminkey, - data - ) - .then(response => { - this.temps = _.reject(this.temps, obj => { - return obj.id == tempId - }) - this.temps.push(mapTemp(response.data)) - this.closeformDialog() - }) - .catch(error => { - LNbits.utils.notifyApiError(error) - }) - }, - exportJSON(tempId) { - const temp = _.findWhere(this.temps, {id: tempId}) - const data = [...temp.items] - const filename = `items_${temp.id}.json` - const json = JSON.stringify(data, null, 2) - let status = Quasar.utils.exportFile(filename, json) - if (status !== true) { - this.$q.notify({ - message: 'Browser denied file download...', - color: 'negative' - }) - } - }, - importJSON(tempId) { - try { - let input = document.getElementById('import') - input.click() - input.onchange = e => { - let file = e.target.files[0] - let reader = new FileReader() - reader.readAsText(file, 'UTF-8') - reader.onload = async readerEvent => { - try { - let content = readerEvent.target.result - let data = JSON.parse(content).filter( - obj => obj.title && obj.price - ) - if (!data.length) { - throw new Error('Invalid JSON or missing data.') - } - this.openFileDataDialog(tempId, data) - } catch (error) { - this.$q.notify({ - message: `Error importing file. ${error.message}`, - color: 'negative' - }) - return - } - } - } - } catch (error) { - this.$q.notify({ - message: 'Error importing file', - color: 'negative' - }) - } - }, - openFileDataDialog(tempId, data) { - const temp = _.findWhere(this.temps, {id: tempId}) - const wallet = _.findWhere(this.g.user.wallets, { - id: temp.wallet - }) - data.forEach(item => { - item.formattedPrice = LNbits.utils.formatCurrency( - Number(item.price).toFixed(2), - temp.currency - ) - }) - this.fileDataDialog.data = data - this.fileDataDialog.count = data.length - this.fileDataDialog.show = true - this.fileDataDialog.import = () => { - let updatedData = { - items: [...temp.items, ...data] - } - this.updateTempItems(temp.id, wallet, updatedData) - this.fileDataDialog.data = {} - this.fileDataDialog.show = false - } - }, openUrlDialog(id) { this.urlDialog.data = _.findWhere(this.temps, {id}) this.urlDialog.show = true @@ -522,6 +388,7 @@ created: function () { if (this.g.user.wallets.length) { this.getTemps() + } } }) diff --git a/templates/temp/tpos.html b/templates/temp/temp.html similarity index 85% rename from templates/temp/tpos.html rename to templates/temp/temp.html index 7d44037..518db04 100644 --- a/templates/temp/tpos.html +++ b/templates/temp/temp.html @@ -37,7 +37,7 @@ - {% include "lnurlp/_lnurl.html" %} +
@@ -48,7 +48,18 @@ new Vue({ el: '#vue', - mixins: [windowMixin] + mixins: [windowMixin], + data: function () { + return { + lnurlpay: "", + lnurlwithdraw: "", + } + }, + created: function () { + if (this.g.user.wallets.length) { + this.getTemps() + } + } }) {% endblock %} diff --git a/views.py b/views.py index b26a391..5957521 100644 --- a/views.py +++ b/views.py @@ -42,14 +42,15 @@ async def temp(request: Request, temp_id): "temp/temp.html", { "request": request, - "temp": temp, - "withdrawamtemps": temp.withdrawamtemps, + "temp_id": temp_id, + "lnurlpay": temp.lnurlpayamount, + "lnurlwithdraw": temp.lnurlwithdrawamount, "web_manifest": f"/temp/manifest/{temp_id}.webmanifest", }, ) -# Manifest, customise or remove manifest completely +# Manifest for public page, customise or remove manifest completely @temp_ext.get("/manifest/{temp_id}.webmanifest") async def manifest(temp_id: str): diff --git a/views_api.py b/views_api.py index bb0f83b..4e6e79d 100644 --- a/views_api.py +++ b/views_api.py @@ -38,13 +38,13 @@ from .models import CreateTempData @temp_ext.get("/api/v1/temps", status_code=HTTPStatus.OK) async def api_temps( - all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type) + req: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type) ): wallet_ids = [wallet.wallet.id] if all_wallets: user = await get_user(wallet.wallet.user) wallet_ids = user.wallet_ids if user else [] - return [temp.dict() for temp in await get_temps(wallet_ids)] + return [temp.dict() for temp in await get_temps(wallet_ids, req)] ## Get a specific record belonging to a user