gonets/SRV/api/v1/network.py

155 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Body, HTTPException
import logging
from typing import Dict, Tuple, List, Union
from services.network_service import NetworkService
from models.network import (
NetworkInterfacesContainer,
Activation,
Deactivation,
NetworkInterface,
WiFiDevice,
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
router = APIRouter()
network_service = NetworkService()
class ContainerPositionManager:
"""
Класс для управления позициями и состоянием контейнеров
"""
def __init__(self):
self.positions: Dict[str, Dict[str, Union[int, bool]]] = {
"activation": {"x": 0, "y": 0, "isOpen": False},
"deactivation": {"x": 0, "y": 0, "isOpen": False},
}
def get_position_and_state(self, container_name: str) -> Tuple[int, int, bool]:
container = self.positions.get(container_name)
if not container:
raise ValueError(f"Неверное имя контейнера: {container_name}")
return container["x"], container["y"], container["isOpen"]
def update_position(self, container_id: int, x: int, y: int, isOpen: bool) -> None:
container_name = "activation" if container_id == 1 else "deactivation"
self.positions[container_name] = {"x": x, "y": y, "isOpen": isOpen}
container_manager = ContainerPositionManager()
async def get_network_data() -> Dict[str, Dict]:
"""
Возвращает текущие сетевые данные в виде словаря
"""
logger.debug("Вызов get_network_data()")
try:
network_data = await network_service.get_network_interfaces_container()
activation_interfaces, deactivation_interfaces = _split_interfaces(
network_data.interfaces
)
activation_x, activation_y, activation_is_open = (
container_manager.get_position_and_state("activation")
)
deactivation_x, deactivation_y, deactivation_is_open = (
container_manager.get_position_and_state("deactivation")
)
activation = Activation(
id=1,
interfaces=activation_interfaces,
container_x=activation_x,
container_y=activation_y,
isOpen=activation_is_open,
)
deactivation = Deactivation(
id=2,
interfaces=deactivation_interfaces,
container_x=deactivation_x,
container_y=deactivation_y,
isOpen=deactivation_is_open,
)
return {
"activation": activation.model_dump(),
"deactivation": deactivation.model_dump(),
}
except Exception as e:
logger.error(f"Ошибка в get_network_data: {e}")
raise HTTPException(
status_code=500, detail="Не удалось получить сетевые данные"
)
def _split_interfaces(
interfaces: List[Union[NetworkInterface, WiFiDevice]],
) -> Tuple[
List[Union[NetworkInterface, WiFiDevice]], List[Union[NetworkInterface, WiFiDevice]]
]:
"""
Разделяет интерфейсы на активные и неактивные
"""
activation_interfaces = []
deactivation_interfaces = []
for interface in interfaces:
if interface.device_state == "100":
activation_interfaces.append(interface)
else:
deactivation_interfaces.append(interface)
return activation_interfaces, deactivation_interfaces
@router.post("/update_container_position")
async def update_container_position(data: Dict[str, Union[int, bool]] = Body(...)):
"""
Обновляет позицию и состояние контейнера
"""
try:
required_keys = ["container_id", "container_x", "container_y", "isOpen"]
if not all(key in data for key in required_keys):
raise ValueError(
"Отсутствуют обязательные поля: container_id, container_x, container_y, isOpen"
)
container_id = data["container_id"]
container_x = data["container_x"]
container_y = data["container_y"]
is_open = data["isOpen"]
# Проверка типов
if (
not isinstance(container_id, int)
or not isinstance(container_x, int)
or not isinstance(container_y, int)
or not isinstance(is_open, bool)
):
raise ValueError("Неверный тип данных в запросе")
container_manager.update_position(
container_id, container_x, container_y, is_open
)
return {"success": True, "message": "Позиция и состояние контейнера обновлены"}
except Exception as e:
logger.error(f"Ошибка обновления позиции контейнера: {e}")
raise HTTPException(
status_code=400,
detail=f"Не удалось обновить положение контейнера: {str(e)}",
)
@router.get("/get_hostname")
async def get_hostname():
try:
hostname_info = await network_service.get_hostname()
return hostname_info
except Exception as e:
logger.error(f"Ошибка в get_hostname: {e}")
raise HTTPException(status_code=500, detail="Не удалось получить имя хоста")