From 85d9a3fcc375d17262c69e04d21bd7bd0e1a3023 Mon Sep 17 00:00:00 2001 From: Stefan Stammberger Date: Tue, 28 Sep 2021 21:18:15 +0200 Subject: [PATCH] fix: some errors in lnticket ext --- lnbits/extensions/lnticket/__init__.py | 8 ++--- lnbits/extensions/lnticket/crud.py | 14 +++----- lnbits/extensions/lnticket/models.py | 18 +++++++++- lnbits/extensions/lnticket/tasks.py | 20 +++++------ lnbits/extensions/lnticket/views.py | 12 ++++--- lnbits/extensions/lnticket/views_api.py | 44 ++++++++----------------- 6 files changed, 57 insertions(+), 59 deletions(-) diff --git a/lnbits/extensions/lnticket/__init__.py b/lnbits/extensions/lnticket/__init__.py index 28ef8067..0a872e8c 100644 --- a/lnbits/extensions/lnticket/__init__.py +++ b/lnbits/extensions/lnticket/__init__.py @@ -1,6 +1,4 @@ -from fastapi import APIRouter, FastAPI -from fastapi.staticfiles import StaticFiles -from starlette.routing import Mount +from fastapi import APIRouter from lnbits.db import Database from lnbits.helpers import template_renderer @@ -23,7 +21,9 @@ def lnticket_renderer(): from .views_api import * # noqa from .views import * # noqa +from .tasks import register_listeners -@lntickets_ext.on_event("startup") +@lnticket_ext.on_event("startup") def _do_it(): + # FIXME: isn't called yet register_listeners() diff --git a/lnbits/extensions/lnticket/crud.py b/lnbits/extensions/lnticket/crud.py index 5c1f1e02..327fb90e 100644 --- a/lnbits/extensions/lnticket/crud.py +++ b/lnbits/extensions/lnticket/crud.py @@ -1,9 +1,10 @@ +from lnbits.core.models import Wallet from typing import List, Optional, Union from lnbits.helpers import urlsafe_short_hash from . import db -from .models import Tickets, Forms +from .models import CreateFormData, Tickets, Forms import httpx @@ -103,13 +104,8 @@ async def delete_ticket(ticket_id: str) -> None: async def create_form( - *, - wallet: str, - name: str, - webhook: Optional[str] = None, - description: str, - amount: int, - flatrate: int, + data: CreateFormData, + wallet: Wallet, ) -> Forms: form_id = urlsafe_short_hash() await db.execute( @@ -117,7 +113,7 @@ async def create_form( INSERT INTO lnticket.form2 (id, wallet, name, webhook, description, flatrate, amount, amountmade) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, - (form_id, wallet, name, webhook, description, flatrate, amount, 0), + (form_id, wallet.id, wallet.name, data.webhook, data.description, data.flatrate, data.amount, 0), ) form = await get_form(form_id) diff --git a/lnbits/extensions/lnticket/models.py b/lnbits/extensions/lnticket/models.py index 1bc8237c..6fac90c2 100644 --- a/lnbits/extensions/lnticket/models.py +++ b/lnbits/extensions/lnticket/models.py @@ -1,10 +1,26 @@ +from typing import Optional +from fastapi.param_functions import Query from pydantic import BaseModel +class CreateFormData(BaseModel): + name: str = Query(...) + webhook: str = Query(None) + description: str = Query(..., min_length=0) + amount: int = Query(..., ge=0) + flatrate: int = Query(...) + +class CreateTicketData(BaseModel): + form: str = Query(...) + name: str = Query(...) + email: str = Query("") + ltext: str = Query(...) + sats: int = Query(..., ge=0) + class Forms(BaseModel): id: str wallet: str name: str - webhook: str + webhook: Optional[str] description: str amount: int flatrate: int diff --git a/lnbits/extensions/lnticket/tasks.py b/lnbits/extensions/lnticket/tasks.py index 5160de1d..d08d74c9 100644 --- a/lnbits/extensions/lnticket/tasks.py +++ b/lnbits/extensions/lnticket/tasks.py @@ -1,23 +1,21 @@ -import json -import trio # type: ignore +import asyncio 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 lnbits.tasks import register_invoice_listener 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) + send_queue = asyncio.Queue() + recv_queue = asyncio.Queue() + register_invoice_listener(send_queue) + await wait_for_paid_invoices(recv_queue) -async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel): - async for payment in invoice_paid_chan: +async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue): + while True: + payment = await invoice_paid_queue.get() await on_invoice_paid(payment) diff --git a/lnbits/extensions/lnticket/views.py b/lnbits/extensions/lnticket/views.py index dbf3cbbd..62002b76 100644 --- a/lnbits/extensions/lnticket/views.py +++ b/lnbits/extensions/lnticket/views.py @@ -1,7 +1,9 @@ -from quart import g, abort, render_template - +from fastapi.param_functions import Depends +from starlette.exceptions import HTTPException +from starlette.responses import HTMLResponse +from lnbits.core.models import User from lnbits.core.crud import get_wallet -from lnbits.decorators import check_user_exists, validate_uuids +from lnbits.decorators import check_user_exists from http import HTTPStatus from . import lnticket_ext, lnticket_renderer @@ -12,7 +14,9 @@ from fastapi.templating import Jinja2Templates templates = Jinja2Templates(directory="templates") @lnticket_ext.get("/", response_class=HTMLResponse) -@validate_uuids(["usr"], required=True) +# not needed as we automatically get the user with the given ID +# If no user with this ID is found, an error is raised +# @validate_uuids(["usr"], required=True) # @check_user_exists() async def index(request: Request, user: User = Depends(check_user_exists)): return lnticket_renderer().TemplateResponse("lnticket/index.html", {"request": request,"user": user.dict()}) diff --git a/lnbits/extensions/lnticket/views_api.py b/lnbits/extensions/lnticket/views_api.py index f1094e7e..eaf73e93 100644 --- a/lnbits/extensions/lnticket/views_api.py +++ b/lnbits/extensions/lnticket/views_api.py @@ -1,10 +1,10 @@ +from lnbits.extensions.lnticket.models import CreateFormData, CreateTicketData import re -from quart import g, jsonify, request from http import HTTPStatus +from typing import List -from fastapi import FastAPI, Query +from fastapi import Query from fastapi.params import Depends -from fastapi.encoders import jsonable_encoder from pydantic import BaseModel from starlette.exceptions import HTTPException @@ -13,7 +13,7 @@ from starlette.responses import HTMLResponse, JSONResponse # type: ignore from lnbits.core.crud import get_user, get_wallet from lnbits.core.services import create_invoice, check_invoice_status -from lnbits.decorators import api_check_wallet_key, api_validate_post_request +from lnbits.decorators import WalletTypeInfo, get_key_type from . import lnticket_ext from .crud import ( @@ -33,26 +33,17 @@ from .crud import ( # FORMS -@lnticket_ext.get("/api/v1/forms", status_code=HTTPStatus.OK) -# @api_check_wallet_key("invoice") -async def api_forms(r: Request, wallet: WalletTypeInfo = Depends(get_key_type)): +@lnticket_ext.get("/api/v1/forms") +async def api_forms_get(r: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)): wallet_ids = [wallet.wallet.id] - if "all_wallets" in r.args: + if all_wallets: wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids return ( - [form._asdict() for form in await get_forms(wallet_ids)], + [form.dict() for form in await get_forms(wallet_ids)], ) -class CreateData(BaseModel): - wallet: str = Query(...) - name: str = Query(...) - webhook: str = Query(None) - description: str = Query(..., min_length=0) - amount: int = Query(..., ge=0) - flatrate: int = Query(...) - @lnticket_ext.post("/api/v1/forms", status_code=HTTPStatus.CREATED) @lnticket_ext.put("/api/v1/forms/{form_id}") # @api_check_wallet_key("invoice") @@ -66,7 +57,7 @@ class CreateData(BaseModel): # "flatrate": {"type": "integer", "required": True}, # } # ) -async def api_form_create(data: CreateData, form_id=None, wallet: WalletTypeInfo = Depends(get_key_type)): +async def api_form_create(data: CreateFormData, form_id=None, wallet: WalletTypeInfo = Depends(get_key_type)): if form_id: form = await get_form(form_id) @@ -86,8 +77,8 @@ async def api_form_create(data: CreateData, form_id=None, wallet: WalletTypeInfo form = await update_form(form_id, **data) else: - form = await create_form(**data) - return form._asdict() + form = await create_form(data, wallet.wallet) + return form.dict() @lnticket_ext.delete("/api/v1/forms/{form_id}") @@ -118,25 +109,18 @@ async def api_form_delete(form_id, wallet: WalletTypeInfo = Depends(get_key_type #########tickets########## -@lnticket_ext.get("/api/v1/tickets", status_code=HTTPStatus.OK) +@lnticket_ext.get("/api/v1/tickets") # @api_check_wallet_key("invoice") -async def api_tickets(all_wallets: bool = Query(None), wallet: WalletTypeInfo = Depends(get_key_type)): +async def api_tickets(all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)): wallet_ids = [wallet.wallet.id] if all_wallets: wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids return ( - [form._asdict() for form in await get_tickets(wallet_ids)] + [form.dict() for form in await get_tickets(wallet_ids)] ) -class CreateTicketData(BaseModel): - form: str = Query(...) - name: str = Query(...) - email: str = Query("") - ltext: str = Query(...) - sats: int = Query(..., ge=0) - @lnticket_ext.post("/api/v1/tickets/{form_id}", status_code=HTTPStatus.CREATED) # @api_validate_post_request( # schema={