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>
This commit is contained in:
@@ -171,10 +171,52 @@ class TrackCreate(BaseModel):
|
|||||||
|
|
||||||
@app.get("/api/music/library")
|
@app.get("/api/music/library")
|
||||||
def list_library():
|
def list_library():
|
||||||
"""저장된 트랙 목록 전체 조회 (생성일 내림차순)"""
|
"""저장된 트랙 목록 전체 조회 (생성일 내림차순). 파일시스템과 자동 동기화."""
|
||||||
|
_sync_library_with_disk()
|
||||||
return {"tracks": get_all_tracks()}
|
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)
|
@app.post("/api/music/library", status_code=201)
|
||||||
def save_to_library(req: TrackCreate):
|
def save_to_library(req: TrackCreate):
|
||||||
"""트랙 수동 추가 (외부 파일 등록 또는 프론트 직접 저장용)"""
|
"""트랙 수동 추가 (외부 파일 등록 또는 프론트 직접 저장용)"""
|
||||||
|
|||||||
Reference in New Issue
Block a user