Update app.py
Browse files
app.py
CHANGED
|
@@ -10,9 +10,10 @@ import subprocess
|
|
| 10 |
import shutil
|
| 11 |
from datetime import datetime
|
| 12 |
from sqlmodel import SQLModel, Field, create_engine, Session, select
|
| 13 |
-
|
| 14 |
-
# === Clean safe app-generated temp files ===
|
| 15 |
import glob
|
|
|
|
|
|
|
| 16 |
for pattern in ["/tmp/*.wav", "/tmp/*.mp3"]:
|
| 17 |
for filepath in glob.glob(pattern):
|
| 18 |
try:
|
|
@@ -35,9 +36,10 @@ LANG_CODES = {
|
|
| 35 |
"Arabic": "ar", "Chinese": "zh", "Portuguese": "pt", "Japanese": "ja", "Korean": "ko"
|
| 36 |
}
|
| 37 |
|
| 38 |
-
# === SQLModel
|
| 39 |
class SessionEntry(SQLModel, table=True):
|
| 40 |
-
id: int = Field(default=None, primary_key=True)
|
|
|
|
| 41 |
timestamp: str
|
| 42 |
transcript: str
|
| 43 |
feedback: str
|
|
@@ -46,9 +48,10 @@ class SessionEntry(SQLModel, table=True):
|
|
| 46 |
engine = create_engine(f"sqlite:///{db_path}")
|
| 47 |
SQLModel.metadata.create_all(engine)
|
| 48 |
|
| 49 |
-
def save_to_db(transcript, feedback, language):
|
| 50 |
session = Session(engine)
|
| 51 |
entry = SessionEntry(
|
|
|
|
| 52 |
timestamp=datetime.now().strftime("%Y-%m-%d %H:%M"),
|
| 53 |
transcript=transcript,
|
| 54 |
feedback=feedback,
|
|
@@ -58,9 +61,9 @@ def save_to_db(transcript, feedback, language):
|
|
| 58 |
session.commit()
|
| 59 |
session.close()
|
| 60 |
|
| 61 |
-
def
|
| 62 |
session = Session(engine)
|
| 63 |
-
statement = select(SessionEntry)
|
| 64 |
results = session.exec(statement).all()
|
| 65 |
session.close()
|
| 66 |
return results
|
|
@@ -121,7 +124,7 @@ Transcript:
|
|
| 121 |
)
|
| 122 |
return response.choices[0].message.content
|
| 123 |
|
| 124 |
-
def tutor_feedback(audio_file, language):
|
| 125 |
if not audio_file or not os.path.exists(audio_file):
|
| 126 |
return "", "No audio received.", None, "", []
|
| 127 |
|
|
@@ -134,8 +137,8 @@ def tutor_feedback(audio_file, language):
|
|
| 134 |
mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
|
| 135 |
tts.save(mp3_path)
|
| 136 |
|
| 137 |
-
save_to_db(transcript, feedback_text, language)
|
| 138 |
-
sessions =
|
| 139 |
|
| 140 |
return transcript, feedback_text, mp3_path, transcript, [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions]
|
| 141 |
|
|
@@ -145,10 +148,11 @@ with gr.Blocks(css="light_mode_chatter_owl.css") as app:
|
|
| 145 |
<div id="header" style="text-align: center;">
|
| 146 |
<img src="file/images/chatter_owl.png" width="120">
|
| 147 |
<h2>🦉 Meet <strong>Chatter the Owl</strong></h2>
|
| 148 |
-
<p>
|
| 149 |
</div>
|
| 150 |
""")
|
| 151 |
|
|
|
|
| 152 |
language_dropdown = gr.Dropdown(label="🌍 Select Your Language", choices=list(LANG_CODES.keys()), value="English")
|
| 153 |
|
| 154 |
with gr.Row():
|
|
@@ -168,7 +172,7 @@ with gr.Blocks(css="light_mode_chatter_owl.css") as app:
|
|
| 168 |
|
| 169 |
# Interactions
|
| 170 |
audio_input.change(fn=tutor_feedback,
|
| 171 |
-
inputs=[audio_input, language_dropdown],
|
| 172 |
outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, history_table])
|
| 173 |
|
| 174 |
try_again.click(fn=lambda: ("", "", None, "", "", []),
|
|
|
|
| 10 |
import shutil
|
| 11 |
from datetime import datetime
|
| 12 |
from sqlmodel import SQLModel, Field, create_engine, Session, select
|
| 13 |
+
from typing import Optional
|
|
|
|
| 14 |
import glob
|
| 15 |
+
|
| 16 |
+
# === Clean temp audio files ===
|
| 17 |
for pattern in ["/tmp/*.wav", "/tmp/*.mp3"]:
|
| 18 |
for filepath in glob.glob(pattern):
|
| 19 |
try:
|
|
|
|
| 36 |
"Arabic": "ar", "Chinese": "zh", "Portuguese": "pt", "Japanese": "ja", "Korean": "ko"
|
| 37 |
}
|
| 38 |
|
| 39 |
+
# === SQLModel with nickname support ===
|
| 40 |
class SessionEntry(SQLModel, table=True):
|
| 41 |
+
id: Optional[int] = Field(default=None, primary_key=True)
|
| 42 |
+
user: str
|
| 43 |
timestamp: str
|
| 44 |
transcript: str
|
| 45 |
feedback: str
|
|
|
|
| 48 |
engine = create_engine(f"sqlite:///{db_path}")
|
| 49 |
SQLModel.metadata.create_all(engine)
|
| 50 |
|
| 51 |
+
def save_to_db(user, transcript, feedback, language):
|
| 52 |
session = Session(engine)
|
| 53 |
entry = SessionEntry(
|
| 54 |
+
user=user,
|
| 55 |
timestamp=datetime.now().strftime("%Y-%m-%d %H:%M"),
|
| 56 |
transcript=transcript,
|
| 57 |
feedback=feedback,
|
|
|
|
| 61 |
session.commit()
|
| 62 |
session.close()
|
| 63 |
|
| 64 |
+
def fetch_user_sessions(user):
|
| 65 |
session = Session(engine)
|
| 66 |
+
statement = select(SessionEntry).where(SessionEntry.user == user)
|
| 67 |
results = session.exec(statement).all()
|
| 68 |
session.close()
|
| 69 |
return results
|
|
|
|
| 124 |
)
|
| 125 |
return response.choices[0].message.content
|
| 126 |
|
| 127 |
+
def tutor_feedback(audio_file, language, nickname):
|
| 128 |
if not audio_file or not os.path.exists(audio_file):
|
| 129 |
return "", "No audio received.", None, "", []
|
| 130 |
|
|
|
|
| 137 |
mp3_path = f"/tmp/{uuid.uuid4()}.mp3"
|
| 138 |
tts.save(mp3_path)
|
| 139 |
|
| 140 |
+
save_to_db(nickname, transcript, feedback_text, language)
|
| 141 |
+
sessions = fetch_user_sessions(nickname)
|
| 142 |
|
| 143 |
return transcript, feedback_text, mp3_path, transcript, [[s.timestamp, s.language, s.transcript[:40], s.feedback[:40]] for s in sessions]
|
| 144 |
|
|
|
|
| 148 |
<div id="header" style="text-align: center;">
|
| 149 |
<img src="file/images/chatter_owl.png" width="120">
|
| 150 |
<h2>🦉 Meet <strong>Chatter the Owl</strong></h2>
|
| 151 |
+
<p>Enter your name, choose a language, and speak! I’ll help you grow as a communicator.</p>
|
| 152 |
</div>
|
| 153 |
""")
|
| 154 |
|
| 155 |
+
nickname_box = gr.Textbox(label="👤 Your Nickname", placeholder="Enter your name...")
|
| 156 |
language_dropdown = gr.Dropdown(label="🌍 Select Your Language", choices=list(LANG_CODES.keys()), value="English")
|
| 157 |
|
| 158 |
with gr.Row():
|
|
|
|
| 172 |
|
| 173 |
# Interactions
|
| 174 |
audio_input.change(fn=tutor_feedback,
|
| 175 |
+
inputs=[audio_input, language_dropdown, nickname_box],
|
| 176 |
outputs=[transcript_box, feedback_box, audio_output, hidden_transcript, history_table])
|
| 177 |
|
| 178 |
try_again.click(fn=lambda: ("", "", None, "", "", []),
|