fix: scan visibility, NC folder validation, watcher logging
- nc-scan: detailed INFO logging of every path found, subfolder contents and skip reasons; 502 now includes the exact folder and error so user sees a real message instead of a blank result - band creation: if nc_base_path is explicitly given, verify the folder exists in Nextcloud before saving — returns 422 with a clear message to the user; auto-generated paths still do MKCOL - songs search: add ?unattributed=true to return songs with no session_id (files not in a YYMMDD folder) - BandPage: show "Unattributed Recordings" section below sessions so scanned files without a dated folder always appear - watcher event_loop: promote all per-activity log lines from DEBUG to INFO so they're visible in default Docker Compose log output; log normalized path and skip reason for every activity Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -106,7 +106,7 @@ async def poll_once(nc_client: NextcloudWatcherClient, settings: WatcherSettings
|
||||
|
||||
activities = await nc_client.get_activities(since_id=_last_activity_id)
|
||||
if not activities:
|
||||
log.debug("No new activities since id=%d", _last_activity_id)
|
||||
log.info("No new activities since id=%d", _last_activity_id)
|
||||
return
|
||||
|
||||
log.info("Received %d activities (since id=%d)", len(activities), _last_activity_id)
|
||||
@@ -117,44 +117,42 @@ async def poll_once(nc_client: NextcloudWatcherClient, settings: WatcherSettings
|
||||
subject = activity.get("subject", "")
|
||||
raw_path = extract_nc_file_path(activity)
|
||||
|
||||
log.debug(
|
||||
# Advance the cursor regardless of whether we act on this event
|
||||
_last_activity_id = max(_last_activity_id, activity_id)
|
||||
|
||||
log.info(
|
||||
"Activity id=%d type=%r subject=%r raw_path=%r",
|
||||
activity_id, activity_type, subject, raw_path,
|
||||
)
|
||||
|
||||
# Advance the cursor regardless of whether we act on this event
|
||||
_last_activity_id = max(_last_activity_id, activity_id)
|
||||
|
||||
if raw_path is None:
|
||||
log.debug("Skipping activity %d: no file path in payload", activity_id)
|
||||
log.info(" → skip: no file path in activity payload")
|
||||
continue
|
||||
|
||||
nc_path = normalize_nc_path(raw_path, nc_client.username)
|
||||
log.info(" → normalized path: %r", nc_path)
|
||||
|
||||
# Only care about audio files — skip everything else immediately
|
||||
if not is_audio_file(nc_path, settings.audio_extensions):
|
||||
log.debug(
|
||||
"Skipping activity %d: '%s' is not an audio file (ext: %s)",
|
||||
activity_id, nc_path, Path(nc_path).suffix.lower(),
|
||||
log.info(
|
||||
" → skip: not an audio file (ext=%s)",
|
||||
Path(nc_path).suffix.lower() or "<none>",
|
||||
)
|
||||
continue
|
||||
|
||||
if not is_band_audio_path(nc_path):
|
||||
log.debug(
|
||||
"Skipping activity %d: '%s' is not inside a band folder",
|
||||
activity_id, nc_path,
|
||||
)
|
||||
log.info(" → skip: path not inside a bands/ folder")
|
||||
continue
|
||||
|
||||
if activity_type not in _UPLOAD_TYPES and subject not in _UPLOAD_SUBJECTS:
|
||||
log.debug(
|
||||
"Skipping activity %d: type=%r subject=%r — not a file upload event",
|
||||
activity_id, activity_type, subject,
|
||||
log.info(
|
||||
" → skip: type=%r subject=%r is not a file upload event",
|
||||
activity_type, subject,
|
||||
)
|
||||
continue
|
||||
|
||||
log.info("Detected audio upload: %s (activity %d)", nc_path, activity_id)
|
||||
log.info(" → MATCH — registering audio upload: %s", nc_path)
|
||||
etag = await nc_client.get_file_etag(nc_path)
|
||||
success = await register_version_with_api(nc_path, etag, settings.api_url)
|
||||
if not success:
|
||||
log.warning("Failed to register upload for activity %d (%s)", activity_id, nc_path)
|
||||
log.warning(" → FAILED to register upload for activity %d (%s)", activity_id, nc_path)
|
||||
|
||||
Reference in New Issue
Block a user