From 254fa67859eae877d268ce9f114be105ded71c80 Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Wed, 27 Jul 2022 22:49:23 +0100 Subject: [PATCH 1/5] allow for decimals in fiat unit --- lnbits/extensions/offlineshop/crud.py | 24 ++++++++++++------- lnbits/extensions/offlineshop/migrations.py | 10 ++++++++ lnbits/extensions/offlineshop/models.py | 11 ++++++++- .../extensions/offlineshop/static/js/index.js | 3 ++- lnbits/extensions/offlineshop/views_api.py | 16 ++++++++++--- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/lnbits/extensions/offlineshop/crud.py b/lnbits/extensions/offlineshop/crud.py index bc4f3f14a..896842d80 100644 --- a/lnbits/extensions/offlineshop/crud.py +++ b/lnbits/extensions/offlineshop/crud.py @@ -52,14 +52,20 @@ async def set_method(shop: int, method: str, wordlist: str = "") -> Optional[Sho async def add_item( - shop: int, name: str, description: str, image: Optional[str], price: int, unit: str + shop: int, + name: str, + description: str, + image: Optional[str], + price: int, + unit: str, + fiat_base_multiplier: int, ) -> int: result = await db.execute( """ - INSERT INTO offlineshop.items (shop, name, description, image, price, unit) - VALUES (?, ?, ?, ?, ?, ?) + INSERT INTO offlineshop.items (shop, name, description, image, price, unit, fiat_base_multiplier) + VALUES (?, ?, ?, ?, ?, ?, ?) """, - (shop, name, description, image, price, unit), + (shop, name, description, image, price, unit, fiat_base_multiplier), ) return result._result_proxy.lastrowid @@ -72,6 +78,7 @@ async def update_item( image: Optional[str], price: int, unit: str, + fiat_base_multiplier: int, ) -> int: await db.execute( """ @@ -80,10 +87,11 @@ async def update_item( description = ?, image = ?, price = ?, - unit = ? + unit = ?, + fiat_base_multiplier = ? WHERE shop = ? AND id = ? """, - (name, description, image, price, unit, shop, item_id), + (name, description, image, price, unit, fiat_base_multiplier, shop, item_id), ) return item_id @@ -92,12 +100,12 @@ async def get_item(id: int) -> Optional[Item]: row = await db.fetchone( "SELECT * FROM offlineshop.items WHERE id = ? LIMIT 1", (id,) ) - return Item(**dict(row)) if row else None + return Item.from_row(row) if row else None async def get_items(shop: int) -> List[Item]: rows = await db.fetchall("SELECT * FROM offlineshop.items WHERE shop = ?", (shop,)) - return [Item(**dict(row)) for row in rows] + return [Item.from_row(row) for row in rows] async def delete_item_from_shop(shop: int, item_id: int): diff --git a/lnbits/extensions/offlineshop/migrations.py b/lnbits/extensions/offlineshop/migrations.py index f7c2dfec8..84aea27e2 100644 --- a/lnbits/extensions/offlineshop/migrations.py +++ b/lnbits/extensions/offlineshop/migrations.py @@ -27,3 +27,13 @@ async def m001_initial(db): ); """ ) + + +async def m002_fiat_base_multiplier(db): + """ + Store the multiplier for fiat prices. We store the price in cents and + remember to multiply by 100 when we use it to convert to Dollars. + """ + await db.execute( + "ALTER TABLE offlineshop.items ADD COLUMN fiat_base_multiplier INTEGER DEFAULT 1;" + ) diff --git a/lnbits/extensions/offlineshop/models.py b/lnbits/extensions/offlineshop/models.py index 0128fdb84..ca5c73a55 100644 --- a/lnbits/extensions/offlineshop/models.py +++ b/lnbits/extensions/offlineshop/models.py @@ -2,6 +2,7 @@ import base64 import hashlib import json from collections import OrderedDict +from sqlite3 import Row from typing import Dict, List, Optional from lnurl import encode as lnurl_encode # type: ignore @@ -87,8 +88,16 @@ class Item(BaseModel): description: str image: Optional[str] enabled: bool - price: int + price: float unit: str + fiat_base_multiplier: int + + @classmethod + def from_row(cls, row: Row) -> "Item": + data = dict(row) + if data["unit"] != "sat" and data["fiat_base_multiplier"]: + data["price"] /= data["fiat_base_multiplier"] + return cls(**data) def lnurl(self, req: Request) -> str: return lnurl_encode(req.url_for("offlineshop.lnurl_response", item_id=self.id)) diff --git a/lnbits/extensions/offlineshop/static/js/index.js b/lnbits/extensions/offlineshop/static/js/index.js index 00e932416..c03906093 100644 --- a/lnbits/extensions/offlineshop/static/js/index.js +++ b/lnbits/extensions/offlineshop/static/js/index.js @@ -124,7 +124,8 @@ new Vue({ description, image, price, - unit + unit, + fiat_base_multiplier: unit == 'sat' ? 1 : 100 } try { diff --git a/lnbits/extensions/offlineshop/views_api.py b/lnbits/extensions/offlineshop/views_api.py index 5ced43516..9d7cc97d2 100644 --- a/lnbits/extensions/offlineshop/views_api.py +++ b/lnbits/extensions/offlineshop/views_api.py @@ -1,6 +1,7 @@ from http import HTTPStatus from typing import Optional +from fastapi import Query from fastapi.params import Depends from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl from pydantic.main import BaseModel @@ -34,7 +35,6 @@ async def api_shop_from_wallet( ): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) items = await get_items(shop.id) - try: return { **shop.dict(), @@ -51,8 +51,9 @@ class CreateItemsData(BaseModel): name: str description: str image: Optional[str] - price: int + price: float unit: str + fiat_base_multiplier: int = Query(100, ge=1) @offlineshop_ext.post("/api/v1/offlineshop/items") @@ -61,9 +62,17 @@ async def api_add_or_update_item( data: CreateItemsData, item_id=None, wallet: WalletTypeInfo = Depends(get_key_type) ): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + if data.unit != "sat": + data.price = data.price * 100 if item_id == None: + await add_item( - shop.id, data.name, data.description, data.image, data.price, data.unit + shop.id, + data.name, + data.description, + data.image, + data.price, + data.unit, ) return HTMLResponse(status_code=HTTPStatus.CREATED) else: @@ -75,6 +84,7 @@ async def api_add_or_update_item( data.image, data.price, data.unit, + data.fiat_base_multiplier, ) From 85db59c3593b845bbbf9c1dc4c6299a49416d3a7 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 28 Jul 2022 10:32:17 +0100 Subject: [PATCH 2/5] make format --- lnbits/extensions/events/views_api.py | 3 ++- .../lnurlpayout/templates/lnurlpayout/_api_docs.html | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lnbits/extensions/events/views_api.py b/lnbits/extensions/events/views_api.py index 45ee4de05..56e6b06ca 100644 --- a/lnbits/extensions/events/views_api.py +++ b/lnbits/extensions/events/views_api.py @@ -133,7 +133,8 @@ async def api_ticket_send_ticket(event_id, payment_hash, data: CreateTicket): if not ticket: raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail=f"Event could not be fetched." + status_code=HTTPStatus.NOT_FOUND, + detail=f"Event could not be fetched.", ) return {"paid": True, "ticket_id": ticket.id} diff --git a/lnbits/extensions/lnurlpayout/templates/lnurlpayout/_api_docs.html b/lnbits/extensions/lnurlpayout/templates/lnurlpayout/_api_docs.html index 4f921bb57..afe24c423 100644 --- a/lnbits/extensions/lnurlpayout/templates/lnurlpayout/_api_docs.html +++ b/lnbits/extensions/lnurlpayout/templates/lnurlpayout/_api_docs.html @@ -4,12 +4,7 @@ label="API info" :content-inset-level="0.5" > - + @@ -38,7 +33,6 @@ expand-separator label="Create a lnurlpayout" > - Date: Thu, 28 Jul 2022 11:08:15 +0100 Subject: [PATCH 3/5] add missing param in add item --- lnbits/extensions/offlineshop/views_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lnbits/extensions/offlineshop/views_api.py b/lnbits/extensions/offlineshop/views_api.py index 9d7cc97d2..1bd045dd9 100644 --- a/lnbits/extensions/offlineshop/views_api.py +++ b/lnbits/extensions/offlineshop/views_api.py @@ -73,6 +73,7 @@ async def api_add_or_update_item( data.image, data.price, data.unit, + data.fiat_base_multiplier, ) return HTMLResponse(status_code=HTTPStatus.CREATED) else: From 56cac668caa6aa3473eca522b0e68f01fb5870cc Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Thu, 28 Jul 2022 11:08:55 +0100 Subject: [PATCH 4/5] add mock data and fix conv --- tests/data/mock_data.zip | Bin 24900 -> 50915 bytes tools/conv.py | 11 +++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/data/mock_data.zip b/tests/data/mock_data.zip index 0480adc27373df73d4d3a352ee4bbe5b40a7fc41..4953f53172afb3dc21a9e1fdaae5f708dd0f219e 100644 GIT binary patch delta 28623 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

W{=fX1o^}Zy{{zlKc7%`sMo-}!Fg&$_F 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 E1ENa7L;wH) delta 2435 zcmZ{l3pCVO9LN7NBgSkLrlu(QdqkopalB%@jv68qCC^Yui9A-%S*1vI)^_zoR6|Bn z(v&pbGnu2dR4Yj$WmhVkO0Vg`-Yfj4o$bzH_6er7NkJ}XN)*@3Nr!q5Qo|ufpWV!l?H>17@j%pW?AlDn#xH*FKUv4^~ zw@imehCwiAv}eR1y&vq3>j7mwXQ&4EF$AGOM3GLY1?#1dA$Ryv{8wu^?>-aJ_8Ryg zPO4xfnJmZY5_(IGOp$kAb9GMk$wfhUmuc+yQ}4KhT8HrkWYu_)PkO9etn&yi&vZMo zYFw2aE+54>2aK6~sAhc&-xvh*@#B-VAk=!9I8y5uhA-$wF*wNPj)*~Xq4V6IW!P?9 z?fZEKrUM4*HK{6?QhGs0SUSMZGB}SMH#IZqSQj@>vOb!g=4FBFKPit6atvCTS#kH^ z0guG~UbA}7M)u?T_sawi*KEj@=nu`wwMvk9_%GgTu9`c$)39~lt4Q1Tw*I$=Ua29@!XhXF<71Oi$}`r>Ac1~NQ zSCubsMc@377H_O9B1@L6ZMn7XNpz)Za=X?{rO1${25Fo#d(9-aL9JU}yoJO#Ro%PK zW>d!t8|lz*#;i4E>wE$k5?ysqP7m){OAC9@+e8$p?R~ke_`&)sfs3Ye+bO?xEp3f| z)bZymsi%+uCpNKsnUP~& zwfvn?p{VweNzdD)!i4CmRNv;+_6dC^Px9L$n&LArm1NCgu{&5r{m0@w-*b|t?<>~6 z*(J;fKdz9=yJ2$FcA@zUZwP$lft%`J)`lq>Q9$%aF?#hAXd%`^5-T2gF zRQNeNE_?EwaLqX)y}^k#7R^Pwq-JWp&Nq`zcqN)hu^n6|2`w*6&89HeN%DNyNm}VU zw8r?m@9_6=O2VG7!tCl)v&fvvzK*mT!^0t_%g45@u{dD*u<+28i=l`6wz*7be#=(- zrs3tTMDLr&916>U|b5D_1*Epk9Hj zUL?WgpK+$ZS_*hjd|m-@Oj&OGI0tuN_nZ!EX_MGSV0pHT1k2Pjw#=?n&WZ6uKw5kr zx^U-S8$-UGXN^k>DtLSp5;gff9)&`OhKPolLvYFb0>qh#>b?cbaU}$2RO*5_pO}p{ zigH{j!R;(7MQxw+sk18qMe#%E#MLEW38IkRls>yJ26B2;gx<9)?TB-ZN^v}axKPpMBVH=gL@8fafl<4=@fWrf@76IBr5n&iIcv8X;rT9e@GQh5`okz2Lp7a zqU%leLes!>pv3pVP0iQBzyU3D;7~(_C-tgvidY*11=^OQE9uoZX+Pjq+ri!VS`9E+ zPXTc1X=Fb=K&!Ebi{5$+5L!bc2|>)ryrc%FteA~~HwI%8EF;D*guzC@taTU>!&Mn` zF>Gy0V#tQrh^VA6uwbFlsMUM5IAzOR4D=XVjILyvGJsnhO@TcR!+--*A8fDFf-2ff z1}Lqgk)8u#od=v#>v78E1<*Qk;pjmbr%4|{X1%S^NZMdxP~VrW9@zKC+{C!40p_5; zUQ6~8m^!Lho5uk5A{yD-61a(AUJey7Kt7zGwg%@!C?zjNIN8MxsEAS0+{HMV=Kx~G z&T!IS%$PW4gPU6G1X{$Na9RI4PC4j|fqI_xsEtgx65xsf4u33*1J`l#Og2z!SOgEm zm&xkvb_ekdHgK8WfRk5vfIAJ2aH1x`$(_r9xr7BLi4vUB?t_8S3JY*sGLhyApGdDS Ga^+t_vhL#m diff --git a/tools/conv.py b/tools/conv.py index 99bb54f02..ba504b317 100644 --- a/tools/conv.py +++ b/tools/conv.py @@ -1,9 +1,8 @@ -import psycopg2 -import sqlite3 -import os import argparse +import os +import sqlite3 - +import psycopg2 from environs import Env # type: ignore env = Env() @@ -540,8 +539,8 @@ def migrate_ext(sqlite_db_file, schema, ignore_missing=True): # ITEMS res = sq.execute("SELECT * FROM items;") q = f""" - INSERT INTO offlineshop.items (shop, id, name, description, image, enabled, price, unit) - VALUES (%s, %s, %s, %s, %s, %s::boolean, %s, %s); + INSERT INTO offlineshop.items (shop, id, name, description, image, enabled, price, unit, fiat_base_multiplier) + VALUES (%s, %s, %s, %s, %s, %s::boolean, %s, %s, %s); """ items = res.fetchall() insert_to_pg(q, items) From a57850f39134d001dd2b80b3e6e3df8416bc559c Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Thu, 28 Jul 2022 12:09:20 +0100 Subject: [PATCH 5/5] update offline dbversion in mock data --- tests/data/mock_data.zip | Bin 50915 -> 50920 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/data/mock_data.zip b/tests/data/mock_data.zip index 4953f53172afb3dc21a9e1fdaae5f708dd0f219e..89cafa3f928386972c6bc9d274157fed5d27b767 100644 GIT binary patch delta 5507 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 R{(h5IjSd7##{6l2{vQ*6nyUZ+