MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / get_count_snapshot

Method get_count_snapshot

db_manager.py:1317–1367  ·  view source on GitHub ↗

Cheap aggregate counts used to seed in-memory counters at boot. Mirrors the filtering logic in webapp_modern.sync_all_counts() so the dashboard shows correct numbers from the first /api/status response instead of starting at 0 until the deferred full sync completes.

(self)

Source from the content-addressed store, hash-verified

1315 cursor.execute("SELECT COUNT(*) FROM hosts WHERE vulnerabilities != '' AND vulnerabilities IS NOT NULL")
1316 stats['hosts_with_vulns'] = cursor.fetchone()[0]
1317
1318 # Total scans
1319 cursor.execute("SELECT COUNT(*) FROM scan_history")
1320 stats['total_scans'] = cursor.fetchone()[0]
1321
1322 return stats
1323 except Exception as e:
1324 logger.error(f"Failed to get stats: {e}")
1325 return {}
1326
1327 def get_count_snapshot(self) -> dict:
1328 """Cheap aggregate counts used to seed in-memory counters at boot.
1329
1330 Mirrors the filtering logic in webapp_modern.sync_all_counts() so the
1331 dashboard shows correct numbers from the first /api/status response
1332 instead of starting at 0 until the deferred full sync completes.
1333
1334 Returns {active_targets, inactive_targets, total_targets, total_ports}.
1335 """
1336 snapshot = {
1337 'active_targets': 0,
1338 'inactive_targets': 0,
1339 'total_targets': 0,
1340 'total_ports': 0,
1341 }
1342 try:
1343 with self.get_connection() as conn:
1344 cursor = conn.cursor()
1345
1346 # Match sync_all_counts() filtering: drop STANDALONE rows and rows missing IP
1347 base_filter = "WHERE mac != 'STANDALONE' AND ip IS NOT NULL AND ip != ''"
1348
1349 cursor.execute(f"SELECT COUNT(*) FROM hosts {base_filter}")
1350 snapshot['total_targets'] = cursor.fetchone()[0]
1351
1352 cursor.execute(f"SELECT COUNT(*) FROM hosts {base_filter} AND status = 'alive'")
1353 snapshot['active_targets'] = cursor.fetchone()[0]
1354
1355 cursor.execute(f"SELECT COUNT(*) FROM hosts {base_filter} AND status != 'alive'")
1356 snapshot['inactive_targets'] = cursor.fetchone()[0]
1357
1358 # Sum port-list lengths only for alive hosts (matches sync logic)
1359 cursor.execute(
1360 f"SELECT ports FROM hosts {base_filter} AND status = 'alive' "
1361 "AND ports IS NOT NULL AND ports != '' AND ports != '0'"
1362 )
1363 total_ports = 0
1364 for (ports_str,) in cursor.fetchall():
1365 if not ports_str:
1366 continue
1367 delim = ',' if ',' in ports_str else ';'
1368 for token in ports_str.split(delim):
1369 token = token.strip()
1370 if token and token != '0' and token.isdigit():

Callers 1

_seed_counts_from_dbMethod · 0.80

Calls 6

get_connectionMethod · 0.95
cursorMethod · 0.80
warningMethod · 0.80
executeMethod · 0.45
fetchoneMethod · 0.45
fetchallMethod · 0.45

Tested by

no test coverage detected