feat: add pagination support and count retrieval for adverts by contact type

This commit is contained in:
Lloyd
2026-05-11 13:54:55 +01:00
parent f3946685c2
commit 941c355deb
2 changed files with 57 additions and 5 deletions
+26 -2
View File
@@ -1557,12 +1557,14 @@ class SQLiteHandler:
return {"rx_total": 0, "tx_total": 0, "drop_total": 0, "type_counts": {}}
def get_adverts_by_contact_type(
self, contact_type: str, limit: Optional[int] = None, hours: Optional[int] = None
self, contact_type: str, limit: Optional[int] = None, offset: Optional[int] = None, hours: Optional[int] = None
) -> List[dict]:
try:
if limit is None:
limit = 500
if offset is None:
offset = 0
with self._connect() as conn:
conn.row_factory = sqlite3.Row
@@ -1584,8 +1586,9 @@ class SQLiteHandler:
query += " ORDER BY timestamp DESC"
if limit is not None:
query += " LIMIT ?"
query += " LIMIT ? OFFSET ?"
params.append(limit)
params.append(offset)
rows = conn.execute(query, params).fetchall()
@@ -1617,6 +1620,27 @@ class SQLiteHandler:
logger.error(f"Failed to get adverts by contact_type '{contact_type}': {e}")
return []
def get_adverts_count_by_contact_type(
self, contact_type: str, hours: Optional[int] = None
) -> int:
"""Get total count of adverts for a specific contact type."""
try:
with self._connect() as conn:
query = "SELECT COUNT(*) as total FROM adverts WHERE contact_type = ?"
params = [contact_type]
if hours is not None:
cutoff = time.time() - (hours * 3600)
query += " AND timestamp > ?"
params.append(cutoff)
row = conn.execute(query, params).fetchone()
return row[0] if row else 0
except Exception as e:
logger.error(f"Failed to get adverts count for contact_type '{contact_type}': {e}")
return 0
def generate_transport_key(self, name: str, key_length_bytes: int = 32) -> str:
"""
Generate a transport key using the proper MeshCore key derivation.
+31 -3
View File
@@ -2267,25 +2267,26 @@ class APIEndpoints:
@cherrypy.expose
@cherrypy.tools.json_out()
def adverts_by_contact_type(self, contact_type=None, limit=None, hours=None):
def adverts_by_contact_type(self, contact_type=None, limit=None, offset=None, hours=None):
try:
if not contact_type:
return self._error("contact_type parameter is required")
limit_int = int(limit) if limit is not None else None
offset_int = int(offset) if offset is not None else None
hours_int = int(hours) if hours is not None else None
storage = self._get_storage()
adverts = storage.sqlite_handler.get_adverts_by_contact_type(
contact_type=contact_type, limit=limit_int, hours=hours_int
contact_type=contact_type, limit=limit_int, offset=offset_int, hours=hours_int
)
return self._success(
adverts,
count=len(adverts),
contact_type=contact_type,
filters={"contact_type": contact_type, "limit": limit_int, "hours": hours_int},
filters={"contact_type": contact_type, "limit": limit_int, "offset": offset_int, "hours": hours_int},
)
except ValueError as e:
@@ -2294,6 +2295,33 @@ class APIEndpoints:
logger.error(f"Error getting adverts by contact type: {e}")
return self._error(e)
@cherrypy.expose
@cherrypy.tools.json_out()
def adverts_count_by_contact_type(self, contact_type=None, hours=None):
"""Get the total count of adverts for a specific contact type."""
try:
if not contact_type:
return self._error("contact_type parameter is required")
hours_int = int(hours) if hours is not None else None
storage = self._get_storage()
count = storage.sqlite_handler.get_adverts_count_by_contact_type(
contact_type=contact_type, hours=hours_int
)
return self._success(
{"count": count},
contact_type=contact_type,
hours=hours_int,
)
except ValueError as e:
return self._error(f"Invalid parameter format: {e}")
except Exception as e:
logger.error(f"Error getting adverts count by contact type: {e}")
return self._error(e)
@cherrypy.expose
@cherrypy.tools.json_out()
def advert_rate_limit_stats(self):