music-lab 프론트엔드 대조 수정 (이중저장·title·audio_url·status shape)
- 이중 저장 방지: auto-register 유지, Save 버튼 제거는 프론트 담당 (방식 A)
- title 자동 생성: "{genre} — {mood} Mix" 형식으로 개선
- audio_url 절대경로 제거: 항상 /media/music/{task_id}.mp3 상대경로 반환
- status succeeded 시 track 메타데이터 포함 (프론트 Save 버튼 없이 즉시 UI 반영 가능)
- get_track_by_task_id() 함수 추가
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -171,6 +171,12 @@ def delete_track(track_id: int) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_track_by_task_id(task_id: str) -> Optional[Dict[str, Any]]:
|
||||||
|
with _conn() as conn:
|
||||||
|
row = conn.execute("SELECT * FROM music_library WHERE task_id = ?", (task_id,)).fetchone()
|
||||||
|
return _track_row_to_dict(row) if row else None
|
||||||
|
|
||||||
|
|
||||||
def get_track_file_path(track_id: int) -> Optional[str]:
|
def get_track_file_path(track_id: int) -> Optional[str]:
|
||||||
with _conn() as conn:
|
with _conn() as conn:
|
||||||
row = conn.execute("SELECT file_path FROM music_library WHERE id = ?", (track_id,)).fetchone()
|
row = conn.execute("SELECT file_path FROM music_library WHERE id = ?", (track_id,)).fetchone()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from pydantic import BaseModel
|
|||||||
from .db import (
|
from .db import (
|
||||||
init_db,
|
init_db,
|
||||||
create_task, update_task, get_task,
|
create_task, update_task, get_task,
|
||||||
get_all_tracks, add_track, delete_track, get_track_file_path,
|
get_all_tracks, add_track, delete_track, get_track_file_path, get_track_by_task_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -86,11 +86,15 @@ def _run_generation(task_id: str, params: dict) -> None:
|
|||||||
for chunk in resp.iter_content(chunk_size=8192):
|
for chunk in resp.iter_content(chunk_size=8192):
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
|
|
||||||
audio_url = f"{MUSIC_MEDIA_BASE}/{filename}"
|
# audio_url은 항상 Nginx 상대경로 (Mixed Content 방지)
|
||||||
|
audio_url = f"/media/music/{filename}"
|
||||||
|
|
||||||
# 라이브러리 자동 등록
|
# 라이브러리 자동 등록 — title 자동 생성
|
||||||
genre = params.get("genre", "")
|
genre = params.get("genre", "")
|
||||||
title = f"{genre} {task_id[:8]}" if genre else task_id[:8]
|
moods = params.get("moods", [])
|
||||||
|
mood_str = moods[0] if moods else "Original"
|
||||||
|
title = f"{genre} — {mood_str} Mix" if genre else f"{mood_str} Mix"
|
||||||
|
|
||||||
add_track({
|
add_track({
|
||||||
"title": title,
|
"title": title,
|
||||||
"genre": genre,
|
"genre": genre,
|
||||||
@@ -145,11 +149,13 @@ def get_status(task_id: str):
|
|||||||
"""
|
"""
|
||||||
생성 작업 상태 조회. 프론트는 succeeded 또는 failed가 될 때까지 폴링.
|
생성 작업 상태 조회. 프론트는 succeeded 또는 failed가 될 때까지 폴링.
|
||||||
status: queued | processing | succeeded | failed
|
status: queued | processing | succeeded | failed
|
||||||
|
succeeded 시 track 메타데이터 포함 (라이브러리 별도 저장 불필요).
|
||||||
"""
|
"""
|
||||||
task = get_task(task_id)
|
task = get_task(task_id)
|
||||||
if not task:
|
if not task:
|
||||||
raise HTTPException(status_code=404, detail="Task not found")
|
raise HTTPException(status_code=404, detail="Task not found")
|
||||||
return {
|
|
||||||
|
resp = {
|
||||||
"status": task["status"],
|
"status": task["status"],
|
||||||
"progress": task["progress"],
|
"progress": task["progress"],
|
||||||
"message": task["message"],
|
"message": task["message"],
|
||||||
@@ -157,6 +163,14 @@ def get_status(task_id: str):
|
|||||||
"error": task["error"],
|
"error": task["error"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# succeeded 시 라이브러리에 저장된 트랙 메타데이터 포함
|
||||||
|
# 프론트는 이 track 객체로 UI를 바로 업데이트하면 됨 (Save 버튼 불필요)
|
||||||
|
if task["status"] == "succeeded":
|
||||||
|
track = get_track_by_task_id(task_id)
|
||||||
|
resp["track"] = track
|
||||||
|
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
# ── 라이브러리 API ────────────────────────────────────────────────────────────
|
# ── 라이브러리 API ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user