Wokring on Nextcloud scan

This commit is contained in:
Mistral Vibe
2026-04-10 13:01:31 +02:00
parent 4bab0a76f7
commit ba22853bc7
3 changed files with 114 additions and 99 deletions

View File

@@ -9,7 +9,6 @@ from urllib.parse import unquote
from sqlalchemy.ext.asyncio import AsyncSession
from rehearsalhub.repositories.audio_version import AudioVersionRepository
from rehearsalhub.repositories.rehearsal_session import RehearsalSessionRepository
from rehearsalhub.repositories.song import SongRepository
from rehearsalhub.schemas.audio_version import AudioVersionCreate
@@ -103,7 +102,6 @@ async def scan_band_folder(
dav_prefix = f"/remote.php/dav/files/{nc._auth[0]}/"
relative = _make_relative(dav_prefix)
version_repo = AudioVersionRepository(db_session)
session_repo = RehearsalSessionRepository(db_session)
song_repo = SongRepository(db_session)
song_svc = SongService(db_session)
@@ -133,68 +131,69 @@ async def scan_band_folder(
meta = await nc.get_file_metadata(nc_file_path)
etag = meta.etag
except Exception as exc:
log.warning("Metadata error for '%s': %s", nc_file_path, exc)
log.error("Metadata fetch failed for '%s': %s", nc_file_path, exc, exc_info=True)
skipped += 1
yield {"type": "skipped", "path": nc_file_path, "reason": f"metadata error: {exc}"}
continue
# Skip if this exact version is already indexed
if etag and await version_repo.get_by_etag(etag):
log.info("Already registered (etag match): %s", nc_file_path)
skipped += 1
yield {"type": "skipped", "path": nc_file_path, "reason": "already registered"}
continue
try:
# Resolve or create a RehearsalSession from a YYMMDD folder segment
rehearsal_date = parse_rehearsal_date(nc_file_path)
rehearsal_session_id = None
if rehearsal_date:
session_folder = extract_session_folder(nc_file_path) or song_folder
rs = await session_repo.get_or_create(band_id, rehearsal_date, session_folder)
rehearsal_session_id = rs.id
yield {
"type": "session",
"session": {
"id": str(rs.id),
"date": rs.date.isoformat(),
"label": rs.label,
"nc_folder_path": rs.nc_folder_path,
},
}
# Resolve or create a RehearsalSession from a YYMMDD folder segment
rehearsal_date = parse_rehearsal_date(nc_file_path)
rehearsal_session_id = None
if rehearsal_date:
session_folder = extract_session_folder(nc_file_path) or song_folder
rs = await session_repo.get_or_create(band_id, rehearsal_date, session_folder)
rehearsal_session_id = rs.id
yield {
"type": "session",
"session": {
"id": str(rs.id),
"date": rs.date.isoformat(),
"label": rs.label,
"nc_folder_path": rs.nc_folder_path,
},
}
# Find or create the Song record
song = await song_repo.get_by_nc_folder_path(song_folder)
if song is None:
song = await song_repo.get_by_title_and_band(band_id, song_title)
is_new = song is None
if is_new:
log.info("Creating song '%s' folder='%s'", song_title, song_folder)
song = await song_repo.create(
band_id=band_id,
session_id=rehearsal_session_id,
title=song_title,
status="jam",
notes=None,
nc_folder_path=song_folder,
created_by=member_id,
)
elif rehearsal_session_id and song.session_id is None:
song = await song_repo.update(song, session_id=rehearsal_session_id)
# Find or create the Song record
song = await song_repo.get_by_nc_folder_path(song_folder)
if song is None:
song = await song_repo.get_by_title_and_band(band_id, song_title)
is_new = song is None
if is_new:
log.info("Creating song '%s' folder='%s'", song_title, song_folder)
song = await song_repo.create(
band_id=band_id,
session_id=rehearsal_session_id,
title=song_title,
status="jam",
notes=None,
nc_folder_path=song_folder,
created_by=member_id,
# Register the audio version
version = await song_svc.register_version(
song.id,
AudioVersionCreate(
nc_file_path=nc_file_path,
nc_file_etag=etag,
format=Path(nc_file_path).suffix.lstrip(".").lower(),
file_size_bytes=meta.size,
),
member_id,
)
elif rehearsal_session_id and song.session_id is None:
song = await song_repo.update(song, session_id=rehearsal_session_id)
log.info("Imported '%s' as version %s for song '%s'", nc_file_path, version.id, song.title)
# Register the audio version
await song_svc.register_version(
song.id,
AudioVersionCreate(
nc_file_path=nc_file_path,
nc_file_etag=etag,
format=Path(nc_file_path).suffix.lstrip(".").lower(),
file_size_bytes=meta.size,
),
member_id,
)
imported += 1
read = SongRead.model_validate(song).model_copy(update={"version_count": 1, "session_id": rehearsal_session_id})
yield {"type": "song", "song": read.model_dump(mode="json"), "is_new": is_new}
imported += 1
read = SongRead.model_validate(song).model_copy(update={"version_count": 1, "session_id": rehearsal_session_id})
yield {"type": "song", "song": read.model_dump(mode="json"), "is_new": is_new}
except Exception as exc:
log.error("Failed to import '%s': %s", nc_file_path, exc, exc_info=True)
skipped += 1
yield {"type": "skipped", "path": nc_file_path, "reason": f"import error: {exc}"}
yield {
"type": "done",