157 lines
5.5 KiB
Python
157 lines
5.5 KiB
Python
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, PUT, DELETE 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) |