mirror of
https://github.com/rightup/pyMC_Repeater.git
synced 2026-03-28 17:43:06 +01:00
feat: add endpoint to retrieve adverts by contact type with optional filters
This commit is contained in:
@@ -544,4 +544,60 @@ class SQLiteHandler:
|
||||
"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) -> List[dict]:
|
||||
|
||||
try:
|
||||
with sqlite3.connect(self.sqlite_path) as conn:
|
||||
conn.row_factory = sqlite3.Row
|
||||
|
||||
query = """
|
||||
SELECT id, timestamp, pubkey, node_name, is_repeater, route_type,
|
||||
contact_type, latitude, longitude, first_seen, last_seen,
|
||||
rssi, snr, advert_count, is_new_neighbor
|
||||
FROM adverts
|
||||
WHERE contact_type = ?
|
||||
"""
|
||||
params = [contact_type]
|
||||
|
||||
if hours is not None:
|
||||
cutoff = time.time() - (hours * 3600)
|
||||
query += " AND timestamp > ?"
|
||||
params.append(cutoff)
|
||||
|
||||
query += " ORDER BY timestamp DESC"
|
||||
|
||||
if limit is not None:
|
||||
query += " LIMIT ?"
|
||||
params.append(limit)
|
||||
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
|
||||
adverts = []
|
||||
for row in rows:
|
||||
advert = {
|
||||
"id": row["id"],
|
||||
"timestamp": row["timestamp"],
|
||||
"pubkey": row["pubkey"],
|
||||
"node_name": row["node_name"],
|
||||
"is_repeater": bool(row["is_repeater"]),
|
||||
"route_type": row["route_type"],
|
||||
"contact_type": row["contact_type"],
|
||||
"latitude": row["latitude"],
|
||||
"longitude": row["longitude"],
|
||||
"first_seen": row["first_seen"],
|
||||
"last_seen": row["last_seen"],
|
||||
"rssi": row["rssi"],
|
||||
"snr": row["snr"],
|
||||
"advert_count": row["advert_count"],
|
||||
"is_new_neighbor": bool(row["is_new_neighbor"])
|
||||
}
|
||||
adverts.append(advert)
|
||||
|
||||
logger.debug(f"Found {len(adverts)} adverts with contact_type '{contact_type}'")
|
||||
return adverts
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get adverts by contact_type '{contact_type}': {e}")
|
||||
return []
|
||||
@@ -335,8 +335,8 @@ class APIEndpoints:
|
||||
# Use SQLite directly for packet type graph data since RRD data is too sparse
|
||||
storage = self._get_storage()
|
||||
|
||||
# Get packet type stats from SQLite
|
||||
stats = storage._get_packet_type_stats_sqlite(params['hours'])
|
||||
# Get packet type stats directly from SQLite handler to avoid RRD formatting issues
|
||||
stats = storage.sqlite_handler.get_packet_type_stats(params['hours'])
|
||||
if 'error' in stats:
|
||||
return self._error(stats['error'])
|
||||
|
||||
@@ -621,4 +621,38 @@ class APIEndpoints:
|
||||
|
||||
return generate()
|
||||
|
||||
cad_calibration_stream._cp_config = {'response.stream': True}
|
||||
cad_calibration_stream._cp_config = {'response.stream': True}
|
||||
|
||||
@cherrypy.expose
|
||||
@cherrypy.tools.json_out()
|
||||
@cors_enabled
|
||||
def adverts_by_contact_type(self, contact_type=None, limit=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
|
||||
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
|
||||
)
|
||||
|
||||
return self._success(adverts,
|
||||
count=len(adverts),
|
||||
contact_type=contact_type,
|
||||
filters={
|
||||
"contact_type": contact_type,
|
||||
"limit": limit_int,
|
||||
"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 by contact type: {e}")
|
||||
return self._error(e)
|
||||
Reference in New Issue
Block a user