diff --git a/lnbits/extensions/shop/README.md b/lnbits/extensions/market/README.md similarity index 54% rename from lnbits/extensions/shop/README.md rename to lnbits/extensions/market/README.md index 86ac9ed9..22d38e0d 100644 --- a/lnbits/extensions/shop/README.md +++ b/lnbits/extensions/market/README.md @@ -1,7 +1,7 @@ -

Shop

+

Market

A movable market stand

Make a list of products to sell, point the list to an relay (or many), stack sats. -Shop is a movable market stand, for anon transactions. You then give permission for an relay to list those products. Delivery addresses are sent through the Lightning Network. +Market is a movable market stand, for anon transactions. You then give permission for an relay to list those products. Delivery addresses are sent through the Lightning Network.

API endpoints

diff --git a/lnbits/extensions/shop/__init__.py b/lnbits/extensions/market/__init__.py similarity index 59% rename from lnbits/extensions/shop/__init__.py rename to lnbits/extensions/market/__init__.py index 8c85d8b6..3795ec73 100644 --- a/lnbits/extensions/shop/__init__.py +++ b/lnbits/extensions/market/__init__.py @@ -7,20 +7,20 @@ from lnbits.db import Database from lnbits.helpers import template_renderer from lnbits.tasks import catch_everything_and_restart -db = Database("ext_shop") +db = Database("ext_market") -shop_ext: APIRouter = APIRouter(prefix="/shop", tags=["shop"]) +market_ext: APIRouter = APIRouter(prefix="/market", tags=["market"]) -shop_static_files = [ +market_static_files = [ { - "path": "/shop/static", - "app": StaticFiles(directory="lnbits/extensions/shop/static"), - "name": "shop_static", + "path": "/market/static", + "app": StaticFiles(directory="lnbits/extensions/market/static"), + "name": "market_static", } ] # if 'nostradmin' not in LNBITS_ADMIN_EXTENSIONS: -# @shop_ext.get("/", response_class=HTMLResponse) +# @market_ext.get("/", response_class=HTMLResponse) # async def index(request: Request): # return template_renderer().TemplateResponse( # "error.html", {"request": request, "err": "Ask system admin to enable NostrAdmin!"} @@ -28,9 +28,9 @@ shop_static_files = [ # else: -def shop_renderer(): - return template_renderer(["lnbits/extensions/shop/templates"]) - # return template_renderer(["lnbits/extensions/shop/templates"]) +def market_renderer(): + return template_renderer(["lnbits/extensions/market/templates"]) + # return template_renderer(["lnbits/extensions/market/templates"]) from .tasks import wait_for_paid_invoices @@ -38,6 +38,6 @@ from .views import * # noqa from .views_api import * # noqa -def shop_start(): +def market_start(): loop = asyncio.get_event_loop() loop.create_task(catch_everything_and_restart(wait_for_paid_invoices)) diff --git a/lnbits/extensions/market/config.json b/lnbits/extensions/market/config.json new file mode 100644 index 00000000..b540189e --- /dev/null +++ b/lnbits/extensions/market/config.json @@ -0,0 +1,6 @@ +{ + "name": "Market", + "short_description": "Webmarket on LNbits", + "tile": "/market/static/images/bitcoin-shop.png", + "contributors": ["benarc", "talvasconcelos"] +} diff --git a/lnbits/extensions/shop/crud.py b/lnbits/extensions/market/crud.py similarity index 54% rename from lnbits/extensions/shop/crud.py rename to lnbits/extensions/market/crud.py index c58dfb3e..6d82b354 100644 --- a/lnbits/extensions/shop/crud.py +++ b/lnbits/extensions/market/crud.py @@ -17,7 +17,7 @@ from .models import ( OrderDetail, Orders, Products, - ShopSettings, + MarketSettings, Stalls, Zones, createOrder, @@ -30,11 +30,11 @@ from .models import ( ###Products -async def create_shop_product(data: createProduct) -> Products: +async def create_market_product(data: createProduct) -> Products: product_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO shop.products (id, stall, product, categories, description, image, price, quantity) + INSERT INTO market.products (id, stall, product, categories, description, image, price, quantity) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, ( @@ -48,55 +48,55 @@ async def create_shop_product(data: createProduct) -> Products: data.quantity, ), ) - product = await get_shop_product(product_id) + product = await get_market_product(product_id) assert product, "Newly created product couldn't be retrieved" return product -async def update_shop_product(product_id: str, **kwargs) -> Optional[Products]: +async def update_market_product(product_id: str, **kwargs) -> Optional[Products]: q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) await db.execute( - f"UPDATE shop.products SET {q} WHERE id = ?", + f"UPDATE market.products SET {q} WHERE id = ?", (*kwargs.values(), product_id), ) - row = await db.fetchone("SELECT * FROM shop.products WHERE id = ?", (product_id,)) + row = await db.fetchone("SELECT * FROM market.products WHERE id = ?", (product_id,)) return Products(**row) if row else None -async def get_shop_product(product_id: str) -> Optional[Products]: - row = await db.fetchone("SELECT * FROM shop.products WHERE id = ?", (product_id,)) +async def get_market_product(product_id: str) -> Optional[Products]: + row = await db.fetchone("SELECT * FROM market.products WHERE id = ?", (product_id,)) return Products(**row) if row else None -async def get_shop_products(stall_ids: Union[str, List[str]]) -> List[Products]: +async def get_market_products(stall_ids: Union[str, List[str]]) -> List[Products]: if isinstance(stall_ids, str): stall_ids = [stall_ids] - # with open_ext_db("shop") as db: + # with open_ext_db("market") as db: q = ",".join(["?"] * len(stall_ids)) rows = await db.fetchall( f""" - SELECT * FROM shop.products WHERE stall IN ({q}) + SELECT * FROM market.products WHERE stall IN ({q}) """, (*stall_ids,), ) return [Products(**row) for row in rows] -async def delete_shop_product(product_id: str) -> None: - await db.execute("DELETE FROM shop.products WHERE id = ?", (product_id,)) +async def delete_market_product(product_id: str) -> None: + await db.execute("DELETE FROM market.products WHERE id = ?", (product_id,)) ###zones -async def create_shop_zone(user, data: createZones) -> Zones: +async def create_market_zone(user, data: createZones) -> Zones: zone_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO shop.zones ( + INSERT INTO market.zones ( id, "user", cost, @@ -108,43 +108,43 @@ async def create_shop_zone(user, data: createZones) -> Zones: (zone_id, user, data.cost, data.countries.lower()), ) - zone = await get_shop_zone(zone_id) + zone = await get_market_zone(zone_id) assert zone, "Newly created zone couldn't be retrieved" return zone -async def update_shop_zone(zone_id: str, **kwargs) -> Optional[Zones]: +async def update_market_zone(zone_id: str, **kwargs) -> Optional[Zones]: q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) await db.execute( - f"UPDATE shop.zones SET {q} WHERE id = ?", + f"UPDATE market.zones SET {q} WHERE id = ?", (*kwargs.values(), zone_id), ) - row = await db.fetchone("SELECT * FROM shop.zones WHERE id = ?", (zone_id,)) + row = await db.fetchone("SELECT * FROM market.zones WHERE id = ?", (zone_id,)) return Zones(**row) if row else None -async def get_shop_zone(zone_id: str) -> Optional[Zones]: - row = await db.fetchone("SELECT * FROM shop.zones WHERE id = ?", (zone_id,)) +async def get_market_zone(zone_id: str) -> Optional[Zones]: + row = await db.fetchone("SELECT * FROM market.zones WHERE id = ?", (zone_id,)) return Zones(**row) if row else None -async def get_shop_zones(user: str) -> List[Zones]: - rows = await db.fetchall('SELECT * FROM shop.zones WHERE "user" = ?', (user,)) +async def get_market_zones(user: str) -> List[Zones]: + rows = await db.fetchall('SELECT * FROM market.zones WHERE "user" = ?', (user,)) return [Zones(**row) for row in rows] -async def delete_shop_zone(zone_id: str) -> None: - await db.execute("DELETE FROM shop.zones WHERE id = ?", (zone_id,)) +async def delete_market_zone(zone_id: str) -> None: + await db.execute("DELETE FROM market.zones WHERE id = ?", (zone_id,)) ###Stalls -async def create_shop_stall(data: createStalls) -> Stalls: +async def create_market_stall(data: createStalls) -> Stalls: stall_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO shop.stalls ( + INSERT INTO market.stalls ( id, wallet, name, @@ -166,56 +166,56 @@ async def create_shop_stall(data: createStalls) -> Stalls: ), ) - stall = await get_shop_stall(stall_id) + stall = await get_market_stall(stall_id) assert stall, "Newly created stall couldn't be retrieved" return stall -async def update_shop_stall(stall_id: str, **kwargs) -> Optional[Stalls]: +async def update_market_stall(stall_id: str, **kwargs) -> Optional[Stalls]: q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) await db.execute( - f"UPDATE shop.stalls SET {q} WHERE id = ?", + f"UPDATE market.stalls SET {q} WHERE id = ?", (*kwargs.values(), stall_id), ) - row = await db.fetchone("SELECT * FROM shop.stalls WHERE id = ?", (stall_id,)) + row = await db.fetchone("SELECT * FROM market.stalls WHERE id = ?", (stall_id,)) return Stalls(**row) if row else None -async def get_shop_stall(stall_id: str) -> Optional[Stalls]: - row = await db.fetchone("SELECT * FROM shop.stalls WHERE id = ?", (stall_id,)) +async def get_market_stall(stall_id: str) -> Optional[Stalls]: + row = await db.fetchone("SELECT * FROM market.stalls WHERE id = ?", (stall_id,)) return Stalls(**row) if row else None -async def get_shop_stalls(wallet_ids: Union[str, List[str]]) -> List[Stalls]: +async def get_market_stalls(wallet_ids: Union[str, List[str]]) -> List[Stalls]: q = ",".join(["?"] * len(wallet_ids)) rows = await db.fetchall( - f"SELECT * FROM shop.stalls WHERE wallet IN ({q})", (*wallet_ids,) + f"SELECT * FROM market.stalls WHERE wallet IN ({q})", (*wallet_ids,) ) return [Stalls(**row) for row in rows] -async def get_shop_stalls_by_ids(stall_ids: Union[str, List[str]]) -> List[Stalls]: +async def get_market_stalls_by_ids(stall_ids: Union[str, List[str]]) -> List[Stalls]: q = ",".join(["?"] * len(stall_ids)) rows = await db.fetchall( - f"SELECT * FROM shop.stalls WHERE id IN ({q})", (*stall_ids,) + f"SELECT * FROM market.stalls WHERE id IN ({q})", (*stall_ids,) ) return [Stalls(**row) for row in rows] -async def delete_shop_stall(stall_id: str) -> None: - await db.execute("DELETE FROM shop.stalls WHERE id = ?", (stall_id,)) +async def delete_market_stall(stall_id: str) -> None: + await db.execute("DELETE FROM market.stalls WHERE id = ?", (stall_id,)) ###Orders -async def create_shop_order(data: createOrder, invoiceid: str): +async def create_market_order(data: createOrder, invoiceid: str): returning = "" if db.type == SQLITE else "RETURNING ID" method = db.execute if db.type == SQLITE else db.fetchone result = await (method)( f""" - INSERT INTO shop.orders (wallet, shippingzone, address, email, total, invoiceid, paid, shipped) + INSERT INTO market.orders (wallet, shippingzone, address, email, total, invoiceid, paid, shipped) VALUES (?, ?, ?, ?, ?, ?, ?, ?) {returning} """, @@ -236,12 +236,12 @@ async def create_shop_order(data: createOrder, invoiceid: str): return result[0] -async def create_shop_order_details(order_id: str, data: List[createOrderDetails]): +async def create_market_order_details(order_id: str, data: List[createOrderDetails]): for item in data: item_id = urlsafe_short_hash() await db.execute( """ - INSERT INTO shop.order_details (id, order_id, product_id, quantity) + INSERT INTO market.order_details (id, order_id, product_id, quantity) VALUES (?, ?, ?, ?) """, ( @@ -251,34 +251,34 @@ async def create_shop_order_details(order_id: str, data: List[createOrderDetails item.quantity, ), ) - order_details = await get_shop_order_details(order_id) + order_details = await get_market_order_details(order_id) return order_details -async def get_shop_order_details(order_id: str) -> List[OrderDetail]: +async def get_market_order_details(order_id: str) -> List[OrderDetail]: rows = await db.fetchall( - f"SELECT * FROM shop.order_details WHERE order_id = ?", (order_id,) + f"SELECT * FROM market.order_details WHERE order_id = ?", (order_id,) ) return [OrderDetail(**row) for row in rows] -async def get_shop_order(order_id: str) -> Optional[Orders]: - row = await db.fetchone("SELECT * FROM shop.orders WHERE id = ?", (order_id,)) +async def get_market_order(order_id: str) -> Optional[Orders]: + row = await db.fetchone("SELECT * FROM market.orders WHERE id = ?", (order_id,)) return Orders(**row) if row else None -async def get_shop_order_invoiceid(invoice_id: str) -> Optional[Orders]: +async def get_market_order_invoiceid(invoice_id: str) -> Optional[Orders]: row = await db.fetchone( - "SELECT * FROM shop.orders WHERE invoiceid = ?", (invoice_id,) + "SELECT * FROM market.orders WHERE invoiceid = ?", (invoice_id,) ) return Orders(**row) if row else None -async def set_shop_order_paid(payment_hash: str): +async def set_market_order_paid(payment_hash: str): await db.execute( """ - UPDATE shop.orders + UPDATE market.orders SET paid = true WHERE invoiceid = ? """, @@ -286,10 +286,10 @@ async def set_shop_order_paid(payment_hash: str): ) -async def set_shop_order_pubkey(payment_hash: str, pubkey: str): +async def set_market_order_pubkey(payment_hash: str, pubkey: str): await db.execute( """ - UPDATE shop.orders + UPDATE market.orders SET pubkey = ? WHERE invoiceid = ? """, @@ -300,7 +300,7 @@ async def set_shop_order_pubkey(payment_hash: str, pubkey: str): ) -async def update_shop_product_stock(products): +async def update_market_product_stock(products): q = "\n".join( [f"""WHEN id='{p.product_id}' THEN quantity - {p.quantity}""" for p in products] @@ -309,7 +309,7 @@ async def update_shop_product_stock(products): await db.execute( f""" - UPDATE shop.products + UPDATE market.products SET quantity=(CASE {q} END) @@ -319,51 +319,51 @@ async def update_shop_product_stock(products): ) -async def get_shop_orders(wallet_ids: Union[str, List[str]]) -> List[Orders]: +async def get_market_orders(wallet_ids: Union[str, List[str]]) -> List[Orders]: if isinstance(wallet_ids, str): wallet_ids = [wallet_ids] q = ",".join(["?"] * len(wallet_ids)) rows = await db.fetchall( - f"SELECT * FROM shop.orders WHERE wallet IN ({q})", (*wallet_ids,) + f"SELECT * FROM market.orders WHERE wallet IN ({q})", (*wallet_ids,) ) # return [Orders(**row) for row in rows] -async def delete_shop_order(order_id: str) -> None: - await db.execute("DELETE FROM shop.orders WHERE id = ?", (order_id,)) +async def delete_market_order(order_id: str) -> None: + await db.execute("DELETE FROM market.orders WHERE id = ?", (order_id,)) ### Market/Marketplace -async def get_shop_markets(user: str) -> List[Market]: - rows = await db.fetchall("SELECT * FROM shop.markets WHERE usr = ?", (user,)) +async def get_market_markets(user: str) -> List[Market]: + rows = await db.fetchall("SELECT * FROM market.markets WHERE usr = ?", (user,)) return [Market(**row) for row in rows] -async def get_shop_market(market_id: str) -> Optional[Market]: - row = await db.fetchone("SELECT * FROM shop.markets WHERE id = ?", (market_id,)) +async def get_market_market(market_id: str) -> Optional[Market]: + row = await db.fetchone("SELECT * FROM market.markets WHERE id = ?", (market_id,)) return Market(**row) if row else None -async def get_shop_market_stalls(market_id: str): +async def get_market_market_stalls(market_id: str): rows = await db.fetchall( - "SELECT * FROM shop.market_stalls WHERE marketid = ?", (market_id,) + "SELECT * FROM market.market_stalls WHERE marketid = ?", (market_id,) ) ids = [row["stallid"] for row in rows] - return await get_shop_stalls_by_ids(ids) + return await get_market_stalls_by_ids(ids) -async def create_shop_market(data: CreateMarket): +async def create_market_market(data: CreateMarket): market_id = urlsafe_short_hash() await db.execute( """ - INSERT INTO shop.markets (id, usr, name) + INSERT INTO market.markets (id, usr, name) VALUES (?, ?, ?) """, ( @@ -372,18 +372,18 @@ async def create_shop_market(data: CreateMarket): data.name, ), ) - market = await get_shop_market(market_id) + market = await get_market_market(market_id) assert market, "Newly created market couldn't be retrieved" return market -async def create_shop_market_stalls(market_id: str, data: List[str]): +async def create_market_market_stalls(market_id: str, data: List[str]): for stallid in data: id = urlsafe_short_hash() await db.execute( """ - INSERT INTO shop.market_stalls (id, marketid, stallid) + INSERT INTO market.market_stalls (id, marketid, stallid) VALUES (?, ?, ?) """, ( @@ -392,21 +392,21 @@ async def create_shop_market_stalls(market_id: str, data: List[str]): stallid, ), ) - market_stalls = await get_shop_market_stalls(market_id) + market_stalls = await get_market_market_stalls(market_id) return market_stalls -async def update_shop_market(market_id: str, name: str): +async def update_market_market(market_id: str, name: str): await db.execute( - "UPDATE shop.markets SET name = ? WHERE id = ?", + "UPDATE market.markets SET name = ? WHERE id = ?", (name, market_id), ) await db.execute( - "DELETE FROM shop.market_stalls WHERE marketid = ?", + "DELETE FROM market.market_stalls WHERE marketid = ?", (market_id,), ) - market = await get_shop_market(market_id) + market = await get_market_market(market_id) return market @@ -416,7 +416,7 @@ async def update_shop_market(market_id: str, name: str): async def create_chat_message(data: CreateChatMessage): await db.execute( """ - INSERT INTO shop.messages (msg, pubkey, id_conversation) + INSERT INTO market.messages (msg, pubkey, id_conversation) VALUES (?, ?, ?) """, ( @@ -427,44 +427,44 @@ async def create_chat_message(data: CreateChatMessage): ) -async def get_shop_latest_chat_messages(room_name: str): +async def get_market_latest_chat_messages(room_name: str): rows = await db.fetchall( - "SELECT * FROM shop.messages WHERE id_conversation = ? ORDER BY timestamp DESC LIMIT 20", + "SELECT * FROM market.messages WHERE id_conversation = ? ORDER BY timestamp DESC LIMIT 20", (room_name,), ) return [ChatMessage(**row) for row in rows] -async def get_shop_chat_messages(room_name: str): +async def get_market_chat_messages(room_name: str): rows = await db.fetchall( - "SELECT * FROM shop.messages WHERE id_conversation = ? ORDER BY timestamp DESC", + "SELECT * FROM market.messages WHERE id_conversation = ? ORDER BY timestamp DESC", (room_name,), ) return [ChatMessage(**row) for row in rows] -async def get_shop_chat_by_merchant(ids: List[str]) -> List[ChatMessage]: +async def get_market_chat_by_merchant(ids: List[str]) -> List[ChatMessage]: q = ",".join(["?"] * len(ids)) rows = await db.fetchall( - f"SELECT * FROM shop.messages WHERE id_conversation IN ({q})", + f"SELECT * FROM market.messages WHERE id_conversation IN ({q})", (*ids,), ) return [ChatMessage(**row) for row in rows] -async def get_shop_settings(user) -> Optional[ShopSettings]: - row = await db.fetchone("""SELECT * FROM shop.settings WHERE "user" = ?""", (user,)) +async def get_market_settings(user) -> Optional[MarketSettings]: + row = await db.fetchone("""SELECT * FROM market.settings WHERE "user" = ?""", (user,)) - return ShopSettings(**row) if row else None + return MarketSettings(**row) if row else None -async def create_shop_settings(user: str, data): +async def create_market_settings(user: str, data): await db.execute( """ - INSERT INTO shop.settings ("user", currency, fiat_base_multiplier) + INSERT INTO market.settings ("user", currency, fiat_base_multiplier) VALUES (?, ?, ?) """, ( @@ -475,10 +475,10 @@ async def create_shop_settings(user: str, data): ) -async def set_shop_settings(user: str, data): +async def set_market_settings(user: str, data): await db.execute( """ - UPDATE shop.settings + UPDATE market.settings SET currency = ?, fiat_base_multiplier = ? WHERE "user" = ?; """, diff --git a/lnbits/extensions/shop/migrations.py b/lnbits/extensions/market/migrations.py similarity index 85% rename from lnbits/extensions/shop/migrations.py rename to lnbits/extensions/market/migrations.py index e6592dff..72b584f9 100644 --- a/lnbits/extensions/shop/migrations.py +++ b/lnbits/extensions/market/migrations.py @@ -1,10 +1,10 @@ async def m001_initial(db): """ - Initial Shop settings table. + Initial Market settings table. """ await db.execute( """ - CREATE TABLE shop.settings ( + CREATE TABLE market.settings ( "user" TEXT PRIMARY KEY, currency TEXT DEFAULT 'sat', fiat_base_multiplier INTEGER DEFAULT 1 @@ -17,7 +17,7 @@ async def m001_initial(db): """ await db.execute( """ - CREATE TABLE shop.stalls ( + CREATE TABLE market.stalls ( id TEXT PRIMARY KEY, wallet TEXT NOT NULL, name TEXT NOT NULL, @@ -35,7 +35,7 @@ async def m001_initial(db): """ await db.execute( f""" - CREATE TABLE shop.products ( + CREATE TABLE market.products ( id TEXT PRIMARY KEY, stall TEXT NOT NULL REFERENCES {db.references_schema}stalls (id) ON DELETE CASCADE, product TEXT NOT NULL, @@ -54,7 +54,7 @@ async def m001_initial(db): """ await db.execute( """ - CREATE TABLE shop.zones ( + CREATE TABLE market.zones ( id TEXT PRIMARY KEY, "user" TEXT NOT NULL, cost TEXT NOT NULL, @@ -68,7 +68,7 @@ async def m001_initial(db): """ await db.execute( f""" - CREATE TABLE shop.orders ( + CREATE TABLE market.orders ( id {db.serial_primary_key}, wallet TEXT NOT NULL, username TEXT, @@ -92,7 +92,7 @@ async def m001_initial(db): """ await db.execute( f""" - CREATE TABLE shop.order_details ( + CREATE TABLE market.order_details ( id TEXT PRIMARY KEY, order_id INTEGER NOT NULL REFERENCES {db.references_schema}orders (id) ON DELETE CASCADE, product_id TEXT NOT NULL REFERENCES {db.references_schema}products (id) ON DELETE CASCADE, @@ -106,7 +106,7 @@ async def m001_initial(db): """ await db.execute( """ - CREATE TABLE shop.markets ( + CREATE TABLE market.markets ( id TEXT PRIMARY KEY, usr TEXT NOT NULL, name TEXT @@ -119,7 +119,7 @@ async def m001_initial(db): """ await db.execute( f""" - CREATE TABLE shop.market_stalls ( + CREATE TABLE market.market_stalls ( id TEXT PRIMARY KEY, marketid TEXT NOT NULL REFERENCES {db.references_schema}markets (id) ON DELETE CASCADE, stallid TEXT NOT NULL REFERENCES {db.references_schema}stalls (id) ON DELETE CASCADE @@ -132,7 +132,7 @@ async def m001_initial(db): """ await db.execute( f""" - CREATE TABLE shop.messages ( + CREATE TABLE market.messages ( id {db.serial_primary_key}, msg TEXT NOT NULL, pubkey TEXT NOT NULL, @@ -149,8 +149,8 @@ async def m001_initial(db): Create indexes for message fetching """ await db.execute( - "CREATE INDEX idx_messages_timestamp ON shop.messages (timestamp DESC)" + "CREATE INDEX idx_messages_timestamp ON market.messages (timestamp DESC)" ) await db.execute( - "CREATE INDEX idx_messages_conversations ON shop.messages (id_conversation)" + "CREATE INDEX idx_messages_conversations ON market.messages (id_conversation)" ) diff --git a/lnbits/extensions/shop/models.py b/lnbits/extensions/market/models.py similarity index 98% rename from lnbits/extensions/shop/models.py rename to lnbits/extensions/market/models.py index ed6342f0..ea7f6f20 100644 --- a/lnbits/extensions/shop/models.py +++ b/lnbits/extensions/market/models.py @@ -4,7 +4,7 @@ from fastapi.param_functions import Query from pydantic import BaseModel -class ShopSettings(BaseModel): +class MarketSettings(BaseModel): user: str currency: str fiat_base_multiplier: int diff --git a/lnbits/extensions/shop/notifier.py b/lnbits/extensions/market/notifier.py similarity index 95% rename from lnbits/extensions/shop/notifier.py rename to lnbits/extensions/market/notifier.py index 0030001c..e2bf7c91 100644 --- a/lnbits/extensions/shop/notifier.py +++ b/lnbits/extensions/market/notifier.py @@ -10,8 +10,8 @@ from collections import defaultdict from fastapi import WebSocket from loguru import logger -from lnbits.extensions.shop.crud import create_chat_message -from lnbits.extensions.shop.models import CreateChatMessage +from lnbits.extensions.market.crud import create_chat_message +from lnbits.extensions.market.models import CreateChatMessage class Notifier: diff --git a/lnbits/extensions/shop/static/images/bitcoin-shop.png b/lnbits/extensions/market/static/images/bitcoin-shop.png similarity index 100% rename from lnbits/extensions/shop/static/images/bitcoin-shop.png rename to lnbits/extensions/market/static/images/bitcoin-shop.png diff --git a/lnbits/extensions/shop/static/images/placeholder.png b/lnbits/extensions/market/static/images/placeholder.png similarity index 100% rename from lnbits/extensions/shop/static/images/placeholder.png rename to lnbits/extensions/market/static/images/placeholder.png diff --git a/lnbits/extensions/shop/tasks.py b/lnbits/extensions/market/tasks.py similarity index 62% rename from lnbits/extensions/shop/tasks.py rename to lnbits/extensions/market/tasks.py index 621e4fae..004ebb4d 100644 --- a/lnbits/extensions/shop/tasks.py +++ b/lnbits/extensions/market/tasks.py @@ -6,10 +6,10 @@ from lnbits.core.models import Payment from lnbits.tasks import register_invoice_listener from .crud import ( - get_shop_order_details, - get_shop_order_invoiceid, - set_shop_order_paid, - update_shop_product_stock, + get_market_order_details, + get_market_order_invoiceid, + set_market_order_paid, + update_market_product_stock, ) @@ -26,17 +26,17 @@ async def on_invoice_paid(payment: Payment) -> None: if not payment.extra: return - if payment.extra.get("tag") != "shop": + if payment.extra.get("tag") != "market": return - order = await get_shop_order_invoiceid(payment.payment_hash) + order = await get_market_order_invoiceid(payment.payment_hash) if not order: logger.error("this should never happen", payment) return # set order as paid - await set_shop_order_paid(payment.payment_hash) + await set_market_order_paid(payment.payment_hash) # deduct items sold from stock - details = await get_shop_order_details(order.id) - await update_shop_product_stock(details) + details = await get_market_order_details(order.id) + await update_market_product_stock(details) diff --git a/lnbits/extensions/shop/templates/shop/_api_docs.html b/lnbits/extensions/market/templates/market/_api_docs.html similarity index 88% rename from lnbits/extensions/shop/templates/shop/_api_docs.html rename to lnbits/extensions/market/templates/market/_api_docs.html index 3990c301..f0d97dbf 100644 --- a/lnbits/extensions/shop/templates/shop/_api_docs.html +++ b/lnbits/extensions/market/templates/market/_api_docs.html @@ -7,7 +7,7 @@
- LNbits Shop (Nostr support coming soon) + LNbits Market (Nostr support coming soon)
    @@ -17,9 +17,9 @@
  1. Take orders
  2. Includes chat support!
- The first LNbits shop idea 'Diagon Alley' helped create Nostr, and soon - this shop extension will have the option to work on Nostr 'Diagon Alley' - mode, by the merchant, shop, and buyer all having keys, and data being + The first LNbits market idea 'Diagon Alley' helped create Nostr, and soon + this market extension will have the option to work on Nostr 'Diagon Alley' + mode, by the merchant, market, and buyer all having keys, and data being routed through Nostr relays.
@@ -48,7 +48,7 @@ GET - /shop/api/v1/stall/products/<relay_id>
Body (application/json)
@@ -73,7 +73,7 @@ POST - /shop/api/v1/stall/order/<relay_id>
Body (application/json)
GET - /shop/api/v1/stall/checkshipped/<checking_id>
Headers
diff --git a/lnbits/extensions/shop/templates/shop/_chat_box.html b/lnbits/extensions/market/templates/market/_chat_box.html similarity index 100% rename from lnbits/extensions/shop/templates/shop/_chat_box.html rename to lnbits/extensions/market/templates/market/_chat_box.html diff --git a/lnbits/extensions/shop/templates/shop/_dialogs.html b/lnbits/extensions/market/templates/market/_dialogs.html similarity index 98% rename from lnbits/extensions/shop/templates/shop/_dialogs.html rename to lnbits/extensions/market/templates/market/_dialogs.html index d2c22350..d2a8dd0a 100644 --- a/lnbits/extensions/shop/templates/shop/_dialogs.html +++ b/lnbits/extensions/market/templates/market/_dialogs.html @@ -184,7 +184,7 @@ - + @@ -314,8 +314,8 @@ v-if="diagonAlley" filled dense - v-model.trim="stallDialog.data.nostrShops" - label="Nostr shop public keys (seperate by comma)" + v-model.trim="stallDialog.data.nostrMarkets" + label="Nostr market public keys (seperate by comma)" >
@@ -350,7 +350,7 @@ -
How to use Shop
+
How to use Market
Product shipped? @@ -194,7 +194,7 @@ unelevated dense size="xs" - icon="add_shopping_cart" + icon="add_marketping_cart" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" :href="props.row.wallet" @@ -276,10 +276,10 @@ icon="storefront" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" - :href="'/shop/stalls/' + props.row.id" + :href="'/market/stalls/' + props.row.id" target="_blank" > - Stall simple UI shopping cart + Stall simple UI marketping cart {{ col.value }} @@ -348,7 +348,7 @@ icon="storefront" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'" type="a" - :href="'/shop/market/' + props.row.id" + :href="'/market/market/' + props.row.id" target="_blank" > Link to pass to stall relay diff --git a/lnbits/extensions/shop/templates/shop/index.html b/lnbits/extensions/market/templates/market/index.html similarity index 93% rename from lnbits/extensions/shop/templates/shop/index.html rename to lnbits/extensions/market/templates/market/index.html index 49ddf6fb..e16e5d48 100644 --- a/lnbits/extensions/shop/templates/shop/index.html +++ b/lnbits/extensions/market/templates/market/index.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block page %}
- {% include "shop/_dialogs.html" %} + {% include "market/_dialogs.html" %}
@@ -60,14 +60,14 @@ @click="marketDialog.show = true" >Create Market - Makes a simple frontend shop for your stalls (not NOSTR) -
Shop
-
Make a shop of multiple stalls.
+
Market
+
Make a market of multiple stalls.
@@ -87,16 +87,16 @@ class="float-right" unelevated color="primary" - @click="shopDataDownload" + @click="marketDataDownload" >Export all Data - Export all data (shops, products, orders, etc...)
- {% include "shop/_tables.html" %} + {% include "market/_tables.html" %} @@ -149,16 +149,16 @@
- LNbits Shop Extension, powered by Nostr + LNbits Market Extension (Nostr support coming soon)
- {% include "shop/_api_docs.html" %} + {% include "market/_api_docs.html" %}
- {% include "shop/_chat_box.html" %} + {% include "market/_chat_box.html" %}
@@ -215,7 +215,7 @@ obj._data = _.clone(obj) obj.stalls = [] LNbits.api - .request('GET', `/shop/api/v1/markets/${obj.id}/stalls`, null) + .request('GET', `/market/api/v1/markets/${obj.id}/stalls`, null) .then(response => { if (response.data) { obj.stalls = response.data.map(s => s.id) //.toString() @@ -548,7 +548,7 @@ LNbits.api .request( 'PUT', - '/shop/api/v1/settings/' + this.g.user.id, + '/market/api/v1/settings/' + this.g.user.id, this.g.user.wallets[0].adminkey, data ) @@ -563,7 +563,7 @@ LNbits.utils.notifyApiError(error) }) }, - shopDataDownload() { + marketDataDownload() { const removeClone = obj => { delete obj._data return obj @@ -593,10 +593,10 @@ this.keys = {privkey, pubkey} this.stallDialog.data.publickey = this.keys.pubkey this.stallDialog.data.privatekey = this.keys.privkey - this.$q.localStorage.set(`lnbits.shop.${this.g.user.id}`, this.keys) + this.$q.localStorage.set(`lnbits.market.${this.g.user.id}`, this.keys) }, restoreKeys() { - let keys = this.$q.localStorage.getItem(`lnbits.shop.${this.g.user.id}`) + let keys = this.$q.localStorage.getItem(`lnbits.market.${this.g.user.id}`) if (keys) { this.keys = keys this.stallDialog.data.publickey = this.keys.pubkey @@ -645,7 +645,7 @@ LNbits.api .request( 'GET', - '/shop/api/v1/stalls?all_wallets=true', + '/market/api/v1/stalls?all_wallets=true', self.g.user.wallets[0].adminkey ) .then(function (response) { @@ -704,7 +704,7 @@ LNbits.api .request( 'PUT', - '/shop/api/v1/stalls/' + data.id, + '/market/api/v1/stalls/' + data.id, _.findWhere(self.g.user.wallets, { id: self.stallDialog.data.wallet }).inkey, @@ -726,7 +726,7 @@ LNbits.api .request( 'POST', - '/shop/api/v1/stalls', + '/market/api/v1/stalls', _.findWhere(self.g.user.wallets, { id: self.stallDialog.data.wallet }).inkey, @@ -753,7 +753,7 @@ LNbits.api .request( 'DELETE', - '/shop/api/v1/stalls/' + stallId, + '/market/api/v1/stalls/' + stallId, _.findWhere(self.g.user.wallets, {id: stall.wallet}).adminkey ) .then(function (response) { @@ -778,7 +778,7 @@ LNbits.api .request( 'GET', - '/shop/api/v1/products?all_stalls=true', + '/market/api/v1/products?all_stalls=true', self.g.user.wallets[0].inkey ) .then(function (response) { @@ -851,7 +851,7 @@ LNbits.api .request( 'PUT', - '/shop/api/v1/products/' + data.id, + '/market/api/v1/products/' + data.id, _.findWhere(self.g.user.wallets, { id: wallet }).inkey, @@ -877,7 +877,7 @@ LNbits.api .request( 'POST', - '/shop/api/v1/products', + '/market/api/v1/products', _.findWhere(self.g.user.wallets, {id: walletId}).inkey, data ) @@ -899,7 +899,7 @@ LNbits.api .request( 'DELETE', - '/shop/api/v1/products/' + productId, + '/market/api/v1/products/' + productId, _.findWhere(this.g.user.wallets, {id: walletId}).adminkey ) .then(() => { @@ -922,7 +922,7 @@ var self = this LNbits.api - .request('GET', '/shop/api/v1/zones', this.g.user.wallets[0].inkey) + .request('GET', '/market/api/v1/zones', this.g.user.wallets[0].inkey) .then(function (response) { if (response.data) { self.zones = response.data.map(mapZone) @@ -960,7 +960,7 @@ LNbits.api .request( 'POST', - '/shop/api/v1/zones/' + data.id, + '/market/api/v1/zones/' + data.id, self.g.user.wallets[0].adminkey, data ) @@ -982,7 +982,7 @@ LNbits.api .request( 'POST', - '/shop/api/v1/zones', + '/market/api/v1/zones', self.g.user.wallets[0].inkey, data ) @@ -1006,7 +1006,7 @@ LNbits.api .request( 'DELETE', - '/shop/api/v1/zones/' + zoneId, + '/market/api/v1/zones/' + zoneId, self.g.user.wallets[0].adminkey ) .then(function (response) { @@ -1027,7 +1027,7 @@ //////////////////////////////////////// getMarkets() { LNbits.api - .request('GET', '/shop/api/v1/markets', this.g.user.wallets[0].inkey) + .request('GET', '/market/api/v1/markets', this.g.user.wallets[0].inkey) .then(response => { if (response.data) { this.markets = response.data.map(mapMarkets) @@ -1059,7 +1059,7 @@ LNbits.api .request( 'PUT', - '/shop/api/v1/markets/' + data.id, + '/market/api/v1/markets/' + data.id, this.g.user.wallets[0].inkey, data ) @@ -1080,7 +1080,7 @@ LNbits.api .request( 'POST', - '/shop/api/v1/markets', + '/market/api/v1/markets', this.g.user.wallets[0].inkey, data ) @@ -1094,8 +1094,8 @@ LNbits.utils.notifyApiError(error) }) }, - deleteMarket(shopId) { - let market = _.findWhere(this.markets, {id: shopId}) + deleteMarket(marketId) { + let market = _.findWhere(this.markets, {id: marketId}) LNbits.utils .confirmDialog('Are you sure you want to delete this Marketplace?') @@ -1103,12 +1103,12 @@ LNbits.api .request( 'DELETE', - '/shop/api/v1/markets/' + shopId, + '/market/api/v1/markets/' + marketId, this.g.user.wallets[0].inkey ) .then(response => { this.markets = _.reject(this.markets, obj => { - return obj.id == shopId + return obj.id == marketId }) }) .catch(function (error) { @@ -1116,8 +1116,8 @@ }) }) }, - exportShopsCSV: function () { - LNbits.utils.exportCSV(this.shopsTable.columns, this.markets) + exportMarketsCSV: function () { + LNbits.utils.exportCSV(this.marketsTable.columns, this.markets) }, //////////////////////////////////////// ////////////////ORDERS////////////////// @@ -1128,7 +1128,7 @@ await LNbits.api .request( 'GET', - '/shop/api/v1/orders?all_wallets=true', + '/market/api/v1/orders?all_wallets=true', this.g.user.wallets[0].inkey ) .then(response => { @@ -1150,7 +1150,7 @@ LNbits.api .request( 'DELETE', - '/shop/api/v1/orders/' + orderId, + '/market/api/v1/orders/' + orderId, _.findWhere(self.g.user.wallets, {id: order.wallet}).adminkey ) .then(function (response) { @@ -1168,7 +1168,7 @@ LNbits.api .request( 'GET', - `/shop/api/v1/orders/shipped/${order_id}?shipped=${!shipped}`, + `/market/api/v1/orders/shipped/${order_id}?shipped=${!shipped}`, this.g.user.wallets[0].inkey ) .then(response => { @@ -1189,7 +1189,7 @@ await LNbits.api .request( 'GET', - `/shop/api/v1/chat/messages/merchant?orders=${this.orders + `/market/api/v1/chat/messages/merchant?orders=${this.orders .map(o => o.invoiceid) .toString()}`, this.g.user.wallets[0].adminkey @@ -1205,7 +1205,7 @@ }) }, updateLastSeenMsg(id) { - let data = this.$q.localStorage.getItem(`lnbits.shop.chat`) + let data = this.$q.localStorage.getItem(`lnbits.market.chat`) let chat = { ...data, [`${id}`]: { @@ -1214,11 +1214,11 @@ ] } } - this.$q.localStorage.set(`lnbits.shop.chat`, chat) + this.$q.localStorage.set(`lnbits.market.chat`, chat) this.checkUnreadMessages() }, checkUnreadMessages() { - let lastMsgs = this.$q.localStorage.getItem(`lnbits.shop.chat`) || {} + let lastMsgs = this.$q.localStorage.getItem(`lnbits.market.chat`) || {} for (let key in this.messages) { let idx = this.orders.findIndex(f => f.invoiceid == key) @@ -1287,7 +1287,7 @@ if (this.ws.readyState === WebSocket.CLOSED) { console.log('WebSocket CLOSED: Reopening') this.ws = new WebSocket( - ws_scheme + location.host + '/shop/ws/' + this.customerKey + ws_scheme + location.host + '/market/ws/' + this.customerKey ) } }, @@ -1318,7 +1318,7 @@ } else { ws_scheme = 'ws://' } - ws = new WebSocket(ws_scheme + location.host + '/shop/ws/' + room_name) + ws = new WebSocket(ws_scheme + location.host + '/market/ws/' + room_name) ws.onmessage = async event => { let event_data = JSON.parse(event.data) @@ -1335,7 +1335,7 @@ }, async getCurrencies() { await LNbits.api - .request('GET', '/shop/api/v1/currencies') + .request('GET', '/market/api/v1/currencies') .then(response => { this.currencies.units = ['sat', ...response.data] }) @@ -1359,7 +1359,7 @@ await this.getOrders() this.getMarkets() await this.getAllMessages() - let keys = this.$q.localStorage.getItem(`lnbits.shop.${this.g.user.id}`) + let keys = this.$q.localStorage.getItem(`lnbits.market.${this.g.user.id}`) if (keys) { this.keys = keys } diff --git a/lnbits/extensions/shop/templates/shop/market.html b/lnbits/extensions/market/templates/market/market.html similarity index 97% rename from lnbits/extensions/shop/templates/shop/market.html rename to lnbits/extensions/market/templates/market/market.html index 6763ef3b..e59bb245 100644 --- a/lnbits/extensions/shop/templates/shop/market.html +++ b/lnbits/extensions/market/templates/market/market.html @@ -33,7 +33,7 @@ {% raw %} Visit Stall diff --git a/lnbits/extensions/shop/templates/shop/order.html b/lnbits/extensions/market/templates/market/order.html similarity index 95% rename from lnbits/extensions/shop/templates/shop/order.html rename to lnbits/extensions/market/templates/market/order.html index 14d14f34..ebabe882 100644 --- a/lnbits/extensions/shop/templates/shop/order.html +++ b/lnbits/extensions/market/templates/market/order.html @@ -292,7 +292,7 @@ lnbitsBookmark: { show: true, finish: () => { - this.$q.localStorage.set('lnbits.shopbookmark', false) + this.$q.localStorage.set('lnbits.marketbookmark', false) this.lnbitsBookmark.show = false } }, @@ -368,8 +368,8 @@ }, restoreKeys() { this.user.keys = this.keysDialog.data - let data = this.$q.localStorage.getItem(`lnbits.shop.data`) - this.$q.localStorage.set(`lnbits.shop.data`, { + let data = this.$q.localStorage.getItem(`lnbits.market.data`) + this.$q.localStorage.set(`lnbits.market.data`, { ...data, keys: this.user.keys }) @@ -380,7 +380,7 @@ LNbits.utils .confirmDialog('Are you sure you want to delete your stored data?') .onOk(() => { - this.$q.localStorage.remove('lnbits.shop.data') + this.$q.localStorage.remove('lnbits.market.data') this.user = null }) }, @@ -401,7 +401,7 @@ await LNbits.api .request( 'GET', - `/shop/api/v1/chat/messages/${room_name}${ + `/market/api/v1/chat/messages/${room_name}${ all ? '?all_messages=true' : '' }` ) @@ -430,7 +430,7 @@ if (this.ws.readyState === WebSocket.CLOSED) { console.log('WebSocket CLOSED: Reopening') this.ws = new WebSocket( - ws_scheme + location.host + '/shop/ws/' + this.selectedOrder + ws_scheme + location.host + '/market/ws/' + this.selectedOrder ) } }, @@ -443,7 +443,7 @@ } else { ws_scheme = 'ws://' } - ws = new WebSocket(ws_scheme + location.host + '/shop/ws/' + room_name) + ws = new WebSocket(ws_scheme + location.host + '/market/ws/' + room_name) ws.onmessage = event => { let event_data = JSON.parse(event.data) @@ -455,7 +455,7 @@ } }, async created() { - let showBookmark = this.$q.localStorage.getItem('lnbits.shopbookmark') + let showBookmark = this.$q.localStorage.getItem('lnbits.marketbookmark') this.lnbitsBookmark.show = showBookmark === true || showBookmark == null let order_details = JSON.parse('{{ order | tojson }}') @@ -488,7 +488,7 @@ this.products = this.products.map(mapProductsItems) } - let data = this.$q.localStorage.getItem(`lnbits.shop.data`) || false + let data = this.$q.localStorage.getItem(`lnbits.market.data`) || false if (data) { this.user = data @@ -501,7 +501,7 @@ try { await LNbits.api.request( 'GET', - `/shop/api/v1/order/pubkey/${order_id}/${this.user.keys.publickey}` + `/market/api/v1/order/pubkey/${order_id}/${this.user.keys.publickey}` ) } catch (error) { LNbits.utils.notifyApiError(error) @@ -516,7 +516,7 @@ await this.getMessages(order_id) - this.$q.localStorage.set(`lnbits.shop.data`, this.user) + this.$q.localStorage.set(`lnbits.market.data`, this.user) this.startChat(order_id) } }) diff --git a/lnbits/extensions/shop/templates/shop/product.html b/lnbits/extensions/market/templates/market/product.html similarity index 100% rename from lnbits/extensions/shop/templates/shop/product.html rename to lnbits/extensions/market/templates/market/product.html diff --git a/lnbits/extensions/shop/templates/shop/stall.html b/lnbits/extensions/market/templates/market/stall.html similarity index 96% rename from lnbits/extensions/shop/templates/shop/stall.html rename to lnbits/extensions/market/templates/market/stall.html index f715cf37..f9189b30 100644 --- a/lnbits/extensions/shop/templates/shop/stall.html +++ b/lnbits/extensions/market/templates/market/stall.html @@ -94,7 +94,7 @@ {% raw %} { this.checkoutDialog = {show: false, data: {}} @@ -477,7 +477,7 @@ LNbits.api .request( 'GET', - `/shop/api/v1/orders/payments/${this.qrCodeDialog.data.payment_hash}` + `/market/api/v1/orders/payments/${this.qrCodeDialog.data.payment_hash}` ) .then(res => { if (res.data.paid) { @@ -491,7 +491,7 @@ { label: 'See Order', handler: () => { - window.location.href = `/shop/order/?merch=${this.stall.id}&invoice_id=${this.qrCodeDialog.data.payment_hash}` + window.location.href = `/market/order/?merch=${this.stall.id}&invoice_id=${this.qrCodeDialog.data.payment_hash}` } } ] @@ -500,7 +500,7 @@ this.resetCart() this.closeQrCodeDialog() setTimeout(() => { - window.location.href = `/shop/order/?merch=${this.stall.id}&invoice_id=${this.qrCodeDialog.data.payment_hash}` + window.location.href = `/market/order/?merch=${this.stall.id}&invoice_id=${this.qrCodeDialog.data.payment_hash}` }, 5000) } }) diff --git a/lnbits/extensions/shop/views.py b/lnbits/extensions/market/views.py similarity index 67% rename from lnbits/extensions/shop/views.py rename to lnbits/extensions/market/views.py index 309ed134..23bc5706 100644 --- a/lnbits/extensions/shop/views.py +++ b/lnbits/extensions/market/views.py @@ -17,48 +17,48 @@ from starlette.responses import HTMLResponse from lnbits.core.models import User from lnbits.decorators import check_user_exists # type: ignore -from lnbits.extensions.shop import shop_ext, shop_renderer -from lnbits.extensions.shop.models import CreateChatMessage, SetSettings -from lnbits.extensions.shop.notifier import Notifier +from lnbits.extensions.market import market_ext, market_renderer +from lnbits.extensions.market.models import CreateChatMessage, SetSettings +from lnbits.extensions.market.notifier import Notifier from .crud import ( create_chat_message, - create_shop_settings, - get_shop_market, - get_shop_market_stalls, - get_shop_order_details, - get_shop_order_invoiceid, - get_shop_products, - get_shop_settings, - get_shop_stall, - get_shop_zone, - get_shop_zones, - update_shop_product_stock, + create_market_settings, + get_market_market, + get_market_market_stalls, + get_market_order_details, + get_market_order_invoiceid, + get_market_products, + get_market_settings, + get_market_stall, + get_market_zone, + get_market_zones, + update_market_product_stock, ) templates = Jinja2Templates(directory="templates") -@shop_ext.get("/", response_class=HTMLResponse) +@market_ext.get("/", response_class=HTMLResponse) async def index(request: Request, user: User = Depends(check_user_exists)): - settings = await get_shop_settings(user=user.id) + settings = await get_market_settings(user=user.id) if not settings: - await create_shop_settings( + await create_market_settings( user=user.id, data=SetSettings(currency="sat", fiat_base_multiplier=1) ) - settings = await get_shop_settings(user.id) + settings = await get_market_settings(user.id) assert settings - return shop_renderer().TemplateResponse( - "shop/index.html", + return market_renderer().TemplateResponse( + "market/index.html", {"request": request, "user": user.dict(), "currency": settings.currency}, ) -@shop_ext.get("/stalls/{stall_id}", response_class=HTMLResponse) +@market_ext.get("/stalls/{stall_id}", response_class=HTMLResponse) async def stall(request: Request, stall_id): - stall = await get_shop_stall(stall_id) - products = await get_shop_products(stall_id) + stall = await get_market_stall(stall_id) + products = await get_market_products(stall_id) if not stall: raise HTTPException( @@ -67,7 +67,7 @@ async def stall(request: Request, stall_id): zones = [] for id in stall.shippingzones.split(","): - zone = await get_shop_zone(id) + zone = await get_market_zone(id) assert zone z = zone.dict() zones.append({"label": z["countries"], "cost": z["cost"], "value": z["id"]}) @@ -76,8 +76,8 @@ async def stall(request: Request, stall_id): _stall["zones"] = zones - return shop_renderer().TemplateResponse( - "shop/stall.html", + return market_renderer().TemplateResponse( + "market/stall.html", { "request": request, "stall": _stall, @@ -86,21 +86,21 @@ async def stall(request: Request, stall_id): ) -@shop_ext.get("/market/{market_id}", response_class=HTMLResponse) +@market_ext.get("/market/{market_id}", response_class=HTMLResponse) async def market(request: Request, market_id): - market = await get_shop_market(market_id) + market = await get_market_market(market_id) if not market: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Marketplace doesn't exist." ) - stalls = await get_shop_market_stalls(market_id) + stalls = await get_market_market_stalls(market_id) stalls_ids = [stall.id for stall in stalls] - products = [product.dict() for product in await get_shop_products(stalls_ids)] + products = [product.dict() for product in await get_market_products(stalls_ids)] - return shop_renderer().TemplateResponse( - "shop/market.html", + return market_renderer().TemplateResponse( + "market/market.html", { "request": request, "market": market, @@ -110,23 +110,23 @@ async def market(request: Request, market_id): ) -@shop_ext.get("/order", response_class=HTMLResponse) +@market_ext.get("/order", response_class=HTMLResponse) async def order_chat( request: Request, merch: str = Query(...), invoice_id: str = Query(...), keys: str = Query(None), ): - stall = await get_shop_stall(merch) + stall = await get_market_stall(merch) assert stall - order = await get_shop_order_invoiceid(invoice_id) + order = await get_market_order_invoiceid(invoice_id) assert order - _order = await get_shop_order_details(order.id) - products = await get_shop_products(stall.id) + _order = await get_market_order_details(order.id) + products = await get_market_products(stall.id) assert products - return shop_renderer().TemplateResponse( - "shop/order.html", + return market_renderer().TemplateResponse( + "market/order.html", { "request": request, "stall": { @@ -151,7 +151,7 @@ async def order_chat( notifier = Notifier() -@shop_ext.websocket("/ws/{room_name}") +@market_ext.websocket("/ws/{room_name}") async def websocket_endpoint( websocket: WebSocket, room_name: str, background_tasks: BackgroundTasks ): diff --git a/lnbits/extensions/shop/views_api.py b/lnbits/extensions/market/views_api.py similarity index 51% rename from lnbits/extensions/shop/views_api.py rename to lnbits/extensions/market/views_api.py index 87374b20..8d0202a3 100644 --- a/lnbits/extensions/shop/views_api.py +++ b/lnbits/extensions/market/views_api.py @@ -19,44 +19,44 @@ from lnbits.decorators import ( from lnbits.helpers import urlsafe_short_hash from lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis -from . import db, shop_ext +from . import db, market_ext from .crud import ( - create_shop_market, - create_shop_market_stalls, - create_shop_order, - create_shop_order_details, - create_shop_product, - create_shop_settings, - create_shop_stall, - create_shop_zone, - delete_shop_order, - delete_shop_product, - delete_shop_stall, - delete_shop_zone, - get_shop_chat_by_merchant, - get_shop_chat_messages, - get_shop_latest_chat_messages, - get_shop_market, - get_shop_market_stalls, - get_shop_markets, - get_shop_order, - get_shop_order_details, - get_shop_order_invoiceid, - get_shop_orders, - get_shop_product, - get_shop_products, - get_shop_settings, - get_shop_stall, - get_shop_stalls, - get_shop_stalls_by_ids, - get_shop_zone, - get_shop_zones, - set_shop_order_pubkey, - set_shop_settings, - update_shop_market, - update_shop_product, - update_shop_stall, - update_shop_zone, + create_market_market, + create_market_market_stalls, + create_market_order, + create_market_order_details, + create_market_product, + create_market_settings, + create_market_stall, + create_market_zone, + delete_market_order, + delete_market_product, + delete_market_stall, + delete_market_zone, + get_market_chat_by_merchant, + get_market_chat_messages, + get_market_latest_chat_messages, + get_market_market, + get_market_market_stalls, + get_market_markets, + get_market_order, + get_market_order_details, + get_market_order_invoiceid, + get_market_orders, + get_market_product, + get_market_products, + get_market_settings, + get_market_stall, + get_market_stalls, + get_market_stalls_by_ids, + get_market_zone, + get_market_zones, + set_market_order_pubkey, + set_market_settings, + update_market_market, + update_market_product, + update_market_stall, + update_market_zone, ) from .models import ( CreateMarket, @@ -76,8 +76,8 @@ from .models import ( ### Products -@shop_ext.get("/api/v1/products") -async def api_shop_products( +@market_ext.get("/api/v1/products") +async def api_market_products( wallet: WalletTypeInfo = Depends(require_invoice_key), all_stalls: bool = Query(False), ): @@ -87,104 +87,104 @@ async def api_shop_products( user = await get_user(wallet.wallet.user) wallet_ids = user.wallet_ids if user else [] - stalls = [stall.id for stall in await get_shop_stalls(wallet_ids)] + stalls = [stall.id for stall in await get_market_stalls(wallet_ids)] if not stalls: return - return [product.dict() for product in await get_shop_products(stalls)] + return [product.dict() for product in await get_market_products(stalls)] -@shop_ext.post("/api/v1/products") -@shop_ext.put("/api/v1/products/{product_id}") -async def api_shop_product_create( +@market_ext.post("/api/v1/products") +@market_ext.put("/api/v1/products/{product_id}") +async def api_market_product_create( data: createProduct, product_id=None, wallet: WalletTypeInfo = Depends(require_invoice_key), ): # For fiat currencies, # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents. - settings = await get_shop_settings(user=wallet.wallet.user) + settings = await get_market_settings(user=wallet.wallet.user) assert settings - stall = await get_shop_stall(stall_id=data.stall) + stall = await get_market_stall(stall_id=data.stall) assert stall if stall.currency != "sat": data.price *= settings.fiat_base_multiplier if product_id: - product = await get_shop_product(product_id) + product = await get_market_product(product_id) if not product: return {"message": "Product does not exist."} - # stall = await get_shop_stall(stall_id=product.stall) + # stall = await get_market_stall(stall_id=product.stall) if stall.wallet != wallet.wallet.id: return {"message": "Not your product."} - product = await update_shop_product(product_id, **data.dict()) + product = await update_market_product(product_id, **data.dict()) else: - product = await create_shop_product(data=data) + product = await create_market_product(data=data) assert product return product.dict() -@shop_ext.delete("/api/v1/products/{product_id}") -async def api_shop_products_delete( +@market_ext.delete("/api/v1/products/{product_id}") +async def api_market_products_delete( product_id, wallet: WalletTypeInfo = Depends(require_admin_key) ): - product = await get_shop_product(product_id) + product = await get_market_product(product_id) if not product: return {"message": "Product does not exist."} - stall = await get_shop_stall(product.stall) + stall = await get_market_stall(product.stall) assert stall if stall.wallet != wallet.wallet.id: - return {"message": "Not your Shop."} + return {"message": "Not your Market."} - await delete_shop_product(product_id) + await delete_market_product(product_id) raise HTTPException(status_code=HTTPStatus.NO_CONTENT) # # # Shippingzones -@shop_ext.get("/api/v1/zones") -async def api_shop_zones(wallet: WalletTypeInfo = Depends(get_key_type)): +@market_ext.get("/api/v1/zones") +async def api_market_zones(wallet: WalletTypeInfo = Depends(get_key_type)): - return await get_shop_zones(wallet.wallet.user) + return await get_market_zones(wallet.wallet.user) -@shop_ext.post("/api/v1/zones") -async def api_shop_zone_create( +@market_ext.post("/api/v1/zones") +async def api_market_zone_create( data: createZones, wallet: WalletTypeInfo = Depends(get_key_type) ): - zone = await create_shop_zone(user=wallet.wallet.user, data=data) + zone = await create_market_zone(user=wallet.wallet.user, data=data) return zone.dict() -@shop_ext.post("/api/v1/zones/{zone_id}") -async def api_shop_zone_update( +@market_ext.post("/api/v1/zones/{zone_id}") +async def api_market_zone_update( data: createZones, zone_id: str, wallet: WalletTypeInfo = Depends(require_admin_key), ): - zone = await get_shop_zone(zone_id) + zone = await get_market_zone(zone_id) if not zone: return {"message": "Zone does not exist."} if zone.user != wallet.wallet.user: return {"message": "Not your record."} - zone = await update_shop_zone(zone_id, **data.dict()) + zone = await update_market_zone(zone_id, **data.dict()) return zone -@shop_ext.delete("/api/v1/zones/{zone_id}") -async def api_shop_zone_delete( +@market_ext.delete("/api/v1/zones/{zone_id}") +async def api_market_zone_delete( zone_id, wallet: WalletTypeInfo = Depends(require_admin_key) ): - zone = await get_shop_zone(zone_id) + zone = await get_market_zone(zone_id) if not zone: return {"message": "zone does not exist."} @@ -192,15 +192,15 @@ async def api_shop_zone_delete( if zone.user != wallet.wallet.user: return {"message": "Not your zone."} - await delete_shop_zone(zone_id) + await delete_market_zone(zone_id) raise HTTPException(status_code=HTTPStatus.NO_CONTENT) # # # Stalls -@shop_ext.get("/api/v1/stalls") -async def api_shop_stalls( +@market_ext.get("/api/v1/stalls") +async def api_market_stalls( wallet: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False) ): wallet_ids = [wallet.wallet.id] @@ -209,37 +209,37 @@ async def api_shop_stalls( user = await get_user(wallet.wallet.user) wallet_ids = user.wallet_ids if user else [] - return [stall.dict() for stall in await get_shop_stalls(wallet_ids)] + return [stall.dict() for stall in await get_market_stalls(wallet_ids)] -@shop_ext.post("/api/v1/stalls") -@shop_ext.put("/api/v1/stalls/{stall_id}") -async def api_shop_stall_create( +@market_ext.post("/api/v1/stalls") +@market_ext.put("/api/v1/stalls/{stall_id}") +async def api_market_stall_create( data: createStalls, stall_id: str = None, wallet: WalletTypeInfo = Depends(require_invoice_key), ): if stall_id: - stall = await get_shop_stall(stall_id) + stall = await get_market_stall(stall_id) if not stall: return {"message": "Withdraw stall does not exist."} if stall.wallet != wallet.wallet.id: return {"message": "Not your withdraw stall."} - stall = await update_shop_stall(stall_id, **data.dict()) + stall = await update_market_stall(stall_id, **data.dict()) else: - stall = await create_shop_stall(data=data) + stall = await create_market_stall(data=data) assert stall return stall.dict() -@shop_ext.delete("/api/v1/stalls/{stall_id}") -async def api_shop_stall_delete( +@market_ext.delete("/api/v1/stalls/{stall_id}") +async def api_market_stall_delete( stall_id: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): - stall = await get_shop_stall(stall_id) + stall = await get_market_stall(stall_id) if not stall: return {"message": "Stall does not exist."} @@ -247,15 +247,15 @@ async def api_shop_stall_delete( if stall.wallet != wallet.wallet.id: return {"message": "Not your Stall."} - await delete_shop_stall(stall_id) + await delete_market_stall(stall_id) raise HTTPException(status_code=HTTPStatus.NO_CONTENT) ###Orders -@shop_ext.get("/api/v1/orders") -async def api_shop_orders( +@market_ext.get("/api/v1/orders") +async def api_market_orders( wallet: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False) ): wallet_ids = [wallet.wallet.id] @@ -263,48 +263,48 @@ async def api_shop_orders( user = await get_user(wallet.wallet.user) wallet_ids = user.wallet_ids if user else [] - orders = await get_shop_orders(wallet_ids) + orders = await get_market_orders(wallet_ids) if not orders: return orders_with_details = [] for order in orders: _order = order.dict() - _order["details"] = await get_shop_order_details(_order["id"]) + _order["details"] = await get_market_order_details(_order["id"]) orders_with_details.append(_order) try: return orders_with_details # [order for order in orders] - # return [order.dict() for order in await get_shop_orders(wallet_ids)] + # return [order.dict() for order in await get_market_orders(wallet_ids)] except: return {"message": "We could not retrieve the orders."} -@shop_ext.get("/api/v1/orders/{order_id}") -async def api_shop_order_by_id(order_id: str): - order = await get_shop_order(order_id) +@market_ext.get("/api/v1/orders/{order_id}") +async def api_market_order_by_id(order_id: str): + order = await get_market_order(order_id) assert order _order = order.dict() - _order["details"] = await get_shop_order_details(order_id) + _order["details"] = await get_market_order_details(order_id) return _order -@shop_ext.post("/api/v1/orders") -async def api_shop_order_create(data: createOrder): +@market_ext.post("/api/v1/orders") +async def api_market_order_create(data: createOrder): ref = urlsafe_short_hash() payment_hash, payment_request = await create_invoice( wallet_id=data.wallet, amount=data.total, - memo=f"New order on Diagon alley", + memo=f"New order on Market", extra={ - "tag": "shop", + "tag": "market", "reference": ref, }, ) - order_id = await create_shop_order(invoiceid=payment_hash, data=data) + order_id = await create_market_order(invoiceid=payment_hash, data=data) logger.debug(f"ORDER ID {order_id}") logger.debug(f"PRODUCTS {data.products}") - await create_shop_order_details(order_id=order_id, data=data.products) + await create_market_order_details(order_id=order_id, data=data.products) return { "payment_hash": payment_hash, "payment_request": payment_request, @@ -312,9 +312,9 @@ async def api_shop_order_create(data: createOrder): } -@shop_ext.get("/api/v1/orders/payments/{payment_hash}") -async def api_shop_check_payment(payment_hash: str): - order = await get_shop_order_invoiceid(payment_hash) +@market_ext.get("/api/v1/orders/payments/{payment_hash}") +async def api_market_check_payment(payment_hash: str): + order = await get_market_order_invoiceid(payment_hash) if not order: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Order does not exist." @@ -328,11 +328,11 @@ async def api_shop_check_payment(payment_hash: str): return status -@shop_ext.delete("/api/v1/orders/{order_id}") -async def api_shop_order_delete( +@market_ext.delete("/api/v1/orders/{order_id}") +async def api_market_order_delete( order_id: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): - order = await get_shop_order(order_id) + order = await get_market_order(order_id) if not order: return {"message": "Order does not exist."} @@ -340,17 +340,17 @@ async def api_shop_order_delete( if order.wallet != wallet.wallet.id: return {"message": "Not your Order."} - await delete_shop_order(order_id) + await delete_market_order(order_id) raise HTTPException(status_code=HTTPStatus.NO_CONTENT) -# @shop_ext.get("/api/v1/orders/paid/{order_id}") -# async def api_shop_order_paid( +# @market_ext.get("/api/v1/orders/paid/{order_id}") +# async def api_market_order_paid( # order_id, wallet: WalletTypeInfo = Depends(require_admin_key) # ): # await db.execute( -# "UPDATE shop.orders SET paid = ? WHERE id = ?", +# "UPDATE market.orders SET paid = ? WHERE id = ?", # ( # True, # order_id, @@ -359,24 +359,24 @@ async def api_shop_order_delete( # return "", HTTPStatus.OK -@shop_ext.get("/api/v1/order/pubkey/{payment_hash}/{pubkey}") -async def api_shop_order_pubkey(payment_hash: str, pubkey: str): - await set_shop_order_pubkey(payment_hash, pubkey) +@market_ext.get("/api/v1/order/pubkey/{payment_hash}/{pubkey}") +async def api_market_order_pubkey(payment_hash: str, pubkey: str): + await set_market_order_pubkey(payment_hash, pubkey) return "", HTTPStatus.OK -@shop_ext.get("/api/v1/orders/shipped/{order_id}") -async def api_shop_order_shipped( +@market_ext.get("/api/v1/orders/shipped/{order_id}") +async def api_market_order_shipped( order_id, shipped: bool = Query(...), wallet: WalletTypeInfo = Depends(get_key_type) ): await db.execute( - "UPDATE shop.orders SET shipped = ? WHERE id = ?", + "UPDATE market.orders SET shipped = ? WHERE id = ?", ( shipped, order_id, ), ) - order = await db.fetchone("SELECT * FROM shop.orders WHERE id = ?", (order_id,)) + order = await db.fetchone("SELECT * FROM market.orders WHERE id = ?", (order_id,)) return order @@ -384,31 +384,31 @@ async def api_shop_order_shipped( ###List products based on stall id -# @shop_ext.get("/api/v1/stall/products/{stall_id}") -# async def api_shop_stall_products( +# @market_ext.get("/api/v1/stall/products/{stall_id}") +# async def api_market_stall_products( # stall_id, wallet: WalletTypeInfo = Depends(get_key_type) # ): -# rows = await db.fetchone("SELECT * FROM shop.stalls WHERE id = ?", (stall_id,)) +# rows = await db.fetchone("SELECT * FROM market.stalls WHERE id = ?", (stall_id,)) # if not rows: # return {"message": "Stall does not exist."} -# products = db.fetchone("SELECT * FROM shop.products WHERE wallet = ?", (rows[1],)) +# products = db.fetchone("SELECT * FROM market.products WHERE wallet = ?", (rows[1],)) # if not products: # return {"message": "No products"} -# return [products.dict() for products in await get_shop_products(rows[1])] +# return [products.dict() for products in await get_market_products(rows[1])] ###Check a product has been shipped -# @shop_ext.get("/api/v1/stall/checkshipped/{checking_id}") -# async def api_shop_stall_checkshipped( +# @market_ext.get("/api/v1/stall/checkshipped/{checking_id}") +# async def api_market_stall_checkshipped( # checking_id, wallet: WalletTypeInfo = Depends(get_key_type) # ): # rows = await db.fetchone( -# "SELECT * FROM shop.orders WHERE invoiceid = ?", (checking_id,) +# "SELECT * FROM market.orders WHERE invoiceid = ?", (checking_id,) # ) # return {"shipped": rows["shipped"]} @@ -418,42 +418,42 @@ async def api_shop_order_shipped( ## -@shop_ext.get("/api/v1/markets") -async def api_shop_markets(wallet: WalletTypeInfo = Depends(get_key_type)): - # await get_shop_market_stalls(market_id="FzpWnMyHQMcRppiGVua4eY") +@market_ext.get("/api/v1/markets") +async def api_market_markets(wallet: WalletTypeInfo = Depends(get_key_type)): + # await get_market_market_stalls(market_id="FzpWnMyHQMcRppiGVua4eY") try: - return [market.dict() for market in await get_shop_markets(wallet.wallet.user)] + return [market.dict() for market in await get_market_markets(wallet.wallet.user)] except: return {"message": "We could not retrieve the markets."} -@shop_ext.get("/api/v1/markets/{market_id}/stalls") -async def api_shop_market_stalls(market_id: str): - stall_ids = await get_shop_market_stalls(market_id) +@market_ext.get("/api/v1/markets/{market_id}/stalls") +async def api_market_market_stalls(market_id: str): + stall_ids = await get_market_market_stalls(market_id) return stall_ids -@shop_ext.post("/api/v1/markets") -@shop_ext.put("/api/v1/markets/{market_id}") -async def api_shop_market_create( +@market_ext.post("/api/v1/markets") +@market_ext.put("/api/v1/markets/{market_id}") +async def api_market_market_create( data: CreateMarket, market_id: str = None, wallet: WalletTypeInfo = Depends(require_invoice_key), ): if market_id: - market = await get_shop_market(market_id) + market = await get_market_market(market_id) if not market: return {"message": "Market does not exist."} if market.usr != wallet.wallet.user: return {"message": "Not your market."} - market = await update_shop_market(market_id, data.name) + market = await update_market_market(market_id, data.name) else: - market = await create_shop_market(data=data) + market = await create_market_market(data=data) assert market - await create_shop_market_stalls(market_id=market.id, data=data.stalls) + await create_market_market_stalls(market_id=market.id, data=data.stalls) return market.dict() @@ -461,39 +461,39 @@ async def api_shop_market_create( ## MESSAGES/CHAT -@shop_ext.get("/api/v1/chat/messages/merchant") +@market_ext.get("/api/v1/chat/messages/merchant") async def api_get_merchant_messages( orders: str = Query(...), wallet: WalletTypeInfo = Depends(require_admin_key) ): - return [msg.dict() for msg in await get_shop_chat_by_merchant(orders.split(","))] + return [msg.dict() for msg in await get_market_chat_by_merchant(orders.split(","))] -@shop_ext.get("/api/v1/chat/messages/{room_name}") +@market_ext.get("/api/v1/chat/messages/{room_name}") async def api_get_latest_chat_msg(room_name: str, all_messages: bool = Query(False)): if all_messages: - messages = await get_shop_chat_messages(room_name) + messages = await get_market_chat_messages(room_name) else: - messages = await get_shop_latest_chat_messages(room_name) + messages = await get_market_latest_chat_messages(room_name) return messages -@shop_ext.get("/api/v1/currencies") +@market_ext.get("/api/v1/currencies") async def api_list_currencies_available(): return list(currencies.keys()) -@shop_ext.get("/api/v1/settings") +@market_ext.get("/api/v1/settings") async def api_get_settings(wallet: WalletTypeInfo = Depends(require_admin_key)): user = wallet.wallet.user - settings = await get_shop_settings(user) + settings = await get_market_settings(user) return settings -@shop_ext.post("/api/v1/settings") -@shop_ext.put("/api/v1/settings/{usr}") +@market_ext.post("/api/v1/settings") +@market_ext.put("/api/v1/settings/{usr}") async def api_set_settings( data: SetSettings, usr: str = None, @@ -501,16 +501,16 @@ async def api_set_settings( ): if usr: if usr != wallet.wallet.user: - return {"message": "Not your Shop."} + return {"message": "Not your Market."} - settings = await get_shop_settings(user=usr) + settings = await get_market_settings(user=usr) assert settings if settings.user != wallet.wallet.user: - return {"message": "Not your Shop."} + return {"message": "Not your Market."} - return await set_shop_settings(usr, data) + return await set_market_settings(usr, data) user = wallet.wallet.user - return await create_shop_settings(user, data) + return await create_market_settings(user, data) diff --git a/lnbits/extensions/shop/config.json b/lnbits/extensions/shop/config.json deleted file mode 100644 index eba0def9..00000000 --- a/lnbits/extensions/shop/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Shop", - "short_description": "Make a webshop on LNbits", - "tile": "/shop/static/images/bitcoin-shop.png", - "contributors": ["benarc", "talvasconcelos"] -}