version 1.2.2: исправлен парсинг статистики трафика

- app.py: get_traffic_stats() — позиционный парсинг 8 колонок mita get users, без сканирования суффиксов
- bot.py: cmd_users, cmd_dashboard — единый позиционный парсинг вместо поиска единиц
- README: обновлена дорожная карта
This commit is contained in:
2026-06-26 23:48:32 +03:00
parent 667a0957ac
commit 49db39c877
3 changed files with 49 additions and 69 deletions
+22 -41
View File
@@ -175,35 +175,41 @@ def get_warp_ip():
return "недоступен"
def get_traffic_stats():
"""Возвращает трафик и статус активности по всем пользователям."""
"""Возвращает трафик и статус активности по всем пользователям.
Данные берутся напрямую из mita get users."""
raw = mita_cmd("get", "users")
week_total = month_total = 0.0
users_stats = []
today = datetime.now().date()
# mita get users output format:
# mita get users output format (8 колонок):
# User LastActive 1DayDown 1DayUp 7DaysDown 7DaysUp 30DaysDown 30DaysUp
lines = raw.splitlines()
data_lines = []
for line in lines:
for line in raw.splitlines():
line = line.strip()
if not line or line.upper().startswith("USER"):
continue
data_lines.append(line)
for line in data_lines:
parts = re.split(r"\s{2,}", line.strip())
if len(parts) < 3:
parts = line.split()
if len(parts) < 3:
parts = line.split()
if len(parts) < 8:
continue
try:
name = parts[0]
d1_down = _parse_traffic(parts[2])
d1_up = _parse_traffic(parts[3])
d7_down = _parse_traffic(parts[4])
d7_up = _parse_traffic(parts[5])
d30_down = _parse_traffic(parts[6])
d30_up = _parse_traffic(parts[7])
d1_bytes = d1_down + d1_up
d7_bytes = d7_down + d7_up
d30_bytes = d30_down + d30_up
month_total += d30_bytes
week_total += d7_bytes
# Parse LAST ACTIVE field (parts[1])
last_active_raw = parts[1].strip() if len(parts) > 1 else ""
online = False
last_active_display = "никогда"
last_active_raw = parts[1]
if last_active_raw and last_active_raw.lower() not in ("never", "-", "n/a", "никогда"):
try:
la_date = datetime.strptime(last_active_raw[:10], "%Y-%m-%d").date()
@@ -222,38 +228,13 @@ def get_traffic_stats():
except Exception:
last_active_display = last_active_raw
# Find traffic columns — contain units like MiB, GiB, KiB, B
# mita output: 1DayDown 1DayUp 7DaysDown 7DaysUp 30DaysDown 30DaysUp
traffic_parts = [p for p in parts[1:] if any(u in p for u in ["TiB","GiB","MiB","KiB","iB","B"])]
d1_down = d1_up = d7_down = d7_up = d30_down = d30_up = 0.0
if len(traffic_parts) >= 6:
d1_down = _parse_traffic(traffic_parts[0])
d1_up = _parse_traffic(traffic_parts[1])
d7_down = _parse_traffic(traffic_parts[2])
d7_up = _parse_traffic(traffic_parts[3])
d30_down = _parse_traffic(traffic_parts[4])
d30_up = _parse_traffic(traffic_parts[5])
elif len(traffic_parts) >= 4:
d1_down = _parse_traffic(traffic_parts[0])
d1_up = _parse_traffic(traffic_parts[1])
d30_down = _parse_traffic(traffic_parts[2])
d30_up = _parse_traffic(traffic_parts[3])
elif len(traffic_parts) >= 2:
d30_down = _parse_traffic(traffic_parts[0])
d30_up = _parse_traffic(traffic_parts[1])
else:
continue
d7_bytes = d7_down + d7_up if (d7_down + d7_up) > 0 else (d30_down + d30_up) / 30 * 7
month_total += d30_down + d30_up
week_total += d7_bytes
users_stats.append({
"name": name,
"online": online,
"last_active": last_active_display,
"day_mb": round((d1_down + d1_up) / 1024 / 1024, 2),
"day_mb": round(d1_bytes / 1024 / 1024, 2),
"week_mb": round(d7_bytes / 1024 / 1024, 2),
"month_mb": round((d30_down + d30_up) / 1024 / 1024, 2),
"month_mb": round(d30_bytes / 1024 / 1024, 2),
})
except Exception:
continue