| import gradio as gr |
| import uuid |
| from gtts import gTTS |
| from datetime import datetime |
| from sqlmodel import Session |
| from app_utils import ( |
| model, LANG_CODES, client, save_to_db, fetch_user_sessions, |
| convert_to_wav, transcribe_audio, generate_feedback, generate_example_response |
| ) |
|
|
| def spoken_dashboard(): |
| with gr.Column() as spoken_panel: |
| gr.Markdown(""" |
| <div id="header" style="text-align: center;"> |
| <img src="file/images/chatter_owl.png" width="120"> |
| <h2>π¦ Meet <strong>Chatter the Owl</strong></h2> |
| <p>Enter your name, choose a language and goal, and speak! Iβll help you grow as a communicator.</p> |
| </div> |
| """) |
|
|
| nickname_box = gr.Textbox(label="π€ Your Nickname", placeholder="Enter your name...") |
| language_dropdown = gr.Dropdown(label="π Select Your Language", choices=list(LANG_CODES.keys()), value="English") |
|
|
| goal_dropdown = gr.Dropdown( |
| label="π― Communication Goal", |
| choices=[ |
| "Interview preparation", |
| "Public speaking", |
| "Class presentation", |
| "General improvement" |
| ], |
| value="General improvement" |
| ) |
|
|
| focus_checkboxes = gr.CheckboxGroup( |
| label="π§ Areas to Focus On", |
| choices=["Clarity", "Structure", "Fluency", "Tone", "Content Relevance"], |
| value=["Clarity", "Structure", "Fluency", "Tone", "Content Relevance"] |
| ) |
|
|
| with gr.Row(): |
| audio_input = gr.Audio(type="filepath", label="π Speak or Upload Audio") |
|
|
| transcript_box = gr.Textbox(label="π What You Said", interactive=False) |
| feedback_box = gr.Textbox(label="π‘ Chatterβs Feedback", interactive=False) |
| audio_output = gr.Audio(label="π Chatter Speaks", type="filepath") |
| hidden_transcript = gr.Textbox(visible=False) |
|
|
| with gr.Row(): |
| try_again = gr.Button("π Try Again") |
| show_example = gr.Button("π― Show Me an Example") |
|
|
| example_box = gr.Textbox(label="π£ Suggested Improvement", visible=True, placeholder="Click to generate improved speech...") |
| history_table = gr.Dataframe(headers=["π Timestamp", "π Language", "π Transcript (Preview)", "π Feedback (Preview)"]) |
|
|
| def fetch_last_transcript(nickname): |
| if not nickname: |
| return None |
| sessions = fetch_user_sessions(nickname) |
| return sessions[-1].transcript if sessions else None |
|
|
| def tutor_feedback(audio_file, language, nickname, goal, focus_areas): |
| if not audio_file: |
| return "", "No audio received.", None, "", [] |
|
|
| wav_path = convert_to_wav(audio_file) |
| transcript = transcribe_audio(wav_path) |
| previous = fetch_last_transcript(nickname) |
|
|
| feedback_text = generate_feedback( |
| transcript=transcript, |
| language=language, |
| goal=goal, |
| focus_areas=focus_areas, |
| previous_transcript=previous |
| ) |
|
|
| lang_code = LANG_CODES.get(language, "en") |
| tts = gTTS(feedback_text, lang=lang_code) |
| mp3_path = f"/tmp/{uuid.uuid4()}.mp3" |
| tts.save(mp3_path) |
|
|
| if nickname: |
| save_to_db(nickname, transcript, feedback_text, language) |
|
|
| sessions = fetch_user_sessions(nickname) |
| session_table = [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions] |
|
|
| return transcript, feedback_text, mp3_path, transcript, session_table |
|
|
| audio_input.change( |
| fn=tutor_feedback, |
| inputs=[audio_input, language_dropdown, nickname_box, goal_dropdown, focus_checkboxes], |
| outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, history_table], |
| show_progress="minimal" |
| ) |
|
|
| try_again.click(fn=lambda: ("", "", None, "", "", []), |
| inputs=None, |
| outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, example_box, history_table]) |
|
|
| show_example.click(fn=generate_example_response, |
| inputs=[hidden_transcript, language_dropdown], |
| outputs=example_box) |
|
|
| return spoken_panel |
|
|