Files
SonicForgeStudio/app/api/v1/projects.py
T
2026-07-20 10:39:07 +07:00

129 lines
4.3 KiB
Python

import time
import json
import uuid
from fastapi import APIRouter, HTTPException, Depends, Header
from pydantic import BaseModel
from typing import Optional, Any, Dict
from app.models.user import get_db_connection
from app.api.v1.auth import get_current_user, decode_token
router = APIRouter()
class SaveProjectRequest(BaseModel):
name: str
data_json: str
class SaveTempProjectRequest(BaseModel):
data_json: str
def get_optional_user(authorization: Optional[str] = Header(None)) -> Optional[dict]:
if authorization and authorization.startswith("Bearer "):
token = authorization.split(" ")[1]
return decode_token(token)
return None
@router.post("/temp")
async def save_temp_project(req: SaveTempProjectRequest, current_user: Optional[dict] = Depends(get_optional_user)):
user_id = current_user["user_id"] if current_user else "anonymous"
conn = get_db_connection()
cursor = conn.cursor()
size_bytes = len(req.data_json.encode("utf-8"))
now = time.time()
temp_id = f"temp_{user_id}"
cursor.execute("""
INSERT INTO projects (id, user_id, name, data_json, is_temp, size_bytes, updated_at)
VALUES (?, ?, 'Dự án tạm chưa lưu', ?, 1, ?, ?)
ON CONFLICT(id) DO UPDATE SET data_json = excluded.data_json, size_bytes = excluded.size_bytes, updated_at = excluded.updated_at
""", (temp_id, user_id, req.data_json, size_bytes, now))
conn.commit()
conn.close()
return {"message": "Đã lưu dự án tạm tự động", "updated_at": now}
@router.get("/temp")
async def get_temp_project(current_user: Optional[dict] = Depends(get_optional_user)):
user_id = current_user["user_id"] if current_user else "anonymous"
temp_id = f"temp_{user_id}"
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT data_json, updated_at FROM projects WHERE id = ? AND is_temp = 1", (temp_id,))
row = cursor.fetchone()
conn.close()
if not row:
return {"has_temp": False}
return {
"has_temp": True,
"data_json": row["data_json"],
"updated_at": row["updated_at"]
}
@router.post("/cloud")
async def save_cloud_project(req: SaveProjectRequest, current_user: dict = Depends(get_current_user)):
user_id = current_user["user_id"]
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT storage_limit_mb FROM user_quotas WHERE user_id = ?", (user_id,))
quota_row = cursor.fetchone()
storage_limit_mb = quota_row["storage_limit_mb"] if quota_row else 500
cursor.execute("SELECT SUM(size_bytes) as total_used FROM projects WHERE user_id = ? AND is_temp = 0", (user_id,))
used_row = cursor.fetchone()
used_bytes = used_row["total_used"] if used_row and used_row["total_used"] else 0
new_size_bytes = len(req.data_json.encode("utf-8"))
max_bytes = storage_limit_mb * 1024 * 1024
if used_bytes + new_size_bytes > max_bytes:
conn.close()
raise HTTPException(
status_code=400,
detail=f"Dung lượng dự án vượt quá hạn mức Quota ({storage_limit_mb}MB). Vui lòng dọn dẹp hoặc nâng cấp tài khoản."
)
project_id = str(uuid.uuid4())
now = time.time()
cursor.execute("""
INSERT INTO projects (id, user_id, name, data_json, is_temp, size_bytes, updated_at)
VALUES (?, ?, ?, ?, 0, ?, ?)
""", (project_id, user_id, req.name, req.data_json, new_size_bytes, now))
temp_id = f"temp_{user_id}"
cursor.execute("DELETE FROM projects WHERE id = ? AND is_temp = 1", (temp_id,))
conn.commit()
conn.close()
return {
"message": "Đã lưu dự án lên Cloud thành công!",
"project_id": project_id
}
@router.get("/cloud")
async def list_cloud_projects(current_user: dict = Depends(get_current_user)):
user_id = current_user["user_id"]
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("""
SELECT id, name, size_bytes, updated_at FROM projects
WHERE user_id = ? AND is_temp = 0
ORDER BY updated_at DESC
""", (user_id,))
rows = cursor.fetchall()
conn.close()
return [
{
"id": r["id"],
"name": r["name"],
"size_mb": round(r["size_bytes"] / (1024 * 1024), 2),
"updated_at": r["updated_at"]
} for r in rows
]