src/ande_ban/events.py:12:def record_event(
src/ande_ban/campaigns.py:24:def _parse_timestamp(value: Any) -> datetime | None:
src/ande_ban/campaigns.py:45:def _campaign_status(
src/ande_ban/campaigns.py:65:def _campaign_id(organization: str, asn: int) -> str:
src/ande_ban/campaigns.py:73:def _bounded_score(value: int, maximum_value: int, points: int) -> int:
src/ande_ban/campaigns.py:85:def _threat_level(score: int) -> str:
src/ande_ban/campaigns.py:100:def calculate_campaign_confidence(
src/ande_ban/campaigns.py:133:def get_campaigns(
src/ande_ban/policy.py:9:class Decision:
src/ande_ban/policy.py:17:def decide(settings: Settings, ip: str, country: str | None, offense_number: int) -> Decision:
src/ande_ban/metrics.py:12:def _meminfo() -> dict[str, int]:
src/ande_ban/metrics.py:23:def _age_seconds(path: Path) -> int | None:
src/ande_ban/metrics.py:30:def collect_system_metrics(conn, settings) -> dict[str, Any]:
src/ande_ban/storage/factory.py:11:def get_backend(
src/ande_ban/storage/base.py:10:class CursorProtocol(Protocol):
src/ande_ban/storage/base.py:34:class ConnectionProtocol(Protocol):
src/ande_ban/storage/base.py:72:class StorageBackend(ABC):
src/ande_ban/storage/sqlite.py:14:class SQLiteBackend(StorageBackend):
src/ande_ban/diagnostics.py:17:class DiagnosticCheck:
src/ande_ban/diagnostics.py:32:def _mode(path: Path) -> str:
src/ande_ban/diagnostics.py:36:def _path_check(name: str, path: Path, *, required: bool = True) -> DiagnosticCheck:
src/ande_ban/diagnostics.py:46:def _command_check(
src/ande_ban/diagnostics.py:71:def _parse_utc(value: str) -> datetime:
src/ande_ban/diagnostics.py:79:def _sync_freshness_check(
src/ande_ban/diagnostics.py:119:def run_diagnostics(
src/ande_ban/cli.py:17:def build_parser() -> argparse.ArgumentParser:
src/ande_ban/cli.py:71:def main() -> None:
src/ande_ban/database.py:89:def _columns(conn: sqlite3.Connection, table: str) -> set[str]:
src/ande_ban/database.py:93:def _add_columns(
src/ande_ban/database.py:107:def _migrate(conn: sqlite3.Connection) -> None:
src/ande_ban/database.py:143:def _secure_database_permissions(path: Path) -> None:
src/ande_ban/database.py:157:def connect(path: Path) -> sqlite3.Connection:
src/ande_ban/database.py:167:def offense_count(conn: sqlite3.Connection, ip: str) -> int:
src/ande_ban/webapp.py:40:def _service_state(name: str) -> str:
src/ande_ban/webapp.py:54:def handler_factory(
src/ande_ban/webapp.py:268:def main():
src/ande_ban/enrich_history.py:13:class EnrichmentStats:
src/ande_ban/enrich_history.py:21:def enrich_history(
src/ande_ban/enrich_history.py:152:def _build_parser() -> argparse.ArgumentParser:
src/ande_ban/enrich_history.py:180:def main() -> int:
src/ande_ban/api.py:9:def utc_timestamp() -> str:
src/ande_ban/api.py:13:def success(data: Any, *, metadata: dict[str, Any] | None = None) -> dict[str, Any]:
src/ande_ban/api.py:25:def error(code: str, message: str, *, details: Any = None) -> dict[str, Any]:
src/ande_ban/administration.py:30:def database_statistics(settings: Settings) -> dict[str, Any]:
src/ande_ban/administration.py:54:def maintain_database(settings: Settings, *, analyze: bool = True, vacuum: bool = False, force: bool = False) -> dict[str, Any]:
src/ande_ban/administration.py:68:def recent_logs(
src/ande_ban/administration.py:90:def list_backups(directory: str | Path, *, limit: int = 50) -> dict[str, Any]:
src/ande_ban/administration.py:108:def _redacted_config(config_path: Path) -> str:
src/ande_ban/administration.py:120:def create_diagnostic_bundle(
src/ande_ban/sync.py:13:def _run(*args: str) -> str:
src/ande_ban/sync.py:26:def _jails() -> list[str]:
src/ande_ban/sync.py:38:def _status_number(status: str, label: str) -> int:
src/ande_ban/sync.py:47:def _utc_now() -> str:
src/ande_ban/sync.py:51:def _store_sync_run(
src/ande_ban/sync.py:89:def sync_fail2ban(settings: Settings) -> dict:
src/ande_ban/geo_providers/manager.py:10:def _providers(
src/ande_ban/geo_providers/manager.py:44:def lookup(
src/ande_ban/geo_providers/mmdb.py:10:class MMDBProvider:
src/ande_ban/geo_providers/null.py:6:class NullProvider:
src/ande_ban/geo_providers/base.py:8:class GeoRecord:
src/ande_ban/geo_providers/base.py:31:class GeoProvider(Protocol):
src/ande_ban/maintenance.py:20:def validate_configuration(path: str | Path) -> dict[str, Any]:
src/ande_ban/maintenance.py:43:def _sha256(path: Path) -> str:
src/ande_ban/maintenance.py:51:def create_backup(settings: Settings, config_path: str | Path, output: str | Path | None = None) -> dict[str, Any]:
src/ande_ban/maintenance.py:78:def _safe_members(tf: tarfile.TarFile) -> None:
src/ande_ban/maintenance.py:89:def inspect_backup(archive: str | Path) -> dict[str, Any]:
src/ande_ban/maintenance.py:110:def restore_backup(settings: Settings, config_path: str | Path, archive: str | Path, force: bool = False) -> dict[str, Any]:
src/ande_ban/maintenance.py:131:def upgrade_check(settings: Settings, config_path: str | Path) -> dict[str, Any]:
src/ande_ban/events.py.before-storage:11:def record_event(
src/ande_ban/config.py:10:class PolicyTier:
src/ande_ban/config.py:15:class Settings:
src/ande_ban/config.py:31:def _duration(value: str) -> int | None:
src/ande_ban/config.py:41:def _tiers(value: str) -> list[PolicyTier]:
src/ande_ban/config.py:45:def load_settings(path: str | Path = "/etc/ande-ban/ande-ban.ini") -> Settings:
src/ande_ban/geoip.py:9:def lookup_geo(
src/ande_ban/geoip.py:25:def lookup_country(
src/ande_ban/analytics.py:34:def ensure_analytics_indexes(conn: sqlite3.Connection) -> None:
src/ande_ban/analytics.py:39:def _rows(
src/ande_ban/analytics.py:50:def _threat_score(
src/ande_ban/analytics.py:75:def _threat_level(score: int) -> str:
src/ande_ban/analytics.py:85:def _activity_24h(conn: sqlite3.Connection) -> list[dict[str, Any]]:
src/ande_ban/analytics.py:130:def get_analytics(conn: sqlite3.Connection) -> dict[str, Any]:
src/ande_ban/analytics.py:372:def get_range_analytics(
