From 6f0fac9f2dfa1ce18361ac9faca5091b005ba2dc Mon Sep 17 00:00:00 2001 From: 3dtours Date: Wed, 22 Jul 2026 18:37:52 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20s=E1=BB=ADa=20l=E1=BB=97i=20Ai=20prompt?= =?UTF-8?q?=20multi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/audio.py | 13 +++++++--- app/api/v1/projects.py | 53 ++++++++++++++++++++++++++++++++++++++ app/storage/sonicforge.db | Bin 45056 -> 45056 bytes 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/app/api/v1/audio.py b/app/api/v1/audio.py index 5abbd25..c699535 100644 --- a/app/api/v1/audio.py +++ b/app/api/v1/audio.py @@ -1,11 +1,15 @@ import os import uuid import asyncio -from fastapi import APIRouter, UploadFile, File, HTTPException, Query +import json +from fastapi import APIRouter, UploadFile, File, HTTPException, Query, Depends from fastapi.responses import FileResponse from pydantic import BaseModel -from typing import Optional +from typing import Optional, List from app.config import settings +from app.api.v1.auth import get_current_user +from app.api.v1.projects import get_optional_user +from app.models.user import get_db_connection router = APIRouter() @@ -52,11 +56,12 @@ class PythonToolRequest(BaseModel): wave_type: Optional[str] = "sine" @router.post("/upload") -async def upload_audio(file: UploadFile = File(...)): +async def upload_audio(file: UploadFile = File(...), current_user: Optional[dict] = Depends(get_optional_user)): + user_id = current_user["user_id"] if current_user else "anonymous" ext = os.path.splitext(file.filename)[1] if not ext: ext = ".wav" - file_id = f"{uuid.uuid4()}{ext}" + file_id = f"user_{user_id}_{uuid.uuid4()}{ext}" file_path = os.path.join(settings.UPLOADS_DIR, file_id) with open(file_path, "wb") as f: diff --git a/app/api/v1/projects.py b/app/api/v1/projects.py index 9462484..03ee03f 100644 --- a/app/api/v1/projects.py +++ b/app/api/v1/projects.py @@ -126,3 +126,56 @@ async def list_cloud_projects(current_user: dict = Depends(get_current_user)): "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"} diff --git a/app/storage/sonicforge.db b/app/storage/sonicforge.db index 330f740830e7c0c5190bc5b479cec47e1409582c..efec6d94591821a38fe10dbd8639a308576761c2 100644 GIT binary patch delta 398 zcma)$y-Gq+0D$jRZzl;l88}3N4h|vQIR8Ie6z(oIch5PVvB;J{Aw_7k^g>NFyNTQv z@C|wer-lZXUZ8AY#q_3fcB&25R0`?1k(6Q1 zEVqd@-YZ4Cph96!l(C#igRr2;dFK#LsP>*)f>HKWDK&QsU>d;L&ZPJXreHcBJOecB zfMTmvexTbqkYMTC9GTd1>|%zLiw)y8wnz)crIc-<($QTl{pcP5EhX1fWLv#n$m_TF z<>s&x{iU2B(sN2;BYwcz9>od4K32$COA@Q77XMO&VX1yoQQeQ;KeI{qx=@0Ppa2^I tY`_co delta 430 zcmZp8z|`=7X@WH4@`*CejLSDB2*@*XOfHmnaxgSCOf@&PG)XhHFf%tuGE6nLG`2`G zPBStxwoEZMNKLggGe}D|GqOxJOiM{JG)zlMPBAtxurNxsFfccc ze?9jkj>wIT-W-B$W-OfXq4wSEoJ{N`sksI5lh0PFfboTTY3a-qB`YPca6wUiR%&vI zl8#bdVs0u>bn=CI$;t9na^lX3MJ4(9c?!;n1*t{F3O@Py1$wy!#*+go`s%Bdk~0$X z@=|k(m8^_(lroEhOHzwc^OdYhib_*;lyVZ2QgeW21&6o>x%w;B*6LI%L98rFOwNu^ zE-i^SG`BD@H?%Z0GcmU`LfGyMl)_;#P*HIS&`lwkxs#(SeAvtl3=_>wCkIrUO+H(* zUIHjvniP_l1awh!Y%SAX$6GVB>@8J-HczU~XW?XEU|{B-&cHu?Ghc%_|HKJlEE>$A ZjFab8t8g*vGRHH*gNTu3^Sgc_1pp6|iHHCI