from fastapi import FastAPI, HTTPException from pydantic import BaseModel import sqlite3 import datetime from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse app = FastAPI() # Соединение с базой данных 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 | None = None computer_name: str | None = None install_time: str | None = None folder_id: int | None = None # Монтируем папку templates как статические файлы app.mount("/templates", StaticFiles(directory="templates"), name="templates") # Главная страница @app.get("/") async def root(): return FileResponse("templates/index.html") # --- Folders API --- @app.get("/api/folders") def get_folders(): cursor.execute("SELECT * FROM folders") rows = cursor.fetchall() return [{"id": row[0], "name": row[1], "parent_id": row[2]} for row in rows] @app.post("/api/folders") def add_folder(folder: Folder): cursor.execute("INSERT INTO folders (name, parent_id) VALUES (?, ?)", (folder.name, folder.parent_id)) conn.commit() return {"status": "success", "id": cursor.lastrowid} @app.put("/api/folders/{folder_id}") def update_folder(folder_id: int, folder: FolderUpdate): 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.delete("/api/folders/{folder_id}") def delete_folder(folder_id: int): cursor.execute("DELETE FROM folders WHERE id = ?", (folder_id,)) conn.commit() if cursor.rowcount == 0: raise HTTPException(status_code=404, detail="Папка не найдена") return {"status": "success"} # --- Installs API --- @app.get("/api/installs") def get_installs(): 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] @app.post("/api/install") def add_install(data: InstallData): install_time = data.install_time or datetime.datetime.now().isoformat() 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.put("/api/install/{install_id}") def update_install(install_id: int, data: InstallData): # Получаем текущие данные записи cursor.execute("SELECT rust_id, computer_name, install_time, folder_id FROM installs WHERE id = ?", (install_id,)) current = cursor.fetchone() if not current: raise HTTPException(status_code=404, detail="Запись не найдена") # Обновляем только те поля, которые переданы new_rust_id = data.rust_id if data.rust_id is not None else current[0] new_computer_name = data.computer_name if data.computer_name is not None else current[1] new_install_time = data.install_time if data.install_time is not None else current[2] new_folder_id = data.folder_id if data.folder_id is not None else current[3] cursor.execute(""" UPDATE installs SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ? WHERE id = ? """, (new_rust_id, new_computer_name, new_install_time, new_folder_id, install_id)) conn.commit() return {"status": "success"} @app.delete("/api/install/{install_id}") def delete_install(install_id: int): 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 from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["http://10.0.0.10:8001", "http://localhost:8001"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )