Skip to main content

FastHTML Reader View component for verifying transcript segmentation with audio playback and context graph commit.

Project description

cjm-transcript-review

Install

pip install cjm_transcript_review

Project Structure

nbs/
├── components/ (7)
│   ├── audio_controls.ipynb     # Audio playback controls: speed selector and auto-navigate toggle
│   ├── callbacks.ipynb          # Focus change callback and audio playback JavaScript for the review card stack
│   ├── card_stack_config.ipynb  # Card stack configuration, HTML IDs, and button IDs for the review card stack
│   ├── helpers.ipynb            # State getters for the review step from InteractionContext
│   ├── keyboard_config.ipynb    # Review-specific keyboard building blocks for assembly into a KeyboardManager
│   ├── review_card.ipynb        # Review card component showing assembled segment with timing and source info
│   └── step_renderer.ipynb      # Composable render functions for the review card stack step
├── routes/ (5)
│   ├── audio.ipynb       # Route handlers for audio playback controls
│   ├── card_stack.ipynb  # Card stack UI operations — navigation, viewport, and response builders
│   ├── commit.ipynb      # Route handler for committing the document to the context graph
│   ├── core.ipynb        # Review step state management helpers
│   └── init.ipynb        # Router assembly for Phase 3 review routes
├── services/ (1)
│   └── graph.ipynb  # Graph service for committing documents and segments to the context graph
├── html_ids.ipynb  # HTML ID constants for Phase 3: Review & Commit
├── models.ipynb    # Review step state and working document model for Phase 3: Review & Commit
└── utils.ipynb     # Time formatting and source info display utilities for review cards

Total: 16 notebooks across 3 directories

Module Dependencies

graph LR
    components_audio_controls[components.audio_controls<br/>audio_controls]
    components_callbacks[components.callbacks<br/>callbacks]
    components_card_stack_config[components.card_stack_config<br/>card_stack_config]
    components_helpers[components.helpers<br/>helpers]
    components_keyboard_config[components.keyboard_config<br/>keyboard_config]
    components_review_card[components.review_card<br/>review_card]
    components_step_renderer[components.step_renderer<br/>step_renderer]
    html_ids[html_ids<br/>html_ids]
    models[models<br/>models]
    routes_audio[routes.audio<br/>audio]
    routes_card_stack[routes.card_stack<br/>card_stack]
    routes_commit[routes.commit<br/>commit]
    routes_core[routes.core<br/>core]
    routes_init[routes.init<br/>init]
    services_graph[services.graph<br/>graph]
    utils[utils<br/>utils]

    components_helpers --> models
    components_review_card --> utils
    components_review_card --> html_ids
    components_step_renderer --> components_callbacks
    components_step_renderer --> models
    components_step_renderer --> components_review_card
    components_step_renderer --> components_card_stack_config
    components_step_renderer --> html_ids
    components_step_renderer --> components_audio_controls
    components_step_renderer --> components_keyboard_config
    routes_audio --> models
    routes_audio --> routes_core
    routes_card_stack --> models
    routes_card_stack --> routes_core
    routes_card_stack --> components_step_renderer
    routes_card_stack --> components_review_card
    routes_card_stack --> components_card_stack_config
    routes_commit --> models
    routes_commit --> utils
    routes_commit --> routes_core
    routes_commit --> services_graph
    routes_core --> components_review_card
    routes_core --> models
    routes_init --> routes_core
    routes_init --> routes_commit
    routes_init --> models
    routes_init --> routes_card_stack
    routes_init --> routes_audio
    routes_init --> services_graph

29 cross-module dependencies detected

CLI Reference

No CLI commands found in this project.

Module Overview

Detailed documentation for each module in the project:

audio (audio.ipynb)

Route handlers for audio playback controls

Import

from cjm_transcript_review.routes.audio import (
    DEBUG_AUDIO_ROUTES,
    init_audio_router
)

Functions

def _generate_speed_change_js(
    speed:float  # New playback speed
) -> str:  # JavaScript to update playback rate
    "Generate JS to update Web Audio API playback rate via shared library."
def _generate_auto_nav_js(
    enabled:bool  # Whether auto-navigate is enabled
) -> str:  # JavaScript to update auto-navigate flag
    "Generate JS to update auto-navigate flag via shared library."
def _generate_replay_js() -> str:  # JavaScript to replay current segment
    "Generate JS to replay the current segment's audio."
def init_audio_router(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    prefix:str,  # Base prefix for audio routes
    urls:ReviewUrls,  # URL bundle to populate
) -> Tuple[APIRouter, Dict[str, Callable]]:  # (router, routes dict)
    "Initialize audio control routes."

Variables

DEBUG_AUDIO_ROUTES = False

audio_controls (audio_controls.ipynb)

Audio playback controls: speed selector and auto-navigate toggle

Import

from cjm_transcript_review.components.audio_controls import (
    PLAYBACK_SPEEDS,
    AudioControlIds,
    render_speed_selector,
    render_auto_navigate_toggle,
    render_audio_controls
)

Functions

def render_speed_selector(
    current_speed:float=1.0,  # Current playback speed
    change_url:str="",  # URL to POST speed changes to
) -> Any:  # Speed selector component
    "Render playback speed selector dropdown."
def render_auto_navigate_toggle(
    enabled:bool=False,  # Whether auto-navigate is enabled
    toggle_url:str="",  # URL to POST toggle changes to
) -> Any:  # Auto-navigate toggle component
    "Render auto-navigate toggle switch."
def render_audio_controls(
    current_speed:float=1.0,  # Current playback speed
    auto_navigate:bool=False,  # Whether auto-navigate is enabled
    speed_url:str="",  # URL for speed changes
    auto_nav_url:str="",  # URL for auto-navigate toggle
    oob:bool=False,  # Whether to render as OOB swap
) -> Any:  # Combined audio controls component
    "Render combined audio controls (speed selector + auto-navigate toggle)."

Classes

class AudioControlIds:
    "HTML ID constants for audio control elements."

Variables

PLAYBACK_SPEEDS: List[tuple]

callbacks (callbacks.ipynb)

Focus change callback and audio playback JavaScript for the review card stack

Import

from cjm_transcript_review.components.callbacks import (
    REVIEW_AUDIO_CONFIG,
    generate_review_callbacks_script
)

Functions

def generate_review_callbacks_script(
    ids:CardStackHtmlIds,  # Card stack HTML IDs
    button_ids:CardStackButtonIds,  # Card stack button IDs
    config:CardStackConfig,  # Card stack configuration
    urls:CardStackUrls,  # Card stack URL bundle
    container_id:str,  # ID of the review container (parent of card stack)
    focus_input_id:str,  # ID of hidden input for focused segment index
) -> any:  # Script element with all JavaScript callbacks
    "Generate JavaScript for review card stack with Web Audio API audition."

Variables

REVIEW_AUDIO_CONFIG

card_stack (card_stack.ipynb)

Card stack UI operations — navigation, viewport, and response builders

Import

from cjm_transcript_review.routes.card_stack import (
    init_card_stack_router
)

Functions

def _build_slots_oob(
    assembled:List[AssembledSegment],  # Assembled segments with VAD chunks
    state:CardStackState,  # Card stack viewport state
    urls:ReviewUrls,  # URL bundle
) -> List[Any]:  # OOB slot elements
    "Build OOB slot updates for the viewport sections."
def _build_nav_response(
    assembled:List[AssembledSegment],  # Assembled segments with VAD chunks
    state:CardStackState,  # Card stack viewport state
    urls:ReviewUrls,  # URL bundle
) -> Tuple:  # OOB elements (slots + progress + focus)
    "Build OOB response for navigation."
def _handle_review_navigate(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    sess,  # FastHTML session object
    direction:str,  # Navigation direction: "up", "down", "first", "last", "page_up", "page_down"
    urls:ReviewUrls,  # URL bundle for review routes
):  # OOB slot updates with progress, focus, and source position
    "Navigate to a different segment in the viewport using OOB slot swaps."
async def _handle_review_update_viewport(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    request,  # FastHTML request object
    sess,  # FastHTML session object
    visible_count:int,  # New number of visible cards
    urls:ReviewUrls,  # URL bundle for review routes
):  # Full viewport component (outerHTML swap)
    "Update the viewport with a new card count."
def _handle_review_save_width(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    sess,  # FastHTML session object
    card_width:int,  # Card stack width in rem
) -> None:  # No response body (swap=none on client)
    "Save the card stack width to server state."
def init_card_stack_router(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    prefix:str,  # Route prefix (e.g., "/workflow/review/card_stack")
    urls:ReviewUrls,  # URL bundle (populated after routes defined)
) -> Tuple[APIRouter, Dict[str, Callable]]:  # (router, route_dict)
    "Initialize card stack routes for review."

card_stack_config (card_stack_config.ipynb)

Card stack configuration, HTML IDs, and button IDs for the review card stack

Import

from cjm_transcript_review.components.card_stack_config import (
    REVIEW_CS_CONFIG,
    REVIEW_CS_IDS,
    REVIEW_CS_BTN_IDS
)

Variables

REVIEW_CS_CONFIG
REVIEW_CS_IDS
REVIEW_CS_BTN_IDS

commit (commit.ipynb)

Route handler for committing the document to the context graph

Import

from cjm_transcript_review.routes.commit import (
    DEBUG_COMMIT_ROUTES,
    COMMIT_ALERT_ID,
    CommitResult,
    init_commit_router
)

Functions

def _render_commit_alert(
    result:CommitResult,  # Commit operation result
    auto_dismiss_ms:int=5000,  # Auto-dismiss after milliseconds (0 = no auto-dismiss)
) -> Div:  # Alert element with optional auto-dismiss script
    "Render a success or error alert for commit result."
async def _handle_commit(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str,  # Session identifier string
    graph_service:GraphService,  # Graph service for committing
    document_title:Optional[str]=None,  # Override document title (None = auto-generate)
) -> CommitResult:  # Result of the commit operation
    "Handle committing the document to the context graph."
def init_commit_router(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    prefix:str,  # Base prefix for commit route
    graph_service:GraphService,  # Graph service for committing
    urls:ReviewUrls,  # URL bundle to populate
    alert_container_id:str="commit-alert-container",  # ID of container for alert OOB swap
) -> Tuple[APIRouter, Dict[str, Callable]]:  # (router, routes dict)
    "Initialize commit route."

Classes

@dataclass
class CommitResult:
    "Result of a commit operation."
    
    success: bool  # Whether the commit succeeded
    document_id: Optional[str]  # Created document node ID
    segment_count: int = 0  # Number of segments committed
    edge_count: int = 0  # Number of edges created
    error: Optional[str]  # Error message if failed

Variables

DEBUG_COMMIT_ROUTES = False
COMMIT_ALERT_ID = 'commit-alert'

core (core.ipynb)

Review step state management helpers

Import

from cjm_transcript_review.routes.core import (
    WorkflowStateStore,
    DEBUG_REVIEW_STATE,
    ReviewContext
)

Functions

def _get_review_state(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str  # Session identifier string
) -> ReviewStepState:  # Review step state dictionary
    "Get the review step state from the workflow state store."
def _get_segmentation_state(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str  # Session identifier string
) -> Dict[str, Any]:  # Segmentation step state dictionary
    "Get the segmentation step state from the workflow state store."
def _get_alignment_state(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str  # Session identifier string
) -> Dict[str, Any]:  # Alignment step state dictionary
    "Get the alignment step state from the workflow state store."
def _load_review_context(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str  # Session identifier string
) -> ReviewContext:  # Common review state values
    "Load commonly-needed review state values including cross-step data."
def _get_assembled_segments(
    ctx:ReviewContext  # Loaded review context
) -> List[AssembledSegment]:  # Paired segments with VAD chunks
    "Pair segments with VAD chunks for review display."
def _update_review_state(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str,  # Session identifier string
    focused_index:int=None,  # Updated focused index (None = don't change)
    visible_count:int=None,  # Visible card count (None = don't change)
    is_auto_mode:bool=None,  # Auto-adjust mode flag (None = don't change)
    card_width:int=None,  # Card stack width in rem (None = don't change)
    document_title:str=None,  # Document title (None = don't change)
    is_validated:bool=None,  # Validation flag (None = don't change)
    playback_speed:float=None,  # Playback speed (None = don't change)
    auto_navigate:bool=None,  # Auto-navigate flag (None = don't change)
) -> None
    "Update the review step state in the workflow state store."
def _handle_update_title(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    session_id:str,  # Session identifier string
    document_title:str,  # New document title from form input
) -> None
    "Update the document title in review state."
def _build_card_stack_state(
    ctx:ReviewContext,  # Loaded review context
) -> CardStackState:  # Card stack state for library functions
    "Build a CardStackState from review context for library calls."

Classes

class ReviewContext(NamedTuple):
    "Common review state values loaded by handlers."

Variables

DEBUG_REVIEW_STATE = False

graph (graph.ipynb)

Graph service for committing documents and segments to the context graph

Import

from cjm_transcript_review.services.graph import (
    GraphService
)

Classes

class GraphService:
    def __init__(
        self,
        plugin_manager:PluginManager,  # Plugin manager for accessing graph plugin
        plugin_name:str="cjm-graph-plugin-sqlite",  # Name of the graph plugin
    )
    "Service for committing structure to context graph."
    
    def __init__(
            self,
            plugin_manager:PluginManager,  # Plugin manager for accessing graph plugin
            plugin_name:str="cjm-graph-plugin-sqlite",  # Name of the graph plugin
        )
        "Initialize the graph service."
    
    def is_available(self) -> bool:  # True if plugin is loaded and ready
            """Check if the graph plugin is available."""
            return self._manager.get_plugin(self._plugin_name) is not None
        
        def ensure_loaded(
            self,
            config:Optional[Dict[str, Any]]=None,  # Optional plugin configuration
        ) -> bool:  # True if successfully loaded
        "Check if the graph plugin is available."
    
    def ensure_loaded(
            self,
            config:Optional[Dict[str, Any]]=None,  # Optional plugin configuration
        ) -> bool:  # True if successfully loaded
        "Ensure the graph plugin is loaded."
    
    async def commit_document_async(
            self,
            title:str,  # Document title
            text_segments:List[TextSegment],  # Text segments from decomposition
            vad_chunks:List[VADChunk],  # VAD chunks for timing (1:1 with segments)
            media_type:str="audio",  # Source media type
        ) -> Dict[str, Any]:  # Result with document_id and segment_ids
        "Commit a document to the context graph.

Assembles text segments with VAD timing at commit time.
Requires 1:1 alignment: len(text_segments) == len(vad_chunks)."
    
    def commit_document(
            self,
            title:str,  # Document title
            text_segments:List[TextSegment],  # Text segments from decomposition
            vad_chunks:List[VADChunk],  # VAD chunks for timing
            media_type:str="audio",  # Source media type
        ) -> Dict[str, Any]:  # Result with document_id and segment_ids
        "Commit a document to the context graph synchronously."

helpers (helpers.ipynb)

State getters for the review step from InteractionContext

Import

from cjm_transcript_review.components.helpers import *

Functions

def _get_review_state(
    ctx:InteractionContext  # Interaction context with state
) -> ReviewStepState:  # Typed review step state
    "Get the full review step state from context."
def _get_focused_index(
    ctx:InteractionContext,  # Interaction context with state
    default:int=0,  # Default focused index
) -> int:  # Currently focused segment index
    "Get the currently focused segment index."
def _get_visible_count(
    ctx:InteractionContext,  # Interaction context with state
    default:int=5,  # Default visible card count
) -> int:  # Number of visible cards in viewport
    "Get the stored visible card count."
def _get_is_auto_mode(
    ctx:InteractionContext,  # Interaction context with state
) -> bool:  # Whether card count is in auto-adjust mode
    "Get whether the card count is in auto-adjust mode."
def _get_card_width(
    ctx:InteractionContext,  # Interaction context with state
    default:int=50,  # Default card width in rem
) -> int:  # Card stack width in rem
    "Get the stored card stack width."
def _get_segments(
    ctx:InteractionContext  # Interaction context with state
) -> List[TextSegment]:  # List of TextSegment objects from segmentation step
    "Get text segments from segmentation step state."
def _get_vad_chunks(
    ctx:InteractionContext  # Interaction context with state
) -> List[VADChunk]:  # List of VADChunk objects from alignment step
    "Get VAD chunks from alignment step state."
def _get_media_path(
    ctx:InteractionContext  # Interaction context with state
) -> Optional[str]:  # Path to original audio file or None
    "Get the original audio file path from alignment step."
def _is_aligned(
    ctx:InteractionContext  # Interaction context with state
) -> bool:  # True if segment count matches VAD chunk count
    "Check if segments are aligned with VAD chunks (1:1 match)."

html_ids (html_ids.ipynb)

HTML ID constants for Phase 3: Review & Commit

Import

from cjm_transcript_review.html_ids import (
    ReviewHtmlIds
)

Classes

class ReviewHtmlIds:
    "HTML ID constants for Phase 3: Review & Commit."
    
    def as_selector(
            id_str:str  # The HTML ID to convert
        ) -> str:  # CSS selector with # prefix
        "Convert an ID to a CSS selector format."
    
    def review_card(
            index:int  # Segment index
        ) -> str:  # HTML ID for review card
        "Generate HTML ID for a review card."

init (init.ipynb)

Router assembly for Phase 3 review routes

Import

from cjm_transcript_review.routes.init import (
    init_review_routers
)

Functions

def init_review_routers(
    state_store:WorkflowStateStore,  # The workflow state store
    workflow_id:str,  # The workflow identifier
    prefix:str,  # Base prefix for review routes (e.g., "/workflow/review")
    audio_src_url:str="",  # Audio source route (from core routes)
    graph_service:Optional[GraphService]=None,  # Graph service for commit (None = no commit route)
    alert_container_id:str="commit-alert-container",  # ID of container for commit alerts
) -> Tuple[List[APIRouter], ReviewUrls, Dict[str, Callable]]:  # (routers, urls, routes)
    "Initialize and return all review routers with URL bundle."

keyboard_config (keyboard_config.ipynb)

Review-specific keyboard building blocks for assembly into a KeyboardManager

Import

from cjm_transcript_review.components.keyboard_config import (
    create_review_kb_parts,
    create_review_keyboard_manager
)

Functions

def create_review_kb_parts(
    ids:CardStackHtmlIds,  # Card stack HTML IDs
    button_ids:CardStackButtonIds,  # Card stack button IDs for navigation
    config:CardStackConfig,  # Card stack configuration
) -> Tuple[FocusZone, tuple, tuple]:  # (zone, actions, modes)
    "Create review-specific keyboard building blocks."
def create_review_keyboard_manager(
    ids:CardStackHtmlIds,  # Card stack HTML IDs
    button_ids:CardStackButtonIds,  # Card stack button IDs for navigation
    config:CardStackConfig,  # Card stack configuration
) -> ZoneManager:  # Configured keyboard zone manager
    "Create the keyboard zone manager for the review step."

models (models.ipynb)

Review step state and working document model for Phase 3: Review & Commit

Import

from cjm_transcript_review.models import (
    ReviewStepState,
    ReviewUrls,
    WorkingDocument
)

Classes

class ReviewStepState(TypedDict):
    "State for Phase 3: Review & Commit."
@dataclass
class ReviewUrls:
    "URL bundle for Phase 3 review route handlers and renderers."
    
    card_stack: CardStackUrls = field(...)
    audio_src: str = ''  # Audio source route
    speed_change: str = ''  # Playback speed change handler
    toggle_auto_nav: str = ''  # Auto-navigate toggle handler
    replay_current: str = ''  # Replay current segment handler
    update_title: str = ''  # Document title update handler
    commit: str = ''  # Commit handler route
@dataclass
class WorkingDocument:
    "Container for workflow state during structure decomposition."
    
    title: str = ''  # Document title
    media_type: str = 'audio'  # Source media type ('audio', 'video', 'text')
    media_path: Optional[str]  # Path to primary source media
    source_blocks: List[SourceBlock] = field(...)  # Ordered source blocks
    combined_text: str = ''  # Concatenated text from all sources
    segments: List[TextSegment] = field(...)  # Decomposed segments
    vad_chunks: List[VADChunk] = field(...)  # VAD time ranges
    audio_duration: Optional[float]  # Total audio duration in seconds
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Convert to dictionary for JSON serialization."""
            return {
                'title': self.title,
        "Convert to dictionary for JSON serialization."
    
    def from_dict(
            cls,
            data: Dict[str, Any]  # Dictionary representation
        ) -> "WorkingDocument":  # Reconstructed WorkingDocument
        "Create from dictionary."

review_card (review_card.ipynb)

Review card component showing assembled segment with timing and source info

Import

from cjm_transcript_review.components.review_card import (
    AssembledSegment,
    render_review_card,
    create_review_card_renderer
)

Functions

def render_review_card(
    assembled:AssembledSegment,  # Assembled segment with text and timing
    card_role:CardRole,  # Role of this card in viewport ("focused" or "context")
    has_boundary_above:bool=False,  # Audio file boundary exists above this card
    has_boundary_below:bool=False,  # Audio file boundary exists below this card
) -> Any:  # Review card component
    "Render a single review card with text, timing, and source info."
def create_review_card_renderer(
    audio_file_boundaries:Set[int]=None,  # Indices where audio_file_index changes
) -> Callable:  # Card renderer callback: (item, CardRenderContext) -> FT
    "Create a card renderer callback for review cards."

Classes

@dataclass
class AssembledSegment:
    "A segment paired with its corresponding VAD chunk for review."
    
    segment: TextSegment  # Text segment with content and source info
    vad_chunk: VADChunk  # VAD chunk with timing
    
    def index(self) -> int:  # Segment index for card stack
            """Get the index from the segment."""
            return self.segment.index
        
        @property
        def text(self) -> str:  # Segment text content
        "Get the index from the segment."
    
    def text(self) -> str:  # Segment text content
            """Get the text content from the segment."""
            return self.segment.text
        
        @property
        def start_time(self) -> float:  # Start time from VAD chunk
        "Get the text content from the segment."
    
    def start_time(self) -> float:  # Start time from VAD chunk
            """Get the start time from the VAD chunk."""
            return self.vad_chunk.start_time
        
        @property
        def end_time(self) -> float:  # End time from VAD chunk
        "Get the start time from the VAD chunk."
    
    def end_time(self) -> float:  # End time from VAD chunk
        "Get the end time from the VAD chunk."

step_renderer (step_renderer.ipynb)

Composable render functions for the review card stack step

Import

from cjm_transcript_review.components.step_renderer import (
    DEBUG_REVIEW_RENDER,
    render_review_toolbar,
    render_review_stats,
    render_review_source_position,
    render_review_content,
    render_review_footer,
    render_review_step
)

Functions

def render_review_toolbar(
    visible_count:int=DEFAULT_VISIBLE_COUNT,  # Current visible card count
    is_auto_mode:bool=False,  # Whether card count is in auto-adjust mode
    playback_speed:float=1.0,  # Current playback speed
    auto_navigate:bool=False,  # Whether auto-navigate is enabled
    document_title:str="",  # Current document title
    urls:ReviewUrls=None,  # URL bundle for audio control routes
    oob:bool=False,  # Whether to render as OOB swap
) -> Any:  # Toolbar component
    "Render the review toolbar with title input, audio controls, and card count selector."
def render_review_stats(
    assembled:List[AssembledSegment],  # Assembled segments
    oob:bool=False,  # Whether to render as OOB swap
) -> Any:  # Statistics component
    "Render review statistics."
def render_review_source_position(
    assembled:List[AssembledSegment],  # Assembled segments
    focused_index:int=0,  # Currently focused segment index
    oob:bool=False,  # Whether to render as OOB swap
) -> Any:  # Audio file position indicator (empty if single file)
    "Render audio file position indicator for the focused segment."
def render_review_content(
    assembled:List[AssembledSegment],  # Assembled segments to display
    focused_index:int,  # Currently focused segment index
    visible_count:int,  # Number of visible cards in viewport
    card_width:int,  # Card stack width in rem
    urls:ReviewUrls,  # URL bundle for review routes
    audio_urls:Optional[List[str]]=None,  # Audio file URLs for Web Audio API
) -> Any:  # Main content area
    "Render the review content area with card stack viewport and keyboard system."
def render_review_footer(
    assembled:List[AssembledSegment],  # Assembled segments
    focused_index:int,  # Currently focused segment index
) -> Any:  # Footer content with progress indicator, source position, and stats
    "Render footer content with progress indicator, source position, and statistics."
def render_review_step(
    assembled:List[AssembledSegment],  # Assembled segments to display
    focused_index:int=0,  # Currently focused segment index
    visible_count:int=DEFAULT_VISIBLE_COUNT,  # Number of visible cards
    is_auto_mode:bool=False,  # Whether card count is in auto-adjust mode
    card_width:int=DEFAULT_CARD_WIDTH,  # Card stack width in rem
    playback_speed:float=1.0,  # Current playback speed
    auto_navigate:bool=False,  # Whether auto-navigate is enabled
    document_title:str="",  # Current document title
    urls:ReviewUrls=None,  # URL bundle for review routes
    audio_urls:Optional[List[str]]=None,  # Audio file URLs for Web Audio API
) -> Any:  # Complete review step component
    "Render the complete review step with toolbar, content, and footer."

Variables

DEBUG_REVIEW_RENDER = False

utils (utils.ipynb)

Time formatting and source info display utilities for review cards

Import

from cjm_transcript_review.utils import (
    format_time,
    format_duration,
    truncate_id,
    format_char_range,
    format_source_info,
    generate_document_title
)

Functions

def format_time(
    seconds:Optional[float]  # Time in seconds
) -> str:  # Formatted time string (m:ss.s)
    "Format seconds as m:ss.s for sub-second display."
def format_duration(
    start:Optional[float],  # Start time in seconds
    end:Optional[float],  # End time in seconds
) -> str:  # Formatted duration string (e.g., "3.2s")
    "Format duration from start/end times."
def truncate_id(
    id_str:Optional[str],  # Full ID string
    length:int=8,  # Number of characters to keep
) -> str:  # Truncated ID with ellipsis if needed
    "Truncate an ID string for display, adding ellipsis if truncated."
def format_char_range(
    start_char:Optional[int],  # Start character index
    end_char:Optional[int],  # End character index
) -> str:  # Formatted range string (e.g., "char:25-68")
    "Format character range for source reference display."
def format_source_info(
    provider_id:Optional[str],  # Source provider identifier
    source_id:Optional[str],  # Source record ID
    start_char:Optional[int]=None,  # Start character index
    end_char:Optional[int]=None,  # End character index
) -> str:  # Formatted source info string
    "Format source info for display in review cards."
def generate_document_title(
    media_path:Optional[str],  # Path to media file
    default:str="Untitled Document",  # Fallback title if path is None
) -> str:  # Clean document title
    "Generate a document title from a media file path."

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cjm_transcript_review-0.0.8.tar.gz (47.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cjm_transcript_review-0.0.8-py3-none-any.whl (43.4 kB view details)

Uploaded Python 3

File details

Details for the file cjm_transcript_review-0.0.8.tar.gz.

File metadata

  • Download URL: cjm_transcript_review-0.0.8.tar.gz
  • Upload date:
  • Size: 47.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for cjm_transcript_review-0.0.8.tar.gz
Algorithm Hash digest
SHA256 17d30cbbf25eb711d4fa261e9738779376048ee061fcc247c5a1bf6a588fc95a
MD5 e93f54eabfef3faa5e88feeb9ccff82d
BLAKE2b-256 0c07c0b1cf39c2832d4e654525b36c83543305e660d11b93583325bff35d0071

See more details on using hashes here.

File details

Details for the file cjm_transcript_review-0.0.8-py3-none-any.whl.

File metadata

File hashes

Hashes for cjm_transcript_review-0.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 e70158b4e1c3b17c177d1103a5e3b455c7b9edbf79c548f6780e4f33509cfd27
MD5 4e58ac4238cdb249e67bbd7f17fb7178
BLAKE2b-256 81ab72ee1d378e7cbbba580529d4168b1c16604ca9bd8f0ea4a1cc7159e234c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page