platform: modularize api/gui, add docs-tests-web foundation, and refresh root config

This commit is contained in:
beckline
2026-03-26 22:40:54 +03:00
parent 0e2d7f61ea
commit 6a56d734c2
562 changed files with 70151 additions and 16423 deletions

View File

@@ -0,0 +1,74 @@
#!/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}",
)