2 Commits

Author SHA1 Message Date
d2606d7317 music-lab: 라이브러리 파일시스템 동기화 + v2 파일명 중복 수정
- GET /api/music/library 호출 시 디스크 .mp3 파일과 DB 자동 동기화
  - 디스크에 없는 트랙 → DB에서 삭제
  - DB에 없는 .mp3 → 새 트랙으로 자동 등록
- NAS에서 파일명 변경 시 웹에 자동 반영
- _v2_v2 파일명 중복 버그 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 13:56:42 +09:00
33a011a086 music-lab: 두 번째 변형 파일명 _v2_v2 중복 수정
task_id에 이미 _v2가 붙으므로 filename_suffix를 빈 문자열로 변경.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 13:14:35 +09:00
2 changed files with 44 additions and 2 deletions

View File

@@ -171,10 +171,52 @@ class TrackCreate(BaseModel):
@app.get("/api/music/library")
def list_library():
"""저장된 트랙 목록 전체 조회 (생성일 내림차순)"""
"""저장된 트랙 목록 전체 조회 (생성일 내림차순). 파일시스템과 자동 동기화."""
_sync_library_with_disk()
return {"tracks": get_all_tracks()}
def _sync_library_with_disk():
"""파일시스템의 .mp3 파일과 DB를 동기화.
- 디스크에 없는 트랙 → DB에서 삭제
- DB에 없는 .mp3 파일 → 새 트랙으로 추가
"""
tracks = get_all_tracks()
media_base = os.getenv("MUSIC_MEDIA_BASE", "/media/music")
# 디스크의 .mp3 파일 목록
disk_files = set()
try:
for f in os.listdir(MUSIC_DATA_DIR):
if f.lower().endswith(".mp3"):
disk_files.add(f)
except OSError:
return # 디렉토리 접근 불가 시 동기화 스킵
# DB 트랙의 파일명 매핑
db_filenames = {} # filename → track
for t in tracks:
if t.get("audio_url"):
fname = t["audio_url"].split("/")[-1]
db_filenames[fname] = t
# DB에는 있지만 디스크에 없는 → 삭제
for fname, t in db_filenames.items():
if fname not in disk_files:
delete_track(t["id"])
# 디스크에는 있지만 DB에 없는 → 추가
for f in disk_files:
if f not in db_filenames:
title = os.path.splitext(f)[0].replace("-", " ").replace("_", " ")
add_track({
"title": title,
"audio_url": f"{media_base}/{f}",
"file_path": os.path.join(MUSIC_DATA_DIR, f),
"provider": "suno",
})
@app.post("/api/music/library", status_code=201)
def save_to_library(req: TrackCreate):
"""트랙 수동 추가 (외부 파일 등록 또는 프론트 직접 저장용)"""

View File

@@ -157,7 +157,7 @@ def run_suno_generation(task_id: str, params: dict) -> None:
task_id=f"{task_id}_v2",
song=completed_tracks[1],
params=params,
filename_suffix="_v2",
filename_suffix="",
)
except Exception:
pass # 보조 변형 실패는 무시