#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Статистика базы данных WiFi GPS Mapper. Этот модуль ничего не рисует. Он только собирает информацию из SQLite и возвращает обычные словари Python. Отображением занимается dashboard.py. """ from pathlib import Path from .config import ( DATABASE_FILE, CAPTURES_DIR, ) from .database import ( query_value, query_one, ) from .utils import ( format_size, ) # ============================================================ # Размер базы # ============================================================ def database_size(): if not DATABASE_FILE.exists(): return 0 return DATABASE_FILE.stat().st_size # ============================================================ # Размер каталога # ============================================================ def directory_size(path): path = Path(path) if not path.exists(): return 0 total = 0 for file in path.rglob("*"): if file.is_file(): total += file.stat().st_size return total # ============================================================ # Количество файлов # ============================================================ def count_files(path): path = Path(path) if not path.exists(): return 0 total = 0 for file in path.rglob("*"): if file.is_file(): total += 1 return total # ============================================================ # Общая статистика # ============================================================ def database_statistics(conn): statistics = {} statistics["access_points"] = query_value( conn, """ SELECT COUNT(*) FROM access_points """, default=0 ) statistics["access_points_without_coordinates"] = query_value( conn, """ SELECT COUNT(*) FROM access_points WHERE last_latitude IS NULL OR last_longitude IS NULL """, default=0 ) statistics["vendors"] = query_value( conn, """ SELECT COUNT(DISTINCT vendor) FROM access_points WHERE vendor IS NOT NULL AND vendor!='' """, default=0 ) statistics["sessions"] = query_value( conn, """ SELECT COUNT(*) FROM capture_sessions """, default=0 ) statistics["handshakes"] = query_value( conn, """ SELECT COUNT(*) FROM handshakes """, default=0 ) statistics["credentials"] = query_value( conn, """ SELECT COUNT(*) FROM credentials """, default=0 ) statistics["pmkid"] = query_value( conn, """ SELECT COUNT(*) FROM access_points WHERE has_pmkid=1 """, default=0 ) statistics["cracked"] = query_value( conn, """ SELECT COUNT(*) FROM access_points WHERE is_cracked=1 """, default=0 ) statistics["capture_files"] = count_files( CAPTURES_DIR ) statistics["database_size"] = format_size( database_size() ) statistics["captures_size"] = format_size( directory_size( CAPTURES_DIR ) ) row = query_one( conn, """ SELECT MIN(first_seen), MAX(last_seen) FROM access_points """ ) if row: statistics["first_seen"] = row[0] statistics["last_seen"] = row[1] else: statistics["first_seen"] = None statistics["last_seen"] = None return statistics # ============================================================ # Статистика производителей # ============================================================ def top_vendors( conn, limit=20 ): sql = """ SELECT vendor, COUNT(*) AS devices FROM access_points WHERE vendor IS NOT NULL AND vendor!='' GROUP BY vendor ORDER BY devices DESC LIMIT ? """ return conn.execute( sql, ( limit, ) ).fetchall() # ============================================================ # Используемые каналы # ============================================================ def channel_statistics(conn): sql = """ SELECT channel, COUNT(*) AS total FROM access_points GROUP BY channel ORDER BY channel """ return conn.execute(sql).fetchall() # ============================================================ # Типы шифрования # ============================================================ def encryption_statistics(conn): sql = """ SELECT encryption, COUNT(*) AS total FROM access_points GROUP BY encryption ORDER BY total DESC """ return conn.execute(sql).fetchall() # ============================================================ # Самые часто встречающиеся ESSID # ============================================================ def top_essid( conn, limit=25 ): sql = """ SELECT essid, COUNT(*) AS total FROM access_points WHERE essid IS NOT NULL AND essid!='' GROUP BY essid ORDER BY total DESC LIMIT ? """ return conn.execute( sql, ( limit, ) ).fetchall() # ============================================================ # Самые сильные сигналы # ============================================================ def strongest_access_points( conn, limit=20 ): sql = """ SELECT bssid, essid, vendor, last_rssi FROM access_points ORDER BY last_rssi DESC LIMIT ? """ return conn.execute( sql, ( limit, ) ).fetchall()