182 lines
6.4 KiB
Python
182 lines
6.4 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
|
|
]
|
|
|
|
@router.get("/cloud/{project_id}")
|
|
async def get_cloud_project(project_id: str, current_user: dict = Depends(get_current_user)):
|
|
user_id = current_user["user_id"]
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT name, data_json FROM projects WHERE id = ? AND user_id = ? AND is_temp = 0", (project_id, user_id))
|
|
row = cursor.fetchone()
|
|
conn.close()
|
|
|
|
if not row:
|
|
raise HTTPException(status_code=404, detail="Không tìm thấy dự án")
|
|
|
|
return {
|
|
"id": project_id,
|
|
"name": row["name"],
|
|
"data_json": row["data_json"]
|
|
}
|
|
|
|
@router.delete("/cloud/{project_id}")
|
|
async def delete_cloud_project(project_id: str, current_user: dict = Depends(get_current_user)):
|
|
user_id = current_user["user_id"]
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("DELETE FROM projects WHERE id = ? AND user_id = ? AND is_temp = 0", (project_id, user_id))
|
|
conn.commit()
|
|
conn.close()
|
|
return {"success": True, "message": "Đã xóa dự án thành công"}
|
|
|
|
@router.put("/cloud/{project_id}")
|
|
async def update_cloud_project(project_id: str, 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 id FROM projects WHERE id = ? AND user_id = ? AND is_temp = 0", (project_id, user_id))
|
|
exists = cursor.fetchone()
|
|
if not exists:
|
|
conn.close()
|
|
raise HTTPException(status_code=404, detail="Không tìm thấy dự án để cập nhật")
|
|
|
|
new_size_bytes = len(req.data_json.encode("utf-8"))
|
|
now = time.time()
|
|
|
|
cursor.execute("""
|
|
UPDATE projects
|
|
SET name = ?, data_json = ?, size_bytes = ?, updated_at = ?
|
|
WHERE id = ? AND user_id = ?
|
|
""", (req.name, req.data_json, new_size_bytes, now, project_id, user_id))
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
return {"success": True, "message": "Đã cập nhật dự án thành công"}
|