75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
#!/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@<auto>.service'}: {routes_s.state}",
|
||
smartdns_service=f"{self.smartdns_unit}: {smart_state}",
|
||
# это состояние самого VPN-юнита, НЕ autoloop:
|
||
# т.е. работает ли AdGuardVPN-daemon / туннель
|
||
vpn_service=f"VPN: {vpn_st.unit_state}",
|
||
)
|
||
|