#!/usr/bin/env python3 from __future__ import annotations from dataclasses import dataclass from typing import List, Literal from api_client import TransportConflict, TransportPolicyIntent TraceMode = Literal["full", "gui", "smartdns"] ServiceAction = Literal["start", "stop", "restart"] LoginAction = Literal["open", "check", "cancel"] TransportClientAction = Literal["provision", "start", "stop", "restart"] TransportFlowPhase = Literal["draft", "validated", "risky", "confirm", "applied", "error"] @dataclass(frozen=True) class LoginView: text: str color: str logged_in: bool email: str @dataclass(frozen=True) class StatusOverviewView: timestamp: str counts: str iface_table_mark: str policy_route: str routes_service: str smartdns_service: str vpn_service: str @dataclass(frozen=True) class VpnStatusView: desired_location: str pretty_text: str @dataclass(frozen=True) class ActionView: ok: bool pretty_text: str @dataclass(frozen=True) class LoginFlowView: phase: str level: str dot_color: str status_text: str url: str email: str alive: bool cursor: int lines: List[str] can_open: bool can_check: bool can_cancel: bool @dataclass(frozen=True) class VpnAutoconnectView: """Для блока Autoconnect на вкладке AdGuardVPN.""" enabled: bool # True = включён autoloop unit_text: str # строка вида "unit: active" color: str # "green" / "red" / "orange" @dataclass(frozen=True) class RoutesNftProgressView: """Прогресс обновления nft-наборов (agvpn4).""" percent: int message: str active: bool # True — пока идёт апдейт, False — когда закончили / ничего не идёт @dataclass(frozen=True) class TrafficModeView: desired_mode: str applied_mode: str preferred_iface: str advanced_active: bool auto_local_bypass: bool auto_local_active: bool ingress_reply_bypass: bool ingress_reply_active: bool bypass_candidates: int force_vpn_subnets: List[str] force_vpn_uids: List[str] force_vpn_cgroups: List[str] force_direct_subnets: List[str] force_direct_uids: List[str] force_direct_cgroups: List[str] overrides_applied: int cgroup_resolved_uids: int cgroup_warning: str active_iface: str iface_reason: str ingress_rule_present: bool ingress_nft_active: bool probe_ok: bool probe_message: str healthy: bool message: str @dataclass(frozen=True) class RoutesResolveSummaryView: available: bool text: str recheck_text: str color: str recheck_color: str @dataclass(frozen=True) class TransportPolicyFlowView: phase: TransportFlowPhase intents: List[TransportPolicyIntent] base_revision: int current_revision: int applied_revision: int confirm_token: str valid: bool block_count: int warn_count: int diff_added: int diff_changed: int diff_removed: int conflicts: List[TransportConflict] apply_id: str rollback_available: bool message: str code: str