{# Settings → Media folders (issue #63): the folder browser + per-folder domain-pack picker, the same panel the setup wizard's media step uses, mounted here on the protected router (CSRF_SETTINGS). Self-contained: renders from _settings_context, which threads the folder-panel context via _folder_panel_context. The panel owns its own CSRF-guarded routes (/settings/folders, /settings/folders/browse), so it slots in beside the other sections without touching their saves. #}

Media folders

Register the folders under your media root that Voxint should watch, and choose a domain pack per folder to tune transcription and enrichment. Browsing stays inside your media root. Changes apply to the next job you submit.

{% include "fragments/folder_panel.html" %} {# Watch-folder ingest (issue #60): a tri-state toggle + a plain-language status line for the latest automatic sweep. When on, Voxint checks the registered folders on a schedule and starts a run for each new recording, skipping files it already knows. #}

Automatic ingest

When this is on, Voxint checks the folders above on a schedule and starts a job for each new recording it finds — files it has already picked up are skipped. Drop a batch of recordings into a registered folder and they’ll be queued automatically, no manual submitting.

{% if watch_folder_error %} {% endif %}
Watch registered folders for new recordings

{% if watch_folder_effective %}Watching is on.{% else %}Watching is off.{% endif %} {% if watch_folder_checked_at %} Last checked {{ watch_folder_checked_at.strftime("%Y-%m-%d %H:%M UTC") }} — picked up {{ watch_folder_last_sweep.picked_up }} new file{{ "" if watch_folder_last_sweep.picked_up == 1 else "s" }}; {{ watch_folder_last_sweep.already_known }} already known; {{ watch_folder_last_sweep.settling }} waiting to settle. {% if watch_folder_last_sweep.root_missing %} The media folder could not be found during the check — is the drive or share mounted? {% endif %} {% if watch_folder_last_sweep.deferred %} {{ watch_folder_last_sweep.deferred }} {{ "was" if watch_folder_last_sweep.deferred == 1 else "were" }} queued but could not be handed to a worker yet (the job broker was unavailable) — they’ll start automatically when it recovers. {% endif %} {% if watch_folder_last_sweep.stat_errors %} {{ watch_folder_last_sweep.stat_errors }} file{{ "" if watch_folder_last_sweep.stat_errors == 1 else "s" }} disappeared or could not be read during the check. {% endif %} {% if watch_folder_last_sweep.sidecar_errors %} {{ watch_folder_last_sweep.sidecar_errors }} file{{ " is" if watch_folder_last_sweep.sidecar_errors == 1 else "s are" }} waiting because a companion .yaml sidecar has a problem; fix the sidecar and the next check will pick the recording up. {% endif %} {% if watch_folder_last_sweep.hit_file_cap %} A lot of new recordings appeared at once, so only the first batch was queued this pass — the rest is picked up over the next few checks. {% endif %} {% if watch_folder_last_sweep.hit_entry_cap %} This folder is very large, so only the first part is checked each pass, and files beyond it may not be picked up automatically — split it into smaller folders, or submit those files by hand. {% endif %} {% elif watch_folder_effective %} No automatic check has run yet. {% endif %}