mirror of
https://github.com/rightup/pyMC_Repeater.git
synced 2026-05-10 07:24:28 +02:00
Add node name lookup by public key and enhance CORS handling in API endpoints
This commit is contained in:
@@ -186,6 +186,27 @@ class StorageCollector:
|
||||
|
||||
def get_neighbors(self) -> dict:
|
||||
return self.sqlite_handler.get_neighbors()
|
||||
|
||||
def get_node_name_by_pubkey(self, pubkey: str) -> Optional[str]:
|
||||
"""
|
||||
Lookup node name from adverts table by public key.
|
||||
|
||||
Args:
|
||||
pubkey: Public key in hex string format
|
||||
|
||||
Returns:
|
||||
Node name if found, None otherwise
|
||||
"""
|
||||
try:
|
||||
with self.sqlite_handler.get_connection() as conn:
|
||||
result = conn.execute(
|
||||
"SELECT node_name FROM adverts WHERE pubkey = ? AND node_name IS NOT NULL ORDER BY last_seen DESC LIMIT 1",
|
||||
(pubkey,)
|
||||
).fetchone()
|
||||
return result[0] if result else None
|
||||
except Exception as e:
|
||||
logger.debug(f"Could not lookup node name for {pubkey[:8] if pubkey else 'None'}: {e}")
|
||||
return None
|
||||
|
||||
def cleanup_old_data(self, days: int = 7):
|
||||
self.sqlite_handler.cleanup_old_data(days)
|
||||
|
||||
@@ -207,12 +207,24 @@ class RoomServer:
|
||||
f"{client_pubkey[:4].hex()}: {message_text[:50]}"
|
||||
)
|
||||
|
||||
# Update client activity timestamp (they're clearly active if posting)
|
||||
# This prevents them from being evicted while they're actively posting
|
||||
# Log authenticated clients count for debugging distribution
|
||||
all_clients = self.acl.get_all_clients()
|
||||
logger.info(
|
||||
f"Room '{self.room_name}': Message stored, will distribute to "
|
||||
f"{len(all_clients)} authenticated client(s)"
|
||||
)
|
||||
|
||||
# Update client's sync_since to this message's timestamp
|
||||
# This prevents the author from receiving their own message back
|
||||
# Also update activity timestamp (they're clearly active if posting)
|
||||
logger.debug(
|
||||
f"Room '{self.room_name}': Updating author's sync_since to {post_timestamp} "
|
||||
f"to prevent echo"
|
||||
)
|
||||
self.db.upsert_client_sync(
|
||||
room_hash=f"0x{self.room_hash:02X}",
|
||||
client_pubkey=client_pubkey.hex(),
|
||||
sync_since=0, # Will be preserved if already set
|
||||
sync_since=post_timestamp, # Don't send this message back to author
|
||||
last_activity=time.time()
|
||||
)
|
||||
|
||||
@@ -488,9 +500,15 @@ class RoomServer:
|
||||
# Get all clients for this room
|
||||
all_clients = self.acl.get_all_clients()
|
||||
if not all_clients:
|
||||
logger.debug(f"Room '{self.room_name}': No authenticated clients found")
|
||||
self.next_push_time = time.time() + 1.0 # Check again in 1 second
|
||||
continue
|
||||
|
||||
logger.debug(
|
||||
f"Room '{self.room_name}': Found {len(all_clients)} authenticated client(s), "
|
||||
f"checking for unsynced messages"
|
||||
)
|
||||
|
||||
# SAFETY: Limit number of clients
|
||||
if len(all_clients) > MAX_CLIENTS_PER_ROOM:
|
||||
logger.warning(
|
||||
@@ -555,6 +573,12 @@ class RoomServer:
|
||||
last_activity=time.time()
|
||||
)
|
||||
|
||||
# Log the sync check for debugging
|
||||
logger.debug(
|
||||
f"Room '{self.room_name}': Checking client 0x{client.id.get_public_key()[0]:02X} "
|
||||
f"for messages newer than sync_since={sync_since:.1f}"
|
||||
)
|
||||
|
||||
# Find next unsynced message for this client
|
||||
unsynced = self.db.get_unsynced_messages(
|
||||
room_hash=f"0x{self.room_hash:02X}",
|
||||
@@ -565,6 +589,10 @@ class RoomServer:
|
||||
|
||||
if unsynced:
|
||||
post = unsynced[0]
|
||||
logger.debug(
|
||||
f"Room '{self.room_name}': Client 0x{client.id.get_public_key()[0]:02X} "
|
||||
f"has unsynced message #{post['id']}, post_timestamp={post['post_timestamp']:.1f}"
|
||||
)
|
||||
# Check if enough time has passed since post creation
|
||||
now = time.time()
|
||||
if now >= post['post_timestamp'] + POST_SYNC_DELAY_SECS:
|
||||
|
||||
@@ -2069,6 +2069,12 @@ class APIEndpoints:
|
||||
}
|
||||
}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
room_info = self._get_room_server_by_name_or_hash(room_name, room_hash)
|
||||
room_server = room_info['room_server']
|
||||
@@ -2094,7 +2100,8 @@ class APIEndpoints:
|
||||
offset=int(offset)
|
||||
)
|
||||
|
||||
# Format messages with author prefix
|
||||
# Format messages with author prefix and lookup sender names
|
||||
storage = self._get_storage()
|
||||
formatted_messages = []
|
||||
for msg in messages:
|
||||
author_pubkey = msg['author_pubkey']
|
||||
@@ -2108,6 +2115,13 @@ class APIEndpoints:
|
||||
'txt_type': msg['txt_type'],
|
||||
'created_at': msg.get('created_at', msg['post_timestamp'])
|
||||
}
|
||||
|
||||
# Lookup sender name from adverts table
|
||||
if author_pubkey:
|
||||
author_name = storage.get_node_name_by_pubkey(author_pubkey)
|
||||
if author_name:
|
||||
formatted_msg['author_name'] = author_name
|
||||
|
||||
formatted_messages.append(formatted_msg)
|
||||
|
||||
return self._success({
|
||||
@@ -2146,6 +2160,12 @@ class APIEndpoints:
|
||||
Returns:
|
||||
{"success": true, "data": {"message_id": 123}}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
self._require_post()
|
||||
|
||||
@@ -2268,6 +2288,12 @@ class APIEndpoints:
|
||||
}
|
||||
}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
if not self.daemon_instance or not hasattr(self.daemon_instance, 'text_helper'):
|
||||
return self._error("Text helper not available")
|
||||
@@ -2399,6 +2425,12 @@ class APIEndpoints:
|
||||
}
|
||||
}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
# Reuse room_stats logic but return only clients
|
||||
stats = self.room_stats(room_name=room_name, room_hash=room_hash)
|
||||
@@ -2431,6 +2463,12 @@ class APIEndpoints:
|
||||
Returns:
|
||||
{"success": true}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
if cherrypy.request.method != "DELETE":
|
||||
cherrypy.response.status = 405
|
||||
@@ -2473,6 +2511,12 @@ class APIEndpoints:
|
||||
Returns:
|
||||
{"success": true, "data": {"deleted_count": 123}}
|
||||
"""
|
||||
# Enable CORS for this endpoint only if configured
|
||||
self._set_cors_headers()
|
||||
|
||||
if cherrypy.request.method == "OPTIONS":
|
||||
return ""
|
||||
|
||||
try:
|
||||
if cherrypy.request.method != "DELETE":
|
||||
cherrypy.response.status = 405
|
||||
|
||||
Reference in New Issue
Block a user