addressbook_web/app.py

157 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)