Spaces:
Runtime error
Runtime error
| import dash_bootstrap_components as dbc | |
| from dash import dcc, html | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| BUCKET_NAME = "moore-collection" | |
| # --- Helper pour récupérer les chapitres --- | |
| def get_chapter_paths(base_folder): | |
| base = Path(base_folder) | |
| return [d for d in base.iterdir() if d.is_dir()] | |
| chapters = get_chapter_paths("assets") | |
| chapter_options = [{"label": d.name, "value": str(d)} for d in chapters] | |
| # --- Fonctions de création des différentes cards --- | |
| def header_card(): | |
| """Carte d'en-tête avec le titre de l'application.""" | |
| return dbc.Row( | |
| dbc.Col( | |
| html.H1( | |
| "Outil de transcription audio", | |
| className="text-center my-4 text-primary", | |
| ), | |
| width=12, | |
| ) | |
| ) | |
| def user_info_card(): | |
| """Carte pour la saisie des informations utilisateur.""" | |
| return dbc.Row( | |
| dbc.Col( | |
| [ | |
| dbc.Input( | |
| id="user-info", | |
| placeholder="Entrez votre email, pseudonyme ou nom pour qu'on vous crédite", | |
| type="text", | |
| className="mb-3", | |
| ), | |
| dbc.Button( | |
| "Continuer", | |
| id="pseudo-continue-button", | |
| color="primary", | |
| className="w-100", | |
| ), | |
| ], | |
| width=12, | |
| ) | |
| ) | |
| def chapter_card(): | |
| """Carte pour la sélection d'un chapitre.""" | |
| return dbc.Row( | |
| id="chapter-section", | |
| style={"display": "none"}, | |
| children=[ | |
| dbc.Col( | |
| dbc.Card( | |
| [ | |
| dbc.CardHeader("Sélectionnez un chapitre"), | |
| dbc.CardBody( | |
| [ | |
| dcc.Dropdown( | |
| id="chapter-dropdown", | |
| options=chapter_options, | |
| placeholder="Choisissez un chapitre", | |
| ), | |
| dbc.Button( | |
| "Continuer", | |
| id="chapter-continue-button", | |
| color="primary", | |
| className="w-100 mt-2", | |
| ), | |
| ] | |
| ), | |
| ] | |
| ), | |
| width=12, | |
| ) | |
| ], | |
| ) | |
| def page_card(): | |
| """Carte pour la sélection d'une page.""" | |
| return dbc.Row( | |
| id="page-section", | |
| style={"display": "none"}, | |
| children=[ | |
| dbc.Col( | |
| dbc.Card( | |
| [ | |
| dbc.CardHeader("Sélectionnez une page"), | |
| dbc.CardBody( | |
| [ | |
| dcc.Dropdown( | |
| id="page-dropdown", | |
| placeholder="Choisissez une page", | |
| ), | |
| dbc.Button( | |
| "Démarrer la transcription", | |
| id="start-button", | |
| color="primary", | |
| className="w-100 mt-2", | |
| ), | |
| ] | |
| ), | |
| ] | |
| ), | |
| width=12, | |
| ) | |
| ], | |
| ) | |
| def transcription_card(): | |
| """Carte regroupant la lecture audio, les suggestions et les actions de transcription.""" | |
| audio_card = dbc.Card( | |
| [ | |
| dbc.CardHeader("Lecture audio"), | |
| dbc.CardBody( | |
| dcc.Loading( | |
| html.Audio( | |
| id="audio-player", | |
| controls=True, | |
| autoPlay=False, | |
| className="w-100", | |
| ) | |
| ) | |
| ), | |
| ], | |
| className="mb-4 shadow", | |
| ) | |
| suggestion_card = dbc.Card( | |
| [ | |
| dbc.CardHeader("Suggestions de transcriptions"), | |
| dbc.CardBody( | |
| dcc.Checklist( | |
| id="suggestion-checklist", | |
| options=[], # Initialement vide, sera mis à jour via callback | |
| value=[], | |
| style={"columns": "3", "column-gap": "1rem"}, | |
| ) | |
| ), | |
| ], | |
| className="mb-4 shadow", | |
| ) | |
| hidden_message = html.Div( | |
| id="hidden-message", | |
| style={"display": "none"}, | |
| children=[ | |
| html.P( | |
| "Traitement de la page actuelle terminé, vous devez changer de page pour continuer. N'oubliez pas de sauvegarder.", | |
| style={"color": "red"}, | |
| ) | |
| ], | |
| ) | |
| action_buttons = dbc.Col( | |
| [ | |
| dbc.Button( | |
| "Soumettre", | |
| id="submit-button", | |
| n_clicks=0, | |
| color="secondary", | |
| className="w-100", | |
| style={"marginTop": "20px"}, | |
| ), | |
| dbc.Button( | |
| "Sauvegarder résultats", | |
| id="save-results-button", | |
| n_clicks=0, | |
| color="success", | |
| className="w-100", | |
| style={"marginTop": "20px"}, | |
| ), | |
| ], | |
| width=12, | |
| ) | |
| confirmation_message = dbc.Col( | |
| html.Div( | |
| id="confirmation-message", | |
| className="text-success text-center mt-3", | |
| ), | |
| width=12, | |
| ) | |
| # La carte de transcription regroupe plusieurs composants et dcc.Store pour l'état | |
| return dbc.Row( | |
| id="transcription-section", | |
| style={"display": "none"}, | |
| children=[ | |
| dbc.Col(audio_card, width=12), | |
| dbc.Col(suggestion_card, width=12), | |
| dbc.Col(hidden_message, width=12), | |
| action_buttons, | |
| confirmation_message, | |
| # Stores pour l'état de l'application | |
| dcc.Store(id="transcription-store", data=[], storage_type='session'), | |
| dcc.Store(id="audio-store", data=[], storage_type='session'), | |
| dcc.Store(id="values-store", data=[], storage_type='session'), | |
| ], | |
| ) | |
| def create_layout(): | |
| """Compose le layout principal à partir des différentes cards.""" | |
| return dbc.Container( | |
| [ | |
| header_card(), | |
| user_info_card(), | |
| chapter_card(), | |
| page_card(), | |
| transcription_card(), | |
| ], | |
| fluid=True, | |
| className="p-4", | |
| ) | |
| # Initialisation du layout | |
| layout = create_layout() | |
| from .callbacks import * |