from fastapi import FastAPI, HTTPException from pydantic import BaseModel import sqlite3 import datetime from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware # Создаем два экземпляра FastAPI для разных портов (опционально, для демонстрации) app_get = FastAPI(title="RustDesk Organizer - Web Interface") app_post = FastAPI(title="RustDesk Organizer - API") # Монтируем папку templates как статические файлы для GET app_get.mount("/templates", StaticFiles(directory="templates"), name="templates") # Соединение с базой данных conn = sqlite3.connect("/db/rustdesk.db", check_same_thread=False) cursor = conn.cursor() # Создаем таблицы (оставляем как есть) cursor.execute(""" CREATE TABLE IF NOT EXISTS folders ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, parent_id INTEGER, FOREIGN KEY (parent_id) REFERENCES folders(id) ) """) cursor.execute(""" CREATE TABLE IF NOT EXISTS installs ( id INTEGER PRIMARY KEY AUTOINCREMENT, rust_id TEXT, computer_name TEXT, install_time TEXT, folder_id INTEGER, FOREIGN KEY (folder_id) REFERENCES folders(id) ) """) conn.commit() # Модели данных (оставляем как есть) class Folder(BaseModel): name: str parent_id: int | None = None class FolderUpdate(BaseModel): name: str class InstallData(BaseModel): rust_id: str computer_name: str install_time: str | None = None folder_id: int | None = None # Функция для работы с базой данных def get_db(): return conn, cursor # --- GET API (порт 8001) --- @app_get.get("/") async def root(): return FileResponse("templates/index.html") @app_get.get("/api/folders") def get_folders(): conn, cursor = get_db() cursor.execute("SELECT * FROM folders") rows = cursor.fetchall() return [{"id": row[0], "name": row[1], "parent_id": row[2]} for row in rows] @app_get.get("/api/installs") def get_installs(): conn, cursor = get_db() cursor.execute(""" SELECT i.id, i.rust_id, i.computer_name, i.install_time, i.folder_id, f.name as folder_name FROM installs i LEFT JOIN folders f ON i.folder_id = f.id """) rows = cursor.fetchall() return [{"id": row[0], "rust_id": row[1], "computer_name": row[2], "install_time": row[3], "folder_id": row[4], "folder_name": row[5]} for row in rows] # --- POST API (порт 8002) --- @app_post.post("/api/folders") def add_folder(folder: Folder): conn, cursor = get_db() cursor.execute("INSERT INTO folders (name, parent_id) VALUES (?, ?)", (folder.name, folder.parent_id)) conn.commit() return {"status": "success", "id": cursor.lastrowid} @app_post.put("/api/folders/{folder_id}") def update_folder(folder_id: int, folder: FolderUpdate): conn, cursor = get_db() cursor.execute("UPDATE folders SET name = ? WHERE id = ?", (folder.name, folder_id)) conn.commit() if cursor.rowcount == 0: raise HTTPException(status_code=404, detail="Папка не найдена") return {"status": "success"} @app_post.delete("/api/folders/{folder_id}") def delete_folder(folder_id: int): conn, cursor = get_db() cursor.execute("DELETE FROM folders WHERE id = ?", (folder_id,)) conn.commit() if cursor.rowcount == 0: raise HTTPException(status_code=404, detail="Папка не найдена") return {"status": "success"} @app_post.post("/api/install") def add_install(data: InstallData): install_time = data.install_time or datetime.datetime.now().isoformat() conn, cursor = get_db() cursor.execute("INSERT INTO installs (rust_id, computer_name, install_time, folder_id) VALUES (?, ?, ?, ?)", (data.rust_id, data.computer_name, install_time, data.folder_id)) conn.commit() return {"status": "success"} @app_post.put("/api/install/{install_id}") def update_install(install_id: int, data: InstallData): conn, cursor = get_db() cursor.execute(""" UPDATE installs SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ? WHERE id = ? """, (data.rust_id, data.computer_name, data.install_time or datetime.datetime.now().isoformat(), data.folder_id, install_id)) conn.commit() if cursor.rowcount == 0: raise HTTPException(status_code=404, detail="Запись не найдена") return {"status": "success"} @app_post.delete("/api/install/{install_id}") def delete_install(install_id: int): conn, cursor = get_db() cursor.execute("DELETE FROM installs WHERE id = ?", (install_id,)) conn.commit() if cursor.rowcount == 0: raise HTTPException(status_code=404, detail="Запись не найдена") return {"status": "success"} # CORS для обоих приложений for app in [app_get, app_post]: app.add_middleware( CORSMiddleware, allow_origins=["http://10.0.0.10:8001", "http://localhost:8001"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) if __name__ == "__main__": import uvicorn # Запускаем два процесса Uvicorn для разных портов (опционально, для локального теста) uvicorn.run(app_get, host="0.0.0.0", port=8001) uvicorn.run(app_post, host="0.0.0.0", port=8002)