ankban commited on
Commit
8c8ef2f
Β·
verified Β·
1 Parent(s): 8cca692

Update app_utils.py

Browse files
Files changed (1) hide show
  1. app_utils.py +53 -126
app_utils.py CHANGED
@@ -1,106 +1,11 @@
1
- from sqlmodel import SQLModel, Field, create_engine, Session, select
2
- from datetime import datetime
3
- from typing import Optional
4
- import os
5
- import uuid
6
  import re
7
  import json
8
- import subprocess
9
- from faster_whisper import WhisperModel
10
- from openai import OpenAI
11
-
12
- # === Setup ===
13
- db_path = "/tmp/chatter_sessions.db"
14
- engine = create_engine(f"sqlite:///{db_path}")
15
- SQLModel.metadata.create_all(engine)
16
-
17
- openai_api_key = os.getenv("OPENAI_API_KEY")
18
- client = OpenAI(api_key=openai_api_key)
19
-
20
- LANG_CODES = {
21
- "English": "en", "Spanish": "es", "Hindi": "hi", "French": "fr", "German": "de",
22
- "Arabic": "ar", "Chinese": "zh", "Portuguese": "pt", "Japanese": "ja", "Korean": "ko"
23
- }
24
-
25
- # === Spoken Session Table ===
26
- class SessionEntry(SQLModel, table=True):
27
- id: Optional[int] = Field(default=None, primary_key=True)
28
- user: str
29
- timestamp: str
30
- transcript: str
31
- feedback: str
32
- language: str
33
-
34
- # === Spoken Session Utilities ===
35
- def save_to_db(user, transcript, feedback, language):
36
- session = Session(engine)
37
- entry = SessionEntry(
38
- user=user,
39
- timestamp=datetime.now().strftime("%Y-%m-%d %H:%M"),
40
- transcript=transcript,
41
- feedback=feedback,
42
- language=language
43
- )
44
- session.add(entry)
45
- session.commit()
46
- session.close()
47
-
48
- def fetch_user_sessions(user):
49
- session = Session(engine)
50
- statement = select(SessionEntry).where(SessionEntry.user == user)
51
- results = session.exec(statement).all()
52
- session.close()
53
- return results
54
-
55
- # === Whisper Model ===
56
- model = WhisperModel("base", compute_type="int8")
57
-
58
- def convert_to_wav(input_file):
59
- output_wav = f"/tmp/{uuid.uuid4()}.wav"
60
- command = ["ffmpeg", "-y", "-i", input_file, "-ar", "16000", "-ac", "1", output_wav]
61
- subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
62
- return output_wav
63
-
64
- def transcribe_audio(audio_path):
65
- segments, _ = model.transcribe(audio_path)
66
- return " ".join([segment.text for segment in segments])
67
-
68
- # === GPT: Personalized Feedback ===
69
- def generate_feedback(transcript, language, goal="general improvement", focus_areas=None, previous_transcript=None):
70
- focus_str = ", ".join(focus_areas) if focus_areas else "Clarity, Structure, Fluency, Content Relevance, and Tone"
71
- history_section = f"\n\nFor reference, their previous transcript was:\n{previous_transcript}" if previous_transcript else ""
72
-
73
- prompt = f"""
74
- You are a supportive communication coach helping a learner whose goal is: **{goal}**.
75
-
76
- First, return a JSON object of the scores (0–10) for each of the following categories:
77
- {focus_str}
78
-
79
- Then, write a detailed but friendly explanation for each.
80
-
81
- Finally, provide:
82
- - A summary of strengths and improvement areas.
83
- - One motivational line to end with.
84
-
85
- Transcript:
86
- {transcript}
87
- {history_section}
88
- """.strip()
89
-
90
- response = client.chat.completions.create(
91
- model="gpt-4",
92
- messages=[
93
- {"role": "system", "content": f"You are a warm and constructive communication coach responding in {language}."},
94
- {"role": "user", "content": prompt}
95
- ],
96
- temperature=0.7
97
- )
98
- return response.choices[0].message.content
99
 
 
100
 
101
  def parse_scores_from_feedback(feedback_text):
102
  try:
103
- # Match first valid-looking JSON block
104
  json_match = re.search(r"\{.*?\}", feedback_text, re.DOTALL)
105
  if json_match:
106
  score_block = json.loads(json_match.group(0))
@@ -109,43 +14,65 @@ def parse_scores_from_feedback(feedback_text):
109
  print("Score parsing failed:", e)
110
  return {}
111
 
112
-
113
  def generate_progress_summary(current_feedback, previous_feedback):
114
  current_scores = parse_scores_from_feedback(current_feedback)
115
  previous_scores = parse_scores_from_feedback(previous_feedback)
116
-
117
  if not current_scores or not previous_scores:
118
- return "" # can't compare
119
 
120
- summary_lines = []
121
- for category in current_scores:
122
- if category in previous_scores:
123
- diff = current_scores[category] - previous_scores[category]
124
  if diff > 0:
125
- summary_lines.append(f"βœ… **{category}** improved by **+{diff}**")
126
  elif diff < 0:
127
- summary_lines.append(f"⚠️ **{category}** decreased by **{diff}**")
128
  else:
129
- summary_lines.append(f"βž– **{category}** stayed the same")
130
 
131
- if summary_lines:
132
- return "\n\n**πŸ“ˆ Progress Tracker**\n" + "\n".join(summary_lines)
133
  return ""
134
 
135
-
136
- # === GPT: Improved Response ===
137
- def generate_example_response(transcript, language):
138
- prompt = f"""Rewrite this speech to make it more polished, fluent, and confident.
139
- Keep the meaning and tone the same, but improve clarity and structure.
140
-
141
- Transcript:
142
- {transcript}
143
- """
144
- response = client.chat.completions.create(
145
- model="gpt-4",
146
- messages=[
147
- {"role": "system", "content": f"Reply in {language}. Provide only the improved version of the speech."},
148
- {"role": "user", "content": prompt}
149
- ]
150
- )
151
- return response.choices[0].message.content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import re
2
  import json
3
+ import matplotlib.pyplot as plt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ # (Existing imports and functions are assumed to already be here...)
6
 
7
  def parse_scores_from_feedback(feedback_text):
8
  try:
 
9
  json_match = re.search(r"\{.*?\}", feedback_text, re.DOTALL)
10
  if json_match:
11
  score_block = json.loads(json_match.group(0))
 
14
  print("Score parsing failed:", e)
15
  return {}
16
 
 
17
  def generate_progress_summary(current_feedback, previous_feedback):
18
  current_scores = parse_scores_from_feedback(current_feedback)
19
  previous_scores = parse_scores_from_feedback(previous_feedback)
 
20
  if not current_scores or not previous_scores:
21
+ return ""
22
 
23
+ lines = []
24
+ for cat in current_scores:
25
+ if cat in previous_scores:
26
+ diff = current_scores[cat] - previous_scores[cat]
27
  if diff > 0:
28
+ lines.append(f"βœ… **{cat}** improved by **+{diff}**")
29
  elif diff < 0:
30
+ lines.append(f"⚠️ **{cat}** dropped by **{diff}**")
31
  else:
32
+ lines.append(f"βž– **{cat}** stayed the same")
33
 
34
+ if lines:
35
+ return "\n\n**πŸ“ˆ Progress Tracker**\n" + "\n".join(lines)
36
  return ""
37
 
38
+ def build_score_comparison_data(current_feedback, previous_feedback):
39
+ current = parse_scores_from_feedback(current_feedback)
40
+ previous = parse_scores_from_feedback(previous_feedback)
41
+ categories = list(set(current.keys()).union(set(previous.keys())))
42
+ return {
43
+ "Category": categories,
44
+ "Current Score": [current.get(cat, 0) for cat in categories],
45
+ "Previous Score": [previous.get(cat, 0) for cat in categories]
46
+ }
47
+
48
+ def render_score_chart(data):
49
+ fig, ax = plt.subplots()
50
+ x = range(len(data["Category"]))
51
+ ax.bar([i - 0.2 for i in x], data["Previous Score"], width=0.4, label='Previous')
52
+ ax.bar([i + 0.2 for i in x], data["Current Score"], width=0.4, label='Current')
53
+ ax.set_xticks(list(x))
54
+ ax.set_xticklabels(data["Category"])
55
+ ax.set_ylim(0, 10)
56
+ ax.legend()
57
+ ax.set_ylabel("Score")
58
+ ax.set_title("🎯 Score Comparison")
59
+ return fig
60
+
61
+ def build_trend_data(sessions, category="Tone"):
62
+ points = []
63
+ timestamps = []
64
+ for s in sessions:
65
+ score = parse_scores_from_feedback(s.feedback).get(category)
66
+ if score is not None:
67
+ points.append(score)
68
+ timestamps.append(s.timestamp.split()[0])
69
+ return timestamps, points
70
+
71
+ def render_trend_chart(timestamps, points, category="Tone"):
72
+ fig, ax = plt.subplots()
73
+ ax.plot(timestamps, points, marker="o", linestyle="-", color="blue")
74
+ ax.set_title(f"πŸ“ˆ {category} Progress Over Time")
75
+ ax.set_ylim(0, 10)
76
+ ax.set_ylabel("Score")
77
+ ax.set_xlabel("Date")
78
+ return fig