From 83a9dc2a3e25e89fdd1a6a4af67bdf0cd1044ef4 Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Mon, 23 Aug 2021 10:18:52 +0100 Subject: [PATCH 1/2] syntax refactoring up to diagonalley --- lnbits/extensions/events/views_api.py | 54 ++++++------- lnbits/extensions/jukebox/views_api.py | 20 ++--- lnbits/extensions/livestream/views_api.py | 97 +++++++++++++---------- 3 files changed, 87 insertions(+), 84 deletions(-) diff --git a/lnbits/extensions/events/views_api.py b/lnbits/extensions/events/views_api.py index 600c87676..1ea516a9d 100644 --- a/lnbits/extensions/events/views_api.py +++ b/lnbits/extensions/events/views_api.py @@ -53,16 +53,16 @@ class CreateData(BaseModel): price_per_ticket: int = Query(..., ge=0) @events_ext.post("/api/v1/events") -@events_ext.put("/api/v1/events/") +@events_ext.put("/api/v1/events/{event_id}") @api_check_wallet_key("invoice") async def api_event_create(data: CreateData, event_id=None): if event_id: event = await get_event(event_id) if not event: - return jsonable_encoder({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND + return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND if event.wallet != g.wallet.id: - return jsonable_encoder({"message": "Not your event."}), HTTPStatus.FORBIDDEN + return {"message": "Not your event."}, HTTPStatus.FORBIDDEN event = await update_event(event_id, **data) else: @@ -71,15 +71,15 @@ async def api_event_create(data: CreateData, event_id=None): return event._asdict(), HTTPStatus.CREATED -@events_ext.delete("/api/v1/events/") +@events_ext.delete("/api/v1/events/{event_id}") @api_check_wallet_key("invoice") async def api_form_delete(event_id): event = await get_event(event_id) if not event: - return jsonable_encoder({"message": "Event does not exist."}), HTTPStatus.NOT_FOUND + return {"message": "Event does not exist."}, HTTPStatus.NOT_FOUND if event.wallet != g.wallet.id: - return jsonable_encoder({"message": "Not your event."}), HTTPStatus.FORBIDDEN + return {"message": "Not your event."}, HTTPStatus.FORBIDDEN await delete_event(event_id) return "", HTTPStatus.NO_CONTENT @@ -105,11 +105,11 @@ class CreateTicketData(BaseModel): name: str = Query(...) email: str -@events_ext.post("/api/v1/tickets//") +@events_ext.post("/api/v1/tickets/{event_id}/{sats}") async def api_ticket_make_ticket(data: CreateTicketData, event_id, sats): event = await get_event(event_id) if not event: - return jsonable_encoder({"message": "Event does not exist."}), HTTPStatus.NOT_FOUND + return {"message": "Event does not exist."}, HTTPStatus.NOT_FOUND try: payment_hash, payment_request = await create_invoice( wallet_id=event.wallet, @@ -118,22 +118,19 @@ async def api_ticket_make_ticket(data: CreateTicketData, event_id, sats): extra={"tag": "events"}, ) except Exception as e: - return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR + return {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR ticket = await create_ticket( payment_hash=payment_hash, wallet=event.wallet, event=event_id, **data ) if not ticket: - return jsonable_encoder({"message": "Event could not be fetched."}), HTTPStatus.NOT_FOUND + return {"message": "Event could not be fetched."}, HTTPStatus.NOT_FOUND - return ( - jsonable_encoder({"payment_hash": payment_hash, "payment_request": payment_request}), - HTTPStatus.OK, - ) + return {"payment_hash": payment_hash, "payment_request": payment_request}, HTTPStatus.OK -@events_ext.get("/api/v1/tickets/") +@events_ext.get("/api/v1/tickets/{payment_hash}") async def api_ticket_send_ticket(payment_hash): ticket = await get_ticket(payment_hash) @@ -141,7 +138,7 @@ async def api_ticket_send_ticket(payment_hash): status = await check_invoice_status(ticket.wallet, payment_hash) is_paid = not status.pending except Exception: - return jsonable_encoder({"message": "Not paid."}), HTTPStatus.NOT_FOUND + return {"message": "Not paid."}, HTTPStatus.NOT_FOUND if is_paid: wallet = await get_wallet(ticket.wallet) @@ -149,21 +146,21 @@ async def api_ticket_send_ticket(payment_hash): await payment.set_pending(False) ticket = await set_ticket_paid(payment_hash=payment_hash) - return jsonable_encoder({"paid": True, "ticket_id": ticket.id}), HTTPStatus.OK + return {"paid": True, "ticket_id": ticket.id}, HTTPStatus.OK - return jsonable_encoder({"paid": False}), HTTPStatus.OK + return {"paid": False}, HTTPStatus.OK -@events_ext.delete("/api/v1/tickets/") +@events_ext.delete("/api/v1/tickets/{ticket_id}") @api_check_wallet_key("invoice") async def api_ticket_delete(ticket_id): ticket = await get_ticket(ticket_id) if not ticket: - return jsonable_encoder({"message": "Ticket does not exist."}), HTTPStatus.NOT_FOUND + return {"message": "Ticket does not exist."}, HTTPStatus.NOT_FOUND if ticket.wallet != g.wallet.id: - return jsonable_encoder({"message": "Not your ticket."}), HTTPStatus.FORBIDDEN + return {"message": "Not your ticket."}, HTTPStatus.FORBIDDEN await delete_ticket(ticket_id) return "", HTTPStatus.NO_CONTENT @@ -172,26 +169,23 @@ async def api_ticket_delete(ticket_id): # Event Tickets -@events_ext.get("/api/v1/eventtickets//") +@events_ext.get("/api/v1/eventtickets/{wallet_id}/{event_id]") async def api_event_tickets(wallet_id, event_id): return ([ticket._asdict() for ticket in await get_event_tickets(wallet_id=wallet_id, event_id=event_id)], HTTPStatus.OK, ) -@events_ext.get("/api/v1/register/ticket/") +@events_ext.get("/api/v1/register/ticket/{ticket_id}") async def api_event_register_ticket(ticket_id): ticket = await get_ticket(ticket_id) if not ticket: - return jsonable_encoder({"message": "Ticket does not exist."}), HTTPStatus.FORBIDDEN + return {"message": "Ticket does not exist."}, HTTPStatus.FORBIDDEN if not ticket.paid: - return jsonable_encoder({"message": "Ticket not paid for."}), HTTPStatus.FORBIDDEN + return {"message": "Ticket not paid for."}, HTTPStatus.FORBIDDEN if ticket.registered == True: - return jsonable_encoder({"message": "Ticket already registered"}), HTTPStatus.FORBIDDEN + return {"message": "Ticket already registered"}, HTTPStatus.FORBIDDEN - return ( - [ticket._asdict() for ticket in await reg_ticket(ticket_id)], - HTTPStatus.OK, - ) + return [ticket._asdict() for ticket in await reg_ticket(ticket_id)], HTTPStatus.OK diff --git a/lnbits/extensions/jukebox/views_api.py b/lnbits/extensions/jukebox/views_api.py index 7bee82719..4c5dc40af 100644 --- a/lnbits/extensions/jukebox/views_api.py +++ b/lnbits/extensions/jukebox/views_api.py @@ -40,7 +40,7 @@ async def api_get_jukeboxs(): ##################SPOTIFY AUTH##################### -@jukebox_ext.get("/api/v1/jukebox/spotify/cb/") +@jukebox_ext.get("/api/v1/jukebox/spotify/cb/{juke_id}") async def api_check_credentials_callbac(juke_id): sp_code = "" sp_access_token = "" @@ -69,7 +69,7 @@ async def api_check_credentials_callbac(juke_id): return "

Success!

You can close this window

" -@jukebox_ext.get("/api/v1/jukebox/") +@jukebox_ext.get("/api/v1/jukebox/{juke_id}") @api_check_wallet_key("admin") async def api_check_credentials_check(juke_id): jukebox = await get_jukebox(juke_id) @@ -89,7 +89,7 @@ class CreateData(BaseModel): price: Optional[str] = None @jukebox_ext.post("/api/v1/jukebox/") -@jukebox_ext.put("/api/v1/jukebox/") +@jukebox_ext.put("/api/v1/jukebox/{juke_id}") @api_check_wallet_key("admin") async def api_create_update_jukebox(data: CreateData, juke_id=None): if juke_id: @@ -100,7 +100,7 @@ async def api_create_update_jukebox(data: CreateData, juke_id=None): return jukebox._asdict(), HTTPStatus.CREATED -@jukebox_ext.delete("/api/v1/jukebox/") +@jukebox_ext.delete("/api/v1/jukebox/{juke_id}") @api_check_wallet_key("admin") async def api_delete_item(juke_id): await delete_jukebox(juke_id) @@ -120,7 +120,7 @@ async def api_delete_item(juke_id): @jukebox_ext.get( - "/api/v1/jukebox/jb/playlist//" + "/api/v1/jukebox/jb/playlist/{juke_id}/{sp_playlist}" ) async def api_get_jukebox_song(juke_id, sp_playlist, retry=False): try: @@ -210,7 +210,7 @@ async def api_get_token(juke_id): ######CHECK DEVICE -@jukebox_ext.get("/api/v1/jukebox/jb/") +@jukebox_ext.get("/api/v1/jukebox/jb/{juke_id}") async def api_get_jukebox_device_check(juke_id, retry=False): try: jukebox = await get_jukebox(juke_id) @@ -255,7 +255,7 @@ async def api_get_jukebox_device_check(juke_id, retry=False): ######GET INVOICE STUFF -@jukebox_ext.get("/api/v1/jukebox/jb/invoice//") +@jukebox_ext.get("/api/v1/jukebox/jb/invoice/{juke_id}/{song_id}") async def api_get_jukebox_invoice(juke_id, song_id): try: jukebox = await get_jukebox(juke_id) @@ -295,7 +295,7 @@ async def api_get_jukebox_invoice(juke_id, song_id): @jukebox_ext.get( - "/api/v1/jukebox/jb/checkinvoice//" + "/api/v1/jukebox/jb/checkinvoice/{pay_hash}/{juke_id}" ) async def api_get_jukebox_invoice_check(pay_hash, juke_id): try: @@ -320,7 +320,7 @@ async def api_get_jukebox_invoice_check(pay_hash, juke_id): @jukebox_ext.get( - "/api/v1/jukebox/jb/invoicep///" + "/api/v1/jukebox/jb/invoicep/{song_id}/{juke_id}/{pay_hash}" ) async def api_get_jukebox_invoice_paid(song_id, juke_id, pay_hash, retry=False): try: @@ -437,7 +437,7 @@ async def api_get_jukebox_invoice_paid(song_id, juke_id, pay_hash, retry=False): ############################GET TRACKS -@jukebox_ext.get("/api/v1/jukebox/jb/currently/") +@jukebox_ext.get("/api/v1/jukebox/jb/currently/{juke_id}") async def api_get_jukebox_currently(juke_id, retry=False): try: jukebox = await get_jukebox(juke_id) diff --git a/lnbits/extensions/livestream/views_api.py b/lnbits/extensions/livestream/views_api.py index c8816ac1c..222b1e53b 100644 --- a/lnbits/extensions/livestream/views_api.py +++ b/lnbits/extensions/livestream/views_api.py @@ -4,6 +4,11 @@ from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore from lnbits.decorators import api_check_wallet_key, api_validate_post_request +from fastapi import FastAPI, Query +from fastapi.encoders import jsonable_encoder +from fastapi.responses import JSONResponse +from pydantic import BaseModel + from . import livestream_ext from .crud import ( get_or_create_livestream_by_wallet, @@ -18,7 +23,7 @@ from .crud import ( ) -@livestream_ext.route("/api/v1/livestream", methods=["GET"]) +@livestream_ext.get("/api/v1/livestream") @api_check_wallet_key("invoice") async def api_livestream_from_wallet(): ls = await get_or_create_livestream_by_wallet(g.wallet.id) @@ -26,8 +31,7 @@ async def api_livestream_from_wallet(): producers = await get_producers(ls.id) try: - return ( - jsonify( + return { **ls._asdict(), **{ @@ -39,21 +43,19 @@ async def api_livestream_from_wallet(): "producers": [producer._asdict() for producer in producers], }, } - ), - HTTPStatus.OK, - ) + , + HTTPStatus.OK + except LnurlInvalidUrl: - return ( - jsonify( + return { "message": "LNURLs need to be delivered over a publically accessible `https` domain or Tor." } - ), - HTTPStatus.UPGRADE_REQUIRED, - ) + , + HTTPStatus.UPGRADE_REQUIRED -@livestream_ext.route("/api/v1/livestream/track/", methods=["PUT"]) +@livestream_ext.put("/api/v1/livestream/track/{track_id}") @api_check_wallet_key("invoice") async def api_update_track(track_id): try: @@ -68,7 +70,7 @@ async def api_update_track(track_id): return "", HTTPStatus.NO_CONTENT -@livestream_ext.route("/api/v1/livestream/fee/", methods=["PUT"]) +@livestream_ext.put("/api/v1/livestream/fee/{fee_pct}") @api_check_wallet_key("invoice") async def api_update_fee(fee_pct): ls = await get_or_create_livestream_by_wallet(g.wallet.id) @@ -76,33 +78,40 @@ async def api_update_fee(fee_pct): return "", HTTPStatus.NO_CONTENT -@livestream_ext.route("/api/v1/livestream/tracks", methods=["POST"]) -@livestream_ext.route("/api/v1/livestream/tracks/", methods=["PUT"]) +class CreateData(BaseModel): + name: str + download_url: str = Query(None) + price_msat: int = Query(None, ge=0) + producer_id: int #missing the exclude thing + producer_name: str #missing the exclude thing + +@livestream_ext.post("/api/v1/livestream/tracks") +@livestream_ext.put("/api/v1/livestream/tracks/{id}") @api_check_wallet_key("invoice") -@api_validate_post_request( - schema={ - "name": {"type": "string", "empty": False, "required": True}, - "download_url": {"type": "string", "empty": False, "required": False}, - "price_msat": {"type": "number", "min": 0, "required": False}, - "producer_id": { - "type": "number", - "required": True, - "excludes": "producer_name", - }, - "producer_name": { - "type": "string", - "required": True, - "excludes": "producer_id", - }, - } -) -async def api_add_track(id=None): +# @api_validate_post_request( +# schema={ +# "name": {"type": "string", "empty": False, "required": True}, +# "download_url": {"type": "string", "empty": False, "required": False}, +# "price_msat": {"type": "number", "min": 0, "required": False}, +# "producer_id": { +# "type": "number", +# "required": True, +# "excludes": "producer_name", +# }, +# "producer_name": { +# "type": "string", +# "required": True, +# "excludes": "producer_id", +# }, +# } +# ) +async def api_add_track(data: CreateData, id=None): ls = await get_or_create_livestream_by_wallet(g.wallet.id) - if "producer_id" in g.data: - p_id = g.data["producer_id"] - elif "producer_name" in g.data: - p_id = await add_producer(ls.id, g.data["producer_name"]) + if "producer_id" in data: + p_id = data["producer_id"] + elif "producer_name" in data: + p_id = await add_producer(ls.id, data["producer_name"]) else: raise TypeError("need either producer_id or producer_name arguments") @@ -110,24 +119,24 @@ async def api_add_track(id=None): await update_track( ls.id, id, - g.data["name"], - g.data.get("download_url"), - g.data.get("price_msat", 0), + data["name"], + data.get("download_url"), + data.get("price_msat", 0), p_id, ) return "", HTTPStatus.OK else: await add_track( ls.id, - g.data["name"], - g.data.get("download_url"), - g.data.get("price_msat", 0), + data["name"], + data.get("download_url"), + data.get("price_msat", 0), p_id, ) return "", HTTPStatus.CREATED -@livestream_ext.route("/api/v1/livestream/tracks/", methods=["DELETE"]) +@livestream_ext.delete("/api/v1/livestream/tracks/{track_id}") @api_check_wallet_key("invoice") async def api_delete_track(track_id): ls = await get_or_create_livestream_by_wallet(g.wallet.id) From 0806ccfbbd335bf7638cb6edf89b28a40a62ba32 Mon Sep 17 00:00:00 2001 From: Stefan Stammberger Date: Mon, 23 Aug 2021 18:51:17 +0200 Subject: [PATCH 2/2] fix: missing static file serving folder --- lnbits/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lnbits/app.py b/lnbits/app.py index a686d5f7c..b61880b64 100644 --- a/lnbits/app.py +++ b/lnbits/app.py @@ -38,6 +38,7 @@ async def create_app(config_object="lnbits.settings") -> FastAPI: """ app = FastAPI() app.mount("/static", StaticFiles(directory="lnbits/static"), name="static") + app.mount("/core/static", StaticFiles(directory="lnbits/core/static"), name="core_static") origins = [ "http://localhost",