#!/usr/bin/env python3 from __future__ import annotations from api_client import LoginState, Status, UnitState, VpnStatus from .views import LoginView, StatusOverviewView class StatusControllerMixin: def get_login_view(self) -> LoginView: st: LoginState = self.client.get_login_state() # Prefer backend UI-ready "text" if provided, else build it. if st.text: txt = st.text else: if st.email: txt = f"AdGuard VPN: logged in as {st.email}" else: txt = "AdGuard VPN: (no login data)" logged_in = self._is_logged_in_state(st) # Цвет: либо из backend, либо простой нормализованный вариант if st.color: color = st.color else: if logged_in: color = "green" else: s = (st.state or "").strip().lower() color = "orange" if s in ("unknown", "checking") else "red" return LoginView( text=txt, color=color, logged_in=logged_in, email=st.email or "", ) def get_status_overview(self) -> StatusOverviewView: st: Status = self.client.get_status() routes_unit = self._resolve_routes_unit(st.iface) routes_s: UnitState = ( self.client.systemd_state(routes_unit) if routes_unit else UnitState(state="unknown") ) smartdns_s: UnitState = self.client.systemd_state(self.smartdns_unit) vpn_st: VpnStatus = self.client.vpn_status() counts = f"domains={st.domain_count}, ips={st.ip_count}" iface = f"iface={st.iface} table={st.table} mark={st.mark}" policy_route = self._format_policy_route(st.policy_route_ok, st.route_ok) # SmartDNS: если state пустой/unknown — считаем это ошибкой smart_state = smartdns_s.state or "unknown" if smart_state.lower() in ("", "unknown", "failed"): smart_state = "ERROR (unknown state)" return StatusOverviewView( timestamp=st.timestamp or "—", counts=counts, iface_table_mark=iface, policy_route=policy_route, routes_service=f"{routes_unit or 'selective-vpn2@.service'}: {routes_s.state}", smartdns_service=f"{self.smartdns_unit}: {smart_state}", # это состояние самого VPN-юнита, НЕ autoloop: # т.е. работает ли AdGuardVPN-daemon / туннель vpn_service=f"VPN: {vpn_st.unit_state}", )