Product delete (#64)
* feat: restore stalls from `nostr` as pending * feat: stall and prod last update time * feat: restore products and stalls as `pending` * feat: show pending stalls * feat: restore stall * feat: restore a stall from nostr * feat: add blank `Restore Product` button * fix: handle no talls to restore case * feat: show restore dialog * feat: allow query for pending products * feat: restore products * chore: code clean-up * fix: last dm and last order query * chore: code clean-up * fix: subscribe for stalls and products on merchant create/restore * feat: add message type to orders * feat: simplify messages; code format * feat: add type to DMs; restore DMs from nostr * fix: parsing ints * fix: hide copy button if invoice not present * fix: do not generate invoice if product not found * feat: order restore: first version * refactor: move some logic into `services` * feat: improve restore UX * fix: too many calls to customer DMs * fix: allow `All` customers filter * fix: ws reconnect on server restart * fix: query for customer profiles only one * fix: unread messages per customer per merchant * fix: disable `user-profile-events` * fix: customer profile is optional * fix: get customers after new message debounced * chore: code clean-up * feat: auto-create zone * feat: fixed ID for default zone * feat: notify order paid
This commit is contained in:
parent
1cb8fe86b1
commit
51c4147e65
17 changed files with 934 additions and 610 deletions
|
|
@ -2,7 +2,7 @@ import asyncio
|
|||
import json
|
||||
from asyncio import Queue
|
||||
from threading import Thread
|
||||
from typing import Callable
|
||||
from typing import Callable, List
|
||||
|
||||
from loguru import logger
|
||||
from websocket import WebSocketApp
|
||||
|
|
@ -18,11 +18,6 @@ class NostrClient:
|
|||
self.send_req_queue: Queue = Queue()
|
||||
self.ws: WebSocketApp = None
|
||||
|
||||
async def restart(self):
|
||||
await self.send_req_queue.put(ValueError("Restarting NostrClient..."))
|
||||
await self.recieve_event_queue.put(ValueError("Restarting NostrClient..."))
|
||||
self.ws.close()
|
||||
self.ws = None
|
||||
|
||||
async def connect_to_nostrclient_ws(
|
||||
self, on_open: Callable, on_message: Callable
|
||||
|
|
@ -96,36 +91,80 @@ class NostrClient:
|
|||
["REQ", f"direct-messages-out:{public_key}", out_messages_filter]
|
||||
)
|
||||
|
||||
async def subscribe_to_merchant_events(self, public_key: str, since: int):
|
||||
logger.debug(f"Subscribed to direct-messages '{public_key}'.")
|
||||
|
||||
async def subscribe_to_stall_events(self, public_key: str, since: int):
|
||||
stall_filter = {"kinds": [30017], "authors": [public_key]}
|
||||
product_filter = {"kinds": [30018], "authors": [public_key]}
|
||||
if since and since != 0:
|
||||
stall_filter["since"] = since
|
||||
|
||||
await self.send_req_queue.put(
|
||||
["REQ", f"stall-events:{public_key}", stall_filter]
|
||||
)
|
||||
|
||||
logger.debug(f"Subscribed to stall-events: '{public_key}'.")
|
||||
|
||||
async def subscribe_to_product_events(self, public_key: str, since: int):
|
||||
product_filter = {"kinds": [30018], "authors": [public_key]}
|
||||
if since and since != 0:
|
||||
product_filter["since"] = since
|
||||
|
||||
await self.send_req_queue.put(
|
||||
["REQ", f"product-events:{public_key}", product_filter]
|
||||
)
|
||||
logger.debug(f"Subscribed to product-events: '{public_key}'.")
|
||||
|
||||
|
||||
async def subscribe_to_user_profile(self, public_key: str, since: int):
|
||||
profile_filter = {"kinds": [0], "authors": [public_key]}
|
||||
if since and since != 0:
|
||||
profile_filter["since"] = since + 1
|
||||
|
||||
await self.send_req_queue.put(
|
||||
["REQ", f"user-profile-events:{public_key}", profile_filter]
|
||||
)
|
||||
# Disabled for now. The number of clients can grow large.
|
||||
# Some relays only allow a small number of subscriptions.
|
||||
# There is the risk that more important subscriptions will be blocked.
|
||||
# await self.send_req_queue.put(
|
||||
# ["REQ", f"user-profile-events:{public_key}", profile_filter]
|
||||
# )
|
||||
|
||||
async def unsubscribe_from_direct_messages(self, public_key: str):
|
||||
await self.send_req_queue.put(["CLOSE", f"direct-messages-in:{public_key}"])
|
||||
await self.send_req_queue.put(["CLOSE", f"direct-messages-out:{public_key}"])
|
||||
|
||||
logger.debug(f"Unsubscribed from direct-messages '{public_key}'.")
|
||||
|
||||
async def unsubscribe_from_merchant_events(self, public_key: str):
|
||||
await self.send_req_queue.put(["CLOSE", f"stall-events:{public_key}"])
|
||||
await self.send_req_queue.put(["CLOSE", f"product-events:{public_key}"])
|
||||
|
||||
def stop(self):
|
||||
try:
|
||||
self.ws.close()
|
||||
except Exception as ex:
|
||||
logger.warning(ex)
|
||||
logger.debug(f"Unsubscribed from stall-events and product-events '{public_key}'.")
|
||||
|
||||
async def restart(self, public_keys: List[str]):
|
||||
await self.unsubscribe_merchants(public_keys)
|
||||
# Give some time for the CLOSE events to propagate before restarting
|
||||
await asyncio.sleep(10)
|
||||
|
||||
logger.info("Restating NostrClient...")
|
||||
await self.send_req_queue.put(ValueError("Restarting NostrClient..."))
|
||||
await self.recieve_event_queue.put(ValueError("Restarting NostrClient..."))
|
||||
|
||||
self.ws.close()
|
||||
self.ws = None
|
||||
|
||||
|
||||
async def stop(self, public_keys: List[str]):
|
||||
await self.unsubscribe_merchants(public_keys)
|
||||
|
||||
# Give some time for the CLOSE events to propagate before closing the connection
|
||||
await asyncio.sleep(10)
|
||||
self.ws.close()
|
||||
self.ws = None
|
||||
|
||||
async def unsubscribe_merchants(self, public_keys: List[str]):
|
||||
for pk in public_keys:
|
||||
try:
|
||||
await self.unsubscribe_from_direct_messages(pk)
|
||||
await self.unsubscribe_from_merchant_events(pk)
|
||||
except Exception as ex:
|
||||
logger.warning(ex)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue