mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-04 10:26:21 +02:00
Changed naming to Market and Stall
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<h1>Shop</h1>
|
||||
<h1>Market</h1>
|
||||
<h2>A movable market stand</h2>
|
||||
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.
|
||||
<img src="https://i.imgur.com/P1tvBSG.png">
|
||||
|
||||
<h2>API endpoints</h2>
|
@@ -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))
|
6
lnbits/extensions/market/config.json
Normal file
6
lnbits/extensions/market/config.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Market",
|
||||
"short_description": "Webmarket on LNbits",
|
||||
"tile": "/market/static/images/bitcoin-shop.png",
|
||||
"contributors": ["benarc", "talvasconcelos"]
|
||||
}
|
@@ -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" = ?;
|
||||
""",
|
@@ -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)"
|
||||
)
|
@@ -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
|
@@ -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:
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -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)
|
@@ -7,7 +7,7 @@
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-subtitle1 q-my-none">
|
||||
LNbits Shop (Nostr support coming soon)
|
||||
LNbits Market (Nostr support coming soon)
|
||||
</h5>
|
||||
|
||||
<ol>
|
||||
@@ -17,9 +17,9 @@
|
||||
<li>Take orders</li>
|
||||
<li>Includes chat support!</li>
|
||||
</ol>
|
||||
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.
|
||||
<br />
|
||||
<small>
|
||||
@@ -48,7 +48,7 @@
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-light-blue">GET</span>
|
||||
/shop/api/v1/stall/products/<relay_id></code
|
||||
/market/api/v1/stall/products/<relay_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
@@ -73,7 +73,7 @@
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-light-green">POST</span>
|
||||
/shop/api/v1/stall/order/<relay_id></code
|
||||
/market/api/v1/stall/order/<relay_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
|
||||
<code
|
||||
@@ -109,7 +109,7 @@
|
||||
<q-card-section>
|
||||
<code
|
||||
><span class="text-light-blue">GET</span>
|
||||
/shop/api/v1/stall/checkshipped/<checking_id></code
|
||||
/market/api/v1/stall/checkshipped/<checking_id></code
|
||||
>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
@@ -184,7 +184,7 @@
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
<!-- MARKETPLACE/SHOP DIALOG -->
|
||||
<!-- MARKETPLACE/market DIALOG -->
|
||||
<q-dialog v-model="marketDialog.show" position="top">
|
||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
||||
<q-form @submit="sendMarketplaceFormData" class="q-gutter-md">
|
||||
@@ -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)"
|
||||
></q-input>
|
||||
|
||||
<div class="row q-mt-lg">
|
||||
@@ -350,7 +350,7 @@
|
||||
<!-- ONBOARDING DIALOG -->
|
||||
<q-dialog v-model="onboarding.show">
|
||||
<q-card class="q-pa-lg">
|
||||
<h6 class="q-my-md text-primary">How to use Shop</h6>
|
||||
<h6 class="q-my-md text-primary">How to use Market</h6>
|
||||
<q-stepper v-model="step" color="primary" vertical animated>
|
||||
<q-step
|
||||
:name="1"
|
@@ -67,7 +67,7 @@
|
||||
dense
|
||||
size="xs"
|
||||
@click="shipOrder(props.row.id)"
|
||||
icon="add_shopping_cart"
|
||||
icon="add_marketping_cart"
|
||||
color="green"
|
||||
>
|
||||
<q-tooltip> Product shipped? </q-tooltip>
|
||||
@@ -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"
|
||||
></q-btn>
|
||||
<q-tooltip> Stall simple UI shopping cart </q-tooltip>
|
||||
<q-tooltip> Stall simple UI marketping cart </q-tooltip>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ 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"
|
||||
></q-btn>
|
||||
<q-tooltip> Link to pass to stall relay </q-tooltip>
|
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||
%} {% block page %}
|
||||
<div class="row q-col-gutter-md">
|
||||
{% include "shop/_dialogs.html" %}
|
||||
{% include "market/_dialogs.html" %}
|
||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section class="q-gutter-sm row">
|
||||
@@ -60,14 +60,14 @@
|
||||
@click="marketDialog.show = true"
|
||||
>Create Market
|
||||
<q-tooltip>
|
||||
Makes a simple frontend shop for your stalls (not NOSTR)</q-tooltip
|
||||
Makes a simple frontend market for your stalls (not NOSTR)</q-tooltip
|
||||
></q-btn
|
||||
>
|
||||
</q-card-section>
|
||||
<q-separator inset></q-separator>
|
||||
<q-card-section>
|
||||
<div class="text-h6">Shop</div>
|
||||
<div class="text-subtitle2">Make a shop of multiple stalls.</div>
|
||||
<div class="text-h6">Market</div>
|
||||
<div class="text-subtitle2">Make a market of multiple stalls.</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
@@ -87,16 +87,16 @@
|
||||
class="float-right"
|
||||
unelevated
|
||||
color="primary"
|
||||
@click="shopDataDownload"
|
||||
@click="marketDataDownload"
|
||||
>Export all Data
|
||||
<q-tooltip>
|
||||
Export all data (shops, products, orders, etc...)</q-tooltip
|
||||
Export all data (markets, products, orders, etc...)</q-tooltip
|
||||
></q-btn
|
||||
>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
{% include "shop/_tables.html" %}
|
||||
{% include "market/_tables.html" %}
|
||||
<!-- KEYS -->
|
||||
<q-card v-if="keys">
|
||||
<q-card-section>
|
||||
@@ -149,16 +149,16 @@
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
LNbits Shop Extension, powered by Nostr
|
||||
LNbits Market Extension (Nostr support coming soon)
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
<q-list> {% include "shop/_api_docs.html" %} </q-list>
|
||||
<q-list> {% include "market/_api_docs.html" %} </q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<!-- CHAT BOX -->
|
||||
{% include "shop/_chat_box.html" %}
|
||||
{% include "market/_chat_box.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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
|
||||
}
|
@@ -33,7 +33,7 @@
|
||||
<q-card class="card--product">
|
||||
{% raw %}
|
||||
<q-img
|
||||
:src="item.image ? item.image : '/shop/static/images/placeholder.png'"
|
||||
:src="item.image ? item.image : '/market/static/images/placeholder.png'"
|
||||
alt="Product Image"
|
||||
loading="lazy"
|
||||
spinner-color="white"
|
||||
@@ -98,7 +98,7 @@
|
||||
dense
|
||||
color="primary"
|
||||
type="a"
|
||||
:href="'/shop/stalls/' + item.stall"
|
||||
:href="'/market/stalls/' + item.stall"
|
||||
target="_blank"
|
||||
>
|
||||
Visit Stall
|
@@ -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)
|
||||
}
|
||||
})
|
@@ -94,7 +94,7 @@
|
||||
<q-card class="card--product">
|
||||
{% raw %}
|
||||
<q-img
|
||||
:src="item.image ? item.image : '/shop/static/images/placeholder.png'"
|
||||
:src="item.image ? item.image : '/market/static/images/placeholder.png'"
|
||||
alt="Product Image"
|
||||
loading="lazy"
|
||||
spinner-color="white"
|
||||
@@ -431,7 +431,7 @@
|
||||
console.log(this.cart, this.cartMenu)
|
||||
},
|
||||
getPubkey() {
|
||||
let data = this.$q.localStorage.getItem(`lnbits.shop.data`)
|
||||
let data = this.$q.localStorage.getItem(`lnbits.market.data`)
|
||||
if (data && data.keys.publickey) {
|
||||
this.checkoutDialog.data.pubkey = data.keys.publickey
|
||||
} else {
|
||||
@@ -456,7 +456,7 @@
|
||||
})
|
||||
}
|
||||
LNbits.api
|
||||
.request('POST', '/shop/api/v1/orders', null, data)
|
||||
.request('POST', '/market/api/v1/orders', null, data)
|
||||
.then(res => {
|
||||
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)
|
||||
}
|
||||
})
|
@@ -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
|
||||
):
|
@@ -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)
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "Shop",
|
||||
"short_description": "Make a webshop on LNbits",
|
||||
"tile": "/shop/static/images/bitcoin-shop.png",
|
||||
"contributors": ["benarc", "talvasconcelos"]
|
||||
}
|
Reference in New Issue
Block a user