From 593dccfd2eee022f3bfc7cc32bd6eab3157bf2ab Mon Sep 17 00:00:00 2001 From: Iam54r1n4 Date: Sun, 26 Jan 2025 08:21:26 +0000 Subject: [PATCH] Add server status api --- .../webpanel/routers/api/v1/__init__.py | 2 + .../routers/api/v1/schema/__init__.py | 1 + .../webpanel/routers/api/v1/schema/server.py | 16 ++++++ .../scripts/webpanel/routers/api/v1/server.py | 53 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 core/scripts/webpanel/routers/api/v1/schema/server.py create mode 100644 core/scripts/webpanel/routers/api/v1/server.py diff --git a/core/scripts/webpanel/routers/api/v1/__init__.py b/core/scripts/webpanel/routers/api/v1/__init__.py index abc6976..e92088b 100644 --- a/core/scripts/webpanel/routers/api/v1/__init__.py +++ b/core/scripts/webpanel/routers/api/v1/__init__.py @@ -1,6 +1,8 @@ from fastapi import APIRouter from . import user +from . import server api_v1_router = APIRouter() api_v1_router.include_router(user.router, prefix='/users') +api_v1_router.include_router(server.router, prefix='/server') diff --git a/core/scripts/webpanel/routers/api/v1/schema/__init__.py b/core/scripts/webpanel/routers/api/v1/schema/__init__.py index f9b61db..481e59d 100644 --- a/core/scripts/webpanel/routers/api/v1/schema/__init__.py +++ b/core/scripts/webpanel/routers/api/v1/schema/__init__.py @@ -1 +1,2 @@ from . import user +from . import server diff --git a/core/scripts/webpanel/routers/api/v1/schema/server.py b/core/scripts/webpanel/routers/api/v1/schema/server.py new file mode 100644 index 0000000..3df3dae --- /dev/null +++ b/core/scripts/webpanel/routers/api/v1/schema/server.py @@ -0,0 +1,16 @@ +from pydantic import BaseModel + + +# We can't return bytes because the underlying script is returning human readable values which are hard to parse it +# It's better to chnage the underlying script to return bytes instead of changing it here +# Because of this problem we use str type instead of int as type +class ServerStatusResponse(BaseModel): + # disk_usage: int + cpu_usage: str + total_ram: str + ram_usage: str + online_users: int + + uploaded_traffic: str + downloaded_traffic: str + total_traffic: str diff --git a/core/scripts/webpanel/routers/api/v1/server.py b/core/scripts/webpanel/routers/api/v1/server.py new file mode 100644 index 0000000..8f091b2 --- /dev/null +++ b/core/scripts/webpanel/routers/api/v1/server.py @@ -0,0 +1,53 @@ +from fastapi import APIRouter, HTTPException +import cli_api +from .schema.server import ServerStatusResponse + +router = APIRouter() + + +@router.get('/status', response_model=ServerStatusResponse) +async def server_status(): + try: + if res := cli_api.server_info(): + return __parse_server_status(res) + raise HTTPException(status_code=404, detail='Server information not available.') + except Exception as e: + raise HTTPException(status_code=400, detail=f'Error: {str(e)}') + + +def __parse_server_status(server_info: str) -> ServerStatusResponse: + data = {} + for line in server_info.splitlines(): + key, _, value = line.partition(":") + key = key.strip().lower() + value = value.strip() + + if not key or not value: + continue # Skip empty or malformed lines + + try: + if 'cpu usage' in key: + data['cpu_usage'] = value + elif 'total ram' in key: + data['total_ram'] = value + elif 'used ram' in key: + data['ram_usage'] = value + elif 'online users' in key: + data['online_users'] = int(value) + elif 'uploaded traffic' in key: + value = value.replace(' ', '') + data['uploaded_traffic'] = value + elif "downloaded traffic" in key: + value = value.replace(' ', '') + data['downloaded_traffic'] = value + elif 'total traffic' in key: + value = value.replace(' ', '') + data["total_traffic"] = value + except ValueError as e: + raise ValueError(f'Error parsing line \'{line}\': {e}') + + # Validate required fields + try: + return ServerStatusResponse(**data) + except Exception as e: + raise ValueError(f'Invalid or incomplete server info: {e}')