Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -8,6 +8,7 @@ Unified Online/Offline AI Quiz Game with Friends, Chat, Presence, Invites.
|
|
| 8 |
- FIREBASE_DB_URL is set to your Firebase project's Realtime DB (from your screenshot)
|
| 9 |
"""
|
| 10 |
import requests
|
|
|
|
| 11 |
import os
|
| 12 |
import uuid
|
| 13 |
import time
|
|
@@ -1097,7 +1098,17 @@ def play_page():
|
|
| 1097 |
"correct_flags": json.dumps(flags),
|
| 1098 |
}
|
| 1099 |
unified_push_leaderboard(row)
|
| 1100 |
-
save_score_to_csv(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1101 |
|
| 1102 |
# ---------------- AUTO CLOSE GAME ----------------
|
| 1103 |
if game.get("auto_close", True):
|
|
@@ -1254,77 +1265,43 @@ def inbox_page():
|
|
| 1254 |
else:
|
| 1255 |
st.error(msg)
|
| 1256 |
|
| 1257 |
-
# Leaderboard page
|
| 1258 |
-
# ----------------- Leaderboard Page -----------------
|
| 1259 |
def leaderboard_page():
|
| 1260 |
-
import os, csv
|
| 1261 |
-
import streamlit as st
|
| 1262 |
-
from datetime import datetime
|
| 1263 |
-
|
| 1264 |
st.header("๐ Leaderboard")
|
| 1265 |
|
| 1266 |
-
|
| 1267 |
-
if not
|
| 1268 |
st.info("No scores yet.")
|
| 1269 |
return
|
| 1270 |
|
| 1271 |
-
|
| 1272 |
-
with open(LEADERBOARD_FILE, "rb") as f:
|
| 1273 |
-
st.download_button(
|
| 1274 |
-
"โฌ Download Leaderboard CSV",
|
| 1275 |
-
f,
|
| 1276 |
-
file_name="leaderboard.csv",
|
| 1277 |
-
mime="text/csv"
|
| 1278 |
-
)
|
| 1279 |
-
|
| 1280 |
-
# ---------------- Read CSV ----------------
|
| 1281 |
-
leaderboard = []
|
| 1282 |
-
with open(LEADERBOARD_FILE, "r", encoding="utf-8") as f:
|
| 1283 |
-
reader = csv.DictReader(f)
|
| 1284 |
-
leaderboard = list(reader)
|
| 1285 |
-
|
| 1286 |
-
if not leaderboard:
|
| 1287 |
-
st.info("No scores yet.")
|
| 1288 |
-
return
|
| 1289 |
|
| 1290 |
-
#
|
| 1291 |
-
|
| 1292 |
-
|
| 1293 |
|
| 1294 |
-
|
| 1295 |
-
leaderboard = sorted(leaderboard, key=lambda x: x["score"], reverse=True)
|
| 1296 |
|
| 1297 |
-
|
| 1298 |
-
|
| 1299 |
-
for i, row in enumerate(leaderboard[:10], 1):
|
| 1300 |
st.write(
|
| 1301 |
-
f"{i}. {
|
| 1302 |
-
f"(Game {
|
| 1303 |
)
|
| 1304 |
|
| 1305 |
-
#
|
| 1306 |
-
st.subheader("Weekly Leaderboard
|
| 1307 |
-
|
| 1308 |
-
|
| 1309 |
-
weekly = []
|
| 1310 |
-
for r in leaderboard:
|
| 1311 |
-
try:
|
| 1312 |
-
ts = datetime.fromisoformat(r.get("timestamp", ""))
|
| 1313 |
-
if ts.isocalendar()[1] == current_week:
|
| 1314 |
-
weekly.append(r)
|
| 1315 |
-
except Exception:
|
| 1316 |
-
pass
|
| 1317 |
|
| 1318 |
-
if
|
| 1319 |
-
st.info("No scores
|
| 1320 |
else:
|
| 1321 |
-
for i, r in enumerate(weekly
|
| 1322 |
st.write(
|
| 1323 |
-
f"{i}. {r.get('avatar','๐ฎ')} **{r
|
| 1324 |
-
f"(Game {r
|
| 1325 |
)
|
| 1326 |
|
| 1327 |
-
|
| 1328 |
def get_weekly_leaderboard(limit=10):
|
| 1329 |
rows = unified_get("/leaderboard") or []
|
| 1330 |
one_week_ago = datetime.utcnow() - timedelta(days=7)
|
|
|
|
| 8 |
- FIREBASE_DB_URL is set to your Firebase project's Realtime DB (from your screenshot)
|
| 9 |
"""
|
| 10 |
import requests
|
| 11 |
+
import csv
|
| 12 |
import os
|
| 13 |
import uuid
|
| 14 |
import time
|
|
|
|
| 1098 |
"correct_flags": json.dumps(flags),
|
| 1099 |
}
|
| 1100 |
unified_push_leaderboard(row)
|
| 1101 |
+
save_score_to_csv(
|
| 1102 |
+
name=row["name"],
|
| 1103 |
+
score=row["score"],
|
| 1104 |
+
game_id=row["game_id"],
|
| 1105 |
+
topics=row["topics"],
|
| 1106 |
+
avatar=row["avatar"],
|
| 1107 |
+
questions=row["questions"],
|
| 1108 |
+
answers=row["answers"],
|
| 1109 |
+
correct_flags=row["correct_flags"]
|
| 1110 |
+
)
|
| 1111 |
+
|
| 1112 |
|
| 1113 |
# ---------------- AUTO CLOSE GAME ----------------
|
| 1114 |
if game.get("auto_close", True):
|
|
|
|
| 1265 |
else:
|
| 1266 |
st.error(msg)
|
| 1267 |
|
|
|
|
|
|
|
| 1268 |
def leaderboard_page():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1269 |
st.header("๐ Leaderboard")
|
| 1270 |
|
| 1271 |
+
rows = unified_get("leaderboard") or []
|
| 1272 |
+
if not rows:
|
| 1273 |
st.info("No scores yet.")
|
| 1274 |
return
|
| 1275 |
|
| 1276 |
+
df = pd.DataFrame(rows)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1277 |
|
| 1278 |
+
# Safe types
|
| 1279 |
+
df["score"] = pd.to_numeric(df["score"], errors="coerce").fillna(0).astype(int)
|
| 1280 |
+
df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
|
| 1281 |
|
| 1282 |
+
df = df.sort_values(by="score", ascending=False)
|
|
|
|
| 1283 |
|
| 1284 |
+
st.subheader("Top Players (All Time)")
|
| 1285 |
+
for i, r in enumerate(df.head(10).to_dict("records"), 1):
|
|
|
|
| 1286 |
st.write(
|
| 1287 |
+
f"{i}. {r.get('avatar','๐ฎ')} **{r['name']}** "
|
| 1288 |
+
f"(Game {r['game_id']}) โ {r['score']} pts"
|
| 1289 |
)
|
| 1290 |
|
| 1291 |
+
# Weekly leaderboard
|
| 1292 |
+
st.subheader("Weekly Leaderboard")
|
| 1293 |
+
one_week_ago = datetime.utcnow() - timedelta(days=7)
|
| 1294 |
+
weekly = df[df["timestamp"] >= one_week_ago]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1295 |
|
| 1296 |
+
if weekly.empty:
|
| 1297 |
+
st.info("No scores this week.")
|
| 1298 |
else:
|
| 1299 |
+
for i, r in enumerate(weekly.head(10).to_dict("records"), 1):
|
| 1300 |
st.write(
|
| 1301 |
+
f"{i}. {r.get('avatar','๐ฎ')} **{r['name']}** "
|
| 1302 |
+
f"(Game {r['game_id']}) โ {r['score']} pts"
|
| 1303 |
)
|
| 1304 |
|
|
|
|
| 1305 |
def get_weekly_leaderboard(limit=10):
|
| 1306 |
rows = unified_get("/leaderboard") or []
|
| 1307 |
one_week_ago = datetime.utcnow() - timedelta(days=7)
|