Spaces:
Sleeping
Sleeping
File size: 4,465 Bytes
99b596a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | import hashlib
import secrets
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from app.db.models import User, QuizResult, StudySession
# ── Password
def hash_password(password: str) -> str:
salt = secrets.token_hex(16)
hashed = hashlib.sha256((password + salt).encode()).hexdigest()
return f"{salt}:{hashed}"
def verify_password(plain: str, hashed: str) -> bool:
try:
salt, hash_val = hashed.split(":")
return hashlib.sha256((plain + salt).encode()).hexdigest() == hash_val
except:
return False
# ── User CRUD
def get_user_by_email(db: Session, email: str):
return db.query(User).filter(User.email == email).first()
def get_user_by_username(db: Session, username: str):
return db.query(User).filter(User.username == username).first()
def get_user_by_id(db: Session, user_id: int):
return db.query(User).filter(User.id == user_id).first()
def create_user(db: Session, username: str, email: str, password: str):
user = User(
username=username,
email=email,
password=hash_password(password),
created_at=datetime.utcnow()
)
db.add(user)
db.commit()
db.refresh(user)
return user
def update_streak(db: Session, user: User):
now = datetime.utcnow()
if user.last_login:
diff = (now.date() - user.last_login.date()).days
if diff == 1:
user.streak_days += 1
elif diff > 1:
user.streak_days = 1
else:
user.streak_days = 1
user.last_login = now
db.commit()
# ── Quiz Results
def save_quiz_result(db: Session, user_id: int, req):
result = QuizResult(
user_id=user_id,
topic=req.topic,
score=req.score,
total_questions=req.total_questions,
correct_answers=req.correct_answers,
difficulty=req.difficulty,
duration_sec=req.duration_sec
)
db.add(result)
# Mise à jour du niveau utilisateur
user = get_user_by_id(db, user_id)
if user:
results = db.query(QuizResult).filter(QuizResult.user_id == user_id).all()
if len(results) > 0:
avg = sum(r.score for r in results) / len(results)
if avg >= 80:
user.niveau = "expert"
elif avg >= 60:
user.niveau = "intermédiaire"
else:
user.niveau = "débutant"
db.commit()
db.refresh(result)
return result
# ── Profile
def get_student_profile(db: Session, user_id: int) -> dict:
user = get_user_by_id(db, user_id)
if not user:
return {}
quiz_results = db.query(QuizResult).filter(
QuizResult.user_id == user_id
).order_by(QuizResult.created_at.desc()).all()
sessions = db.query(StudySession).filter(
StudySession.user_id == user_id
).all()
scores = [r.score for r in quiz_results]
avg_score = round(sum(scores) / len(scores), 1) if scores else 0
best_score = max(scores) if scores else 0
# Top matières
subjects = {}
for s in sessions:
subjects[s.subject] = subjects.get(s.subject, 0) + 1
top_subjects = sorted(
[{"subject": k, "count": v} for k, v in subjects.items()],
key=lambda x: x["count"], reverse=True
)[:5]
recent_quiz = [
{
"topic": r.topic,
"score": r.score,
"date": r.created_at.strftime("%d/%m/%Y"),
"difficulty": r.difficulty
}
for r in quiz_results[:10]
]
return {
"user": {
"username": user.username,
"email": user.email,
"niveau": user.niveau,
"streak_days": user.streak_days,
"member_since": user.created_at.strftime("%d/%m/%Y") if user.created_at else "N/A"
},
"stats": {
"total_sessions": len(sessions),
"total_quiz": len(quiz_results),
"average_score": avg_score,
"best_score": best_score,
"top_subjects": top_subjects
},
"recent_quiz": recent_quiz
}
def get_progress(db: Session, user_id: int) -> dict:
results = db.query(QuizResult).filter(
QuizResult.user_id == user_id
).order_by(QuizResult.created_at.asc()).all()
return {
"progression": [
{"date": r.created_at.strftime("%d/%m"), "score": r.score, "topic": r.topic}
for r in results
]
} |