Compare commits
2 Commits
a6b3c54534
...
a30239a4fe
| Author | SHA1 | Date | |
|---|---|---|---|
| a30239a4fe | |||
| 52abd9d1f7 |
@@ -560,7 +560,7 @@ async def cleanup_inactive_sessions():
|
|||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
"""Управление жизненным циклом приложения"""
|
"""Управление жизненным циклом приложения"""
|
||||||
global rooms, clients, admin_sessions, client_websockets, admin_websockets
|
global rooms, clients, admin_sessions, client_websockets, admin_websockets
|
||||||
global video_queues, command_queues, room_stats, server_stats, stats_lock, cleanup_task, templates
|
global video_queues, command_queues, room_stats, server_stats, stats_lock, cleanup_task, templates, admin_frame_queues
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
stats_lock = threading.Lock()
|
stats_lock = threading.Lock()
|
||||||
@@ -660,11 +660,13 @@ async def login_form(request: Request, username: str = Form(...), password: str
|
|||||||
"last_activity": datetime.now().isoformat(),
|
"last_activity": datetime.now().isoformat(),
|
||||||
"is_authenticated": True
|
"is_authenticated": True
|
||||||
}
|
}
|
||||||
|
print(f"[Auth] ✓ Admin logged in: {username}, session_id={session_id[:16]}..., total sessions: {len(admin_sessions)}")
|
||||||
|
|
||||||
response = RedirectResponse(url="/dashboard", status_code=303)
|
response = RedirectResponse(url="/dashboard", status_code=303)
|
||||||
response.set_cookie(key="session_id", value=session_id)
|
response.set_cookie(key="session_id", value=session_id)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
print(f"[Auth] ❌ Failed login attempt: {username}")
|
||||||
server_host = get_server_host()
|
server_host = get_server_host()
|
||||||
return templates.TemplateResponse("login.html", {
|
return templates.TemplateResponse("login.html", {
|
||||||
"request": request,
|
"request": request,
|
||||||
|
|||||||
117
test_admin_watch.py
Normal file
117
test_admin_watch.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Скрипт для подключения админа и просмотра видео от клиента
|
||||||
|
Требует, чтобы есть активное подключение клиента, отправляющего кадры
|
||||||
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import websockets
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Загружаем переменные окружения из .env
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Параметры подключения
|
||||||
|
HOST = os.getenv("PUBLIC_HOST", "192.168.0.112")
|
||||||
|
PORT = int(os.getenv("PORT", 8000))
|
||||||
|
|
||||||
|
# Учетные данные админа (из server.py)
|
||||||
|
ADMIN_USERNAME = "admin"
|
||||||
|
ADMIN_PASSWORD = "admin123"
|
||||||
|
|
||||||
|
async def admin_watch():
|
||||||
|
"""Админ логинится и смотрит видео от клиента"""
|
||||||
|
|
||||||
|
# 1. Логинимся как админ
|
||||||
|
print(f"[Admin] Logging in as {ADMIN_USERNAME}...")
|
||||||
|
session = requests.Session()
|
||||||
|
try:
|
||||||
|
login_response = session.post(
|
||||||
|
f"http://{HOST}:{PORT}/login",
|
||||||
|
data={
|
||||||
|
"username": ADMIN_USERNAME,
|
||||||
|
"password": ADMIN_PASSWORD
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if login_response.status_code != 303 and login_response.status_code != 200:
|
||||||
|
print(f"[Admin] ❌ Failed to login: {login_response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Получаем session_id из cookies
|
||||||
|
session_id = session.cookies.get("session_id")
|
||||||
|
if not session_id:
|
||||||
|
print(f"[Admin] ❌ No session_id in cookies")
|
||||||
|
print(f"[Admin] Cookies: {session.cookies}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"[Admin] ✓ Logged in, session_id: {session_id[:16]}...")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Admin] ❌ Login error: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 2. Получаем список активных комнат и клиентов
|
||||||
|
print(f"[Admin] Getting active clients...")
|
||||||
|
try:
|
||||||
|
dashboard_response = session.get(f"http://{HOST}:{PORT}/dashboard")
|
||||||
|
if dashboard_response.status_code != 200:
|
||||||
|
print(f"[Admin] ❌ Failed to get dashboard: {dashboard_response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Парсим HTML чтобы найти client_id (это сложновато, используем API)
|
||||||
|
# Для простоты - просто выведем сообщение о том, как найти client_id
|
||||||
|
print(f"[Admin] 💡 Open http://{HOST}:{PORT}/dashboard in browser to see active clients")
|
||||||
|
print(f"[Admin] 💡 Look for client_id in the page source or network tab")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Admin] ❌ Error: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 3. Для тестирования подключимся к вебсокету админа
|
||||||
|
uri = f"ws://{HOST}:{PORT}/ws/admin/{session_id}"
|
||||||
|
print(f"[Admin] Connecting to WebSocket: {uri}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with websockets.connect(uri) as ws:
|
||||||
|
# Получаем ответ сервера
|
||||||
|
response = await asyncio.wait_for(ws.recv(), timeout=5)
|
||||||
|
print(f"[Admin] ✓ Server response: {response}")
|
||||||
|
|
||||||
|
# Пример: отправляем команду "watch_client"
|
||||||
|
# Вам нужно знать client_id активного клиента
|
||||||
|
print(f"[Admin] 💡 To watch a client, send: {{'type': 'watch_client', 'client_id': 'CLIENT_ID_HERE'}}")
|
||||||
|
print(f"[Admin] 💡 After that, admin will receive binary video frames")
|
||||||
|
|
||||||
|
# Ждём сообщений от сервера
|
||||||
|
print(f"[Admin] Waiting for messages from server (press Ctrl+C to stop)...")
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
message = await asyncio.wait_for(ws.recv(), timeout=5)
|
||||||
|
if isinstance(message, bytes):
|
||||||
|
print(f"[Admin] ✓ Received {len(message)} bytes of video frame data")
|
||||||
|
else:
|
||||||
|
print(f"[Admin] ✓ Message: {message[:100]}")
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# Таймаут OK - просто ждём дальше
|
||||||
|
continue
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print(f"\n[Admin] Disconnected")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Admin] ❌ WebSocket error: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=" * 60)
|
||||||
|
print("Admin WebSocket Test")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"Server: http://{HOST}:{PORT}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
try:
|
||||||
|
asyncio.run(admin_watch())
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[Admin] Interrupted by user")
|
||||||
Reference in New Issue
Block a user