Spaces:
Sleeping
Sleeping
Upload 7 files
Browse files- utils/auth.py +37 -0
- utils/feedback.py +17 -0
- utils/leaderboard.py +11 -0
- utils/llm_score.py +17 -0
- utils/localization.py +10 -0
- utils/storage.py +43 -0
- utils/voice_to_text.py +16 -0
utils/auth.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import bcrypt
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
USERS_CSV = "users.csv"
|
| 6 |
+
|
| 7 |
+
def initialize_user_csv():
|
| 8 |
+
if not os.path.exists(USERS_CSV):
|
| 9 |
+
df = pd.DataFrame(columns=['username', 'password_hash', 'avatar_url'])
|
| 10 |
+
df.to_csv(USERS_CSV, index=False)
|
| 11 |
+
|
| 12 |
+
def register_user(username, password, avatar_url=None):
|
| 13 |
+
initialize_user_csv()
|
| 14 |
+
df = pd.read_csv(USERS_CSV)
|
| 15 |
+
if username in df['username'].values:
|
| 16 |
+
return False, "Username already exists"
|
| 17 |
+
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
|
| 18 |
+
new_user = pd.DataFrame([[username, hashed.decode(), avatar_url or "https://api.dicebear.com/7.x/identicon/svg?seed="+username]], columns=df.columns)
|
| 19 |
+
df = pd.concat([df, new_user], ignore_index=True)
|
| 20 |
+
df.to_csv(USERS_CSV, index=False)
|
| 21 |
+
return True, "Registration successful!"
|
| 22 |
+
|
| 23 |
+
def authenticate_user(username, password):
|
| 24 |
+
initialize_user_csv()
|
| 25 |
+
df = pd.read_csv(USERS_CSV)
|
| 26 |
+
row = df[df['username'] == username]
|
| 27 |
+
if row.empty:
|
| 28 |
+
return False
|
| 29 |
+
stored = row['password_hash'].iloc[0].encode()
|
| 30 |
+
return bcrypt.checkpw(password.encode(), stored)
|
| 31 |
+
|
| 32 |
+
def get_avatar(username):
|
| 33 |
+
df = pd.read_csv(USERS_CSV)
|
| 34 |
+
row = df[df['username'] == username]
|
| 35 |
+
if not row.empty:
|
| 36 |
+
return row['avatar_url'].iloc[0]
|
| 37 |
+
return "https://api.dicebear.com/7.x/identicon/svg?seed="+username
|
utils/feedback.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import csv
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
|
| 5 |
+
FEEDBACK = "feedback.csv"
|
| 6 |
+
|
| 7 |
+
def initialize_feedback():
|
| 8 |
+
if not os.path.exists(FEEDBACK):
|
| 9 |
+
with open(FEEDBACK, "w", newline='', encoding="utf-8") as f:
|
| 10 |
+
writer = csv.writer(f)
|
| 11 |
+
writer.writerow(["username", "feedback", "timestamp"])
|
| 12 |
+
|
| 13 |
+
def save_feedback(username, feedback):
|
| 14 |
+
initialize_feedback()
|
| 15 |
+
with open(FEEDBACK, "a", newline='', encoding="utf-8") as f:
|
| 16 |
+
writer = csv.writer(f)
|
| 17 |
+
writer.writerow([username, feedback, datetime.now().isoformat()])
|
utils/leaderboard.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
LEADERBOARD = "leaderboard.csv"
|
| 5 |
+
|
| 6 |
+
def get_leaderboard():
|
| 7 |
+
if not os.path.exists(LEADERBOARD):
|
| 8 |
+
return pd.DataFrame(columns=["username", "participation_count"])
|
| 9 |
+
df = pd.read_csv(LEADERBOARD)
|
| 10 |
+
df = df.sort_values(by="participation_count", ascending=False)
|
| 11 |
+
return df
|
utils/llm_score.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
|
| 3 |
+
def llama_score_sentence(user_sentence, correct_answer, api_url="http://localhost:8000/completion"):
|
| 4 |
+
prompt = (
|
| 5 |
+
f"Task: Score the learner's answer for a fill-in-the-blank question.\n"
|
| 6 |
+
f"Question: What is the correct answer? {correct_answer}\n"
|
| 7 |
+
f"User's answer: {user_sentence}\n"
|
| 8 |
+
f"Is the answer correct? (yes/no). If not, briefly explain why."
|
| 9 |
+
)
|
| 10 |
+
resp = requests.post(
|
| 11 |
+
api_url,
|
| 12 |
+
json={"prompt": prompt, "n_predict": 32, "temperature": 0.2, "stream": False}
|
| 13 |
+
)
|
| 14 |
+
try:
|
| 15 |
+
return resp.json().get('content', resp.text)
|
| 16 |
+
except Exception:
|
| 17 |
+
return resp.text
|
utils/localization.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
ASSETS_DIR = os.path.join(os.path.dirname(__file__), '..', 'assets')
|
| 5 |
+
PROMPTS_FILE = os.path.join(ASSETS_DIR, 'prompts.json')
|
| 6 |
+
|
| 7 |
+
def get_prompts(language):
|
| 8 |
+
with open(PROMPTS_FILE, "r", encoding="utf-8") as f:
|
| 9 |
+
all_prompts = json.load(f)
|
| 10 |
+
return all_prompts.get(language, all_prompts['en'])
|
utils/storage.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import os
|
| 3 |
+
import csv
|
| 4 |
+
from datetime import datetime
|
| 5 |
+
|
| 6 |
+
RESPONSES = "responses.csv"
|
| 7 |
+
LEADERBOARD = "leaderboard.csv"
|
| 8 |
+
|
| 9 |
+
def initialize_csvs():
|
| 10 |
+
if not os.path.exists(RESPONSES):
|
| 11 |
+
with open(RESPONSES, "w", newline='', encoding="utf-8") as f:
|
| 12 |
+
writer = csv.writer(f)
|
| 13 |
+
writer.writerow([
|
| 14 |
+
"username", "language", "game_type", "prompt", "response", "correct",
|
| 15 |
+
"transcript", "audio_file", "latitude", "longitude", "timestamp"
|
| 16 |
+
])
|
| 17 |
+
if not os.path.exists(LEADERBOARD):
|
| 18 |
+
with open(LEADERBOARD, "w", newline='', encoding="utf-8") as f:
|
| 19 |
+
writer = csv.writer(f)
|
| 20 |
+
writer.writerow(["username", "participation_count"])
|
| 21 |
+
|
| 22 |
+
def save_response(username, language, game_type, prompt, response, correct, transcript, audio_file, lat, lon):
|
| 23 |
+
initialize_csvs()
|
| 24 |
+
with open(RESPONSES, "a", newline='', encoding="utf-8") as f:
|
| 25 |
+
writer = csv.writer(f)
|
| 26 |
+
writer.writerow([
|
| 27 |
+
username, language, game_type, prompt, response, correct,
|
| 28 |
+
transcript, audio_file, lat, lon, datetime.now().isoformat()
|
| 29 |
+
])
|
| 30 |
+
|
| 31 |
+
def update_leaderboard(username):
|
| 32 |
+
initialize_csvs()
|
| 33 |
+
df = pd.read_csv(LEADERBOARD)
|
| 34 |
+
if username in df['username'].values:
|
| 35 |
+
df.loc[df['username'] == username, 'participation_count'] += 1
|
| 36 |
+
else:
|
| 37 |
+
df.loc[len(df)] = [username, 1]
|
| 38 |
+
df.to_csv(LEADERBOARD, index=False)
|
| 39 |
+
|
| 40 |
+
def get_user_data(username):
|
| 41 |
+
initialize_csvs()
|
| 42 |
+
df = pd.read_csv(RESPONSES)
|
| 43 |
+
return df[df['username'] == username]
|
utils/voice_to_text.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import speech_recognition as sr
|
| 2 |
+
from pydub import AudioSegment
|
| 3 |
+
import io
|
| 4 |
+
|
| 5 |
+
def transcribe_audio(audio_bytes, out_wav_path):
|
| 6 |
+
# audio_bytes is bytes
|
| 7 |
+
audio = AudioSegment.from_file(io.BytesIO(audio_bytes))
|
| 8 |
+
audio.export(out_wav_path, format="wav")
|
| 9 |
+
r = sr.Recognizer()
|
| 10 |
+
with sr.AudioFile(out_wav_path) as source:
|
| 11 |
+
audio_data = r.record(source)
|
| 12 |
+
try:
|
| 13 |
+
text = r.recognize_google(audio_data, language="en-IN")
|
| 14 |
+
return text
|
| 15 |
+
except Exception:
|
| 16 |
+
return ""
|