From 69dcbcb002223916cae0314c16c06acbf51c791b Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 8 Mar 2023 18:33:23 +0200 Subject: [PATCH] feat: optimize filtering for DMs --- crud.py | 43 ++++++++++++++++++-- migrations.py | 3 +- models.py | 3 +- services.py | 23 ++++++++--- static/components/order-list/order-list.html | 6 +-- tasks.py | 18 ++++++-- views_api.py | 2 +- 7 files changed, 79 insertions(+), 19 deletions(-) diff --git a/crud.py b/crud.py index a4d513f..5fbad90 100644 --- a/crud.py +++ b/crud.py @@ -318,8 +318,22 @@ async def delete_product(user_id: str, product_id: str) -> None: async def create_order(user_id: str, o: Order) -> Order: await db.execute( f""" - INSERT INTO nostrmarket.orders (user_id, id, event_id, event_created_at, pubkey, address, contact_data, extra_data, order_items, stall_id, invoice_id, total) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + INSERT INTO nostrmarket.orders ( + user_id, + id, + event_id, + event_created_at, + merchant_public_key, + public_key, + address, + contact_data, + extra_data, + order_items, + stall_id, + invoice_id, + total + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(event_id) DO NOTHING """, ( @@ -327,7 +341,8 @@ async def create_order(user_id: str, o: Order) -> Order: o.id, o.event_id, o.event_created_at, - o.pubkey, + o.merchant_public_key, + o.public_key, o.address, json.dumps(o.contact.dict() if o.contact else {}), json.dumps(o.extra.dict()), @@ -384,6 +399,17 @@ async def get_orders_for_stall(user_id: str, stall_id: str) -> List[Order]: return [Order.from_row(row) for row in rows] +async def get_last_order_time(public_key: str) -> int: + row = await db.fetchone( + """ + SELECT event_created_at FROM nostrmarket.orders + WHERE merchant_public_key = ? ORDER BY event_created_at DESC LIMIT 1 + """, + (public_key,), + ) + return row[0] if row else 0 + + async def update_order_paid_status(order_id: str, paid: bool) -> Optional[Order]: await db.execute( f"UPDATE nostrmarket.orders SET paid = ? WHERE id = ?", @@ -457,3 +483,14 @@ async def get_direct_messages(merchant_id: str, public_key: str) -> List[DirectM (merchant_id, public_key), ) return [DirectMessage.from_row(row) for row in rows] + + +async def get_last_direct_messages_time(public_key: str) -> int: + row = await db.fetchone( + """ + SELECT event_created_at FROM nostrmarket.direct_messages + WHERE public_key = ? ORDER BY event_created_at DESC LIMIT 1 + """, + (public_key), + ) + return row[0] if row else 0 diff --git a/migrations.py b/migrations.py index c52dea3..522fa7b 100644 --- a/migrations.py +++ b/migrations.py @@ -79,7 +79,8 @@ async def m001_initial(db): id TEXT PRIMARY KEY, event_id TEXT, event_created_at INTEGER NOT NULL, - pubkey TEXT NOT NULL, + public_key TEXT NOT NULL, + merchant_public_key TEXT NOT NULL, contact_data TEXT NOT NULL DEFAULT '{empty_object}', extra_data TEXT NOT NULL DEFAULT '{empty_object}', order_items TEXT NOT NULL, diff --git a/models.py b/models.py index c76d25b..379d3f8 100644 --- a/models.py +++ b/models.py @@ -282,7 +282,8 @@ class PartialOrder(BaseModel): id: str event_id: Optional[str] event_created_at: Optional[int] - pubkey: str + public_key: str + merchant_public_key: str items: List[OrderItem] contact: Optional[OrderContact] address: Optional[str] diff --git a/services.py b/services.py index 93de86d..5f11739 100644 --- a/services.py +++ b/services.py @@ -54,7 +54,7 @@ async def create_new_order( payment_hash, invoice = await create_invoice( wallet_id=wallet_id, amount=round(total_amount), - memo=f"Order '{data.id}' for pubkey '{data.pubkey}'", + memo=f"Order '{data.id}' for pubkey '{data.public_key}'", extra={ "tag": "nostrmarket", "order_id": data.id, @@ -107,7 +107,7 @@ async def handle_order_paid(order_id: str, merchant_pubkey: str): order_status.dict(), separators=(",", ":"), ensure_ascii=False ) - dm_event = merchant.build_dm_event(dm_content, order.pubkey) + dm_event = merchant.build_dm_event(dm_content, order.public_key) await publish_nostr_event(dm_event) except Exception as ex: logger.warning(ex) @@ -143,7 +143,12 @@ async def _handle_incoming_dms( event: NostrEvent, merchant: Merchant, clear_text_msg: str ): dm_content = await _handle_dirrect_message( - merchant.id, event.pubkey, event.id, event.created_at, clear_text_msg + merchant.id, + merchant.public_key, + event.pubkey, + event.id, + event.created_at, + clear_text_msg, ) if dm_content: dm_event = merchant.build_dm_event(dm_content, event.pubkey) @@ -166,17 +171,23 @@ async def _handle_outgoing_dms( async def _handle_dirrect_message( - merchant_id: str, from_pubkey: str, event_id: str, event_created_at: int, msg: str + merchant_id: str, + merchant_public_key: str, + from_pubkey: str, + event_id: str, + event_created_at: int, + msg: str, ) -> Optional[str]: order, text_msg = order_from_json(msg) try: if order: - order["pubkey"] = from_pubkey + order["public_key"] = from_pubkey + order["merchant_public_key"] = merchant_public_key order["event_id"] = event_id order["event_created_at"] = event_created_at return await _handle_new_order(PartialOrder(**order)) else: - print("### text_msg", text_msg) + print("### text_msg", text_msg, event_created_at, event_id) dm = PartialDirectMessage( event_id=event_id, event_created_at=event_created_at, diff --git a/static/components/order-list/order-list.html b/static/components/order-list/order-list.html index e629b1f..cdac035 100644 --- a/static/components/order-list/order-list.html +++ b/static/components/order-list/order-list.html @@ -43,8 +43,8 @@ > - - {{toShortId(props.row.pubkey)}} + + {{toShortId(props.row.public_key)}} {{formatDate(props.row.time)}} @@ -115,7 +115,7 @@ dense readonly disabled - v-model.trim="props.row.pubkey" + v-model.trim="props.row.public_key" type="text" > diff --git a/tasks.py b/tasks.py index c1a20ba..7d4d9c4 100644 --- a/tasks.py +++ b/tasks.py @@ -9,7 +9,11 @@ from websocket import WebSocketApp from lnbits.core.models import Payment from lnbits.tasks import register_invoice_listener -from .crud import get_public_keys_for_merchants +from .crud import ( + get_last_direct_messages_time, + get_last_order_time, + get_public_keys_for_merchants, +) from .nostr.nostr_client import connect_to_nostrclient_ws from .services import handle_order_paid, process_nostr_message @@ -68,9 +72,15 @@ async def subscribe_to_nostr_client(recieve_event_queue: Queue, send_req_queue: async def wait_for_nostr_events(recieve_event_queue: Queue, send_req_queue: Queue): public_keys = await get_public_keys_for_merchants() for p in public_keys: - await send_req_queue.put( - ["REQ", f"direct-messages-in:{p}", {"kind": 4, "#p": [p]}] - ) + last_order_time = await get_last_order_time(p) + last_dm_time = await get_last_direct_messages_time(p) + since = max(last_order_time, last_dm_time) + + in_messages_filter = {"kind": 4, "#p": [p]} + if since != 0: + in_messages_filter["since"] = since + print("### in_messages_filter", in_messages_filter) + await send_req_queue.put(["REQ", f"direct-messages-in:{p}", in_messages_filter]) # await send_req_queue.put( # ["REQ", f"direct-messages-out:{p}", {"kind": 4, "authors": [p]}] # ) diff --git a/views_api.py b/views_api.py index b654e0c..1f9aaee 100644 --- a/views_api.py +++ b/views_api.py @@ -500,7 +500,7 @@ async def api_update_order_status( data.paid = order.paid dm_content = json.dumps(data.dict(), separators=(",", ":"), ensure_ascii=False) - dm_event = merchant.build_dm_event(dm_content, order.pubkey) + dm_event = merchant.build_dm_event(dm_content, order.public_key) await publish_nostr_event(dm_event) return order