{% extends "base.html" %} {% block title %}Lectures — CLM Recordings{% endblock %} {% block content %}

Lectures

{# Hidden listener: OBS state changes re-fetch the dynamic content so the banner appears/disappears and Record/Arm buttons toggle their disabled attribute without a manual reload. Subscribing to `job` as well keeps the deck-status column in sync when Auphonic jobs finish — without it the row badge stays stuck at "processing" until the user reloads. #}
{% if not snapshot.obs_connected %} {% endif %}
{% if snapshot.armed_deck %} {% endif %} {% if error %} {% endif %} {% for section in sections %}

{{ section.name }}

{% for deck in section.decks %} {% set is_armed = snapshot.armed_deck and snapshot.armed_deck.deck_name == deck.deck_name and snapshot.armed_deck.section_name == section.name %} {% endfor %}
Deck Status Actions
{{ deck.display_name }} {% if is_armed and snapshot.state.value in ('recording', 'paused') %} {% if snapshot.state.value == 'paused' %} paused {% else %} recording {% endif %} {% if snapshot.recording_elapsed_seconds is not none %} {{ '%d:%02d' | format( (snapshot.recording_elapsed_seconds | int) // 60, (snapshot.recording_elapsed_seconds | int) % 60 ) }} {% endif %} {% endif %} {% if deck.status %} {% set st = deck.status.state.value %} {{ st | replace("_", " ") }} {# Surface a failed-job indicator even when the main state falls back to "recorded" (raw file still on disk after Auphonic rejected the job). Otherwise the user sees "recorded" and has no cue that the last processing attempt failed. #} {% if deck.status.failed_job_id and deck.status.state.value != 'failed' %} processing failed {% endif %} {% if deck.status.final_parts and deck.status.raw_parts %} (done: {{ deck.status.final_parts | join(", ") }}; raw: {{ deck.status.raw_parts | join(", ") }}) {% elif deck.status.parts | length > 1 %} (parts {{ deck.status.parts | join(", ") }}) {% elif deck.status.parts | length == 1 and deck.status.parts[0] != 0 %} (part {{ deck.status.parts[0] }}) {% endif %} {% endif %}
{% if is_armed and snapshot.state.value == 'recording' %}
{% elif is_armed and snapshot.state.value == 'paused' %}
{% else %} {# Shared form: two submit buttons, one per action. The per-button hx-post overrides the form's so the Part input is shared but Record vs. Arm hits the right route. #}
{% if is_armed %}
{% endif %} {% endif %} {% if deck.status and deck.status.state.value in ('recorded', 'failed') and deck.status.raw_paths %}
{% for rp in deck.status.raw_paths %} {% endfor %}
{# Advance operates on whichever part is currently unsuffixed on disk; use the first recorded part (matches the _preserve_active_take probe). #}
{% elif deck.status and deck.status.state.value == 'processing' %} processing… {% endif %}
{% endfor %} {% if not sections and not error %}

No sections found in the course.

{% endif %}
{# /#lectures-dynamic #} {% endblock %}