Refactor user config validation and add transcript display
Introduces a dedicated function `validate_and_index_users` to encapsulate the logic for validating user configurations, checking for duplicate slugs and API keys. This function returns a `Result` to handle errors gracefully, and its usage in `load_users` is updated to panic with a more informative error message. Additionally, this commit modifies the web routing to fetch and display audio transcripts. When scanning recordings, it now attempts to read a corresponding `.transcript.txt` file. If found, the transcript content is included in the `RecordingView` and rendered in the `cases.html` template. If the transcript file is not found, a "Transcription pending" message is displayed. The `transcribe` function in `whisper.rs` is updated to explicitly set the language to German (`language=de`), which can improve transcription accuracy by skipping language detection. The `encode=false` query parameter has been removed, as the service is designed to handle encoded audio. Finally, tests have been added for the new `validate_and_index_users` function to ensure duplicate slugs and API keys are correctly rejected. Integration tests in `web_test.rs` have been updated to verify the rendering of transcripts and the pending status.
This commit is contained in:
@@ -10,8 +10,11 @@ body { font-family: sans-serif; max-width: 900px; margin: 2em auto; padding: 0 1
|
||||
.case small { color: #666; font-family: monospace; }
|
||||
.status-open { border-left: 4px solid #4a90e2; }
|
||||
.status-done { border-left: 4px solid #7ed321; }
|
||||
.recording { margin: 0.5em 0; display: flex; align-items: center; gap: 1em; }
|
||||
.recording span { font-family: monospace; font-size: 0.9em; min-width: 20em; }
|
||||
.recording { margin: 0.5em 0; }
|
||||
.recording-head { display: flex; align-items: center; gap: 1em; }
|
||||
.recording-head span { font-family: monospace; font-size: 0.9em; min-width: 20em; }
|
||||
.transcript { margin: 0.5em 0 0 1em; padding: 0.5em; background: #f6f6f6; border-radius: 4px; white-space: pre-wrap; font-family: serif; }
|
||||
.pending { margin: 0.5em 0 0 1em; color: #888; font-style: italic; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -25,11 +28,19 @@ body { font-family: sans-serif; max-width: 900px; margin: 2em auto; padding: 0 1
|
||||
<small>{{ case.case_id }}</small>
|
||||
{% for rec in case.recordings %}
|
||||
<div class="recording">
|
||||
<div class="recording-head">
|
||||
<span>{{ rec.filename }}</span>
|
||||
<audio controls preload="none">
|
||||
<source src="/web/audio/{{ case.user_slug }}/{{ case.case_id }}/{{ rec.filename }}" type="audio/mp4">
|
||||
</audio>
|
||||
</div>
|
||||
{% match rec.transcript %}
|
||||
{% when Some with (t) %}
|
||||
<div class="transcript">{{ t }}</div>
|
||||
{% when None %}
|
||||
<div class="pending">Transcription pending…</div>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user