Spaces:
Runtime error
Runtime error
| """Gamification API - ุงูุชุญุฏูุงุช ูุงูุฅูุฌุงุฒุงุช ููุธุงู ุงูู ุณุชููุงุช""" | |
| from fastapi import APIRouter, HTTPException, Request, Query | |
| from database import fetch_one, fetch_all, execute | |
| from auth import get_current_user | |
| from routers.utils import progress_achievement | |
| router = APIRouter() | |
| LEVELS = [ | |
| (1, "New Popper ๐ฟ", 0), (2, "Movie Fan ๐ฌ", 100), (3, "Film Buff โญ", 300), | |
| (4, "Cinema Lover ๐ฅ", 600), (5, "Movie Star ๐", 1000), (6, "Film Critic ๐", 1500), | |
| (7, "Cinema King ๐", 2500), (8, "Movie Legend ๐ช", 4000), (9, "Hall of Fame โญ", 6000), | |
| (10, "Living Cinema ๐ฌ", 10000), | |
| ] | |
| async def _resolve_user(request: Request) -> dict: | |
| user_data = await get_current_user(request) | |
| user = await fetch_one("SELECT * FROM users WHERE user_id = ?", [str(user_data["id"])]) | |
| if not user: | |
| raise HTTPException(status_code=404, detail="User not found") | |
| return user | |
| async def get_user_xp(request: Request): | |
| """Get user level, XP, and progress to next level""" | |
| user = await _resolve_user(request) | |
| xp = user.get("xp", 0) or 0 | |
| current_level = 1 | |
| for level_num, title, xp_req in LEVELS: | |
| if xp >= xp_req: | |
| current_level = level_num | |
| next_xp = LEVELS[min(current_level, len(LEVELS)-1)][2] if current_level < len(LEVELS) else LEVELS[-1][2] | |
| progress = min(100, int((xp / next_xp) * 100)) if next_xp else 100 | |
| return { | |
| "ok": True, "data": { | |
| "xp": xp, "level": current_level, | |
| "title": LEVELS[current_level-1][1] if current_level <= len(LEVELS) else "Legend", | |
| "xp_to_next": next_xp - xp, "progress": progress | |
| } | |
| } | |
| async def get_daily_quests(request: Request): | |
| """Get today's daily quests""" | |
| user = await _resolve_user(request) | |
| today = "datetime('now', 'start of day')" | |
| quests = await fetch_all(f""" | |
| SELECT dq.*, COALESCE(uq.progress, 0) as user_progress, | |
| CASE WHEN uq.completed=1 THEN 1 ELSE 0 END as completed | |
| FROM daily_quests dq | |
| LEFT JOIN user_quests uq ON dq.id=uq.quest_id AND uq.user_id=? AND uq.date={today} | |
| WHERE dq.is_active=1 ORDER BY dq.sort_order""", [str(user["id"])]) | |
| return {"ok": True, "data": quests} | |
| async def get_weekly_challenges(request: Request): | |
| """Get weekly challenges""" | |
| user = await _resolve_user(request) | |
| challenges = await fetch_all(""" | |
| SELECT wc.*, COALESCE(uw.progress, 0) as user_progress, | |
| CASE WHEN uw.completed=1 THEN 1 ELSE 0 END as completed | |
| FROM weekly_challenges wc | |
| LEFT JOIN user_weekly uw ON wc.id=uw.challenge_id AND uw.user_id=? | |
| WHERE wc.is_active=1""", [str(user["id"])]) | |
| return {"ok": True, "data": challenges} | |
| async def update_quest_progress(quest_id: int, request: Request): | |
| """Update progress for a quest/challenge""" | |
| user = await _resolve_user(request) | |
| await execute(""" | |
| INSERT INTO user_quests (user_id, quest_id, progress, date) | |
| VALUES (?, ?, 1, datetime('now', 'start of day')) | |
| ON CONFLICT(user_id, quest_id, date) DO UPDATE SET progress=progress+1""", | |
| [str(user["id"]), str(quest_id)]) | |
| return {"ok": True, "data": {"progressed": True}} | |
| async def get_season_pass(request: Request): | |
| """Get season pass levels and rewards""" | |
| user = await _resolve_user(request) | |
| levels = await fetch_all("SELECT * FROM season_pass_levels ORDER BY level_num") | |
| user_levels = await fetch_all("SELECT * FROM user_season_pass WHERE user_id=?", [str(user["id"])]) | |
| claimed = {ul["level_num"]: ul["claimed"] for ul in user_levels} | |
| result = [] | |
| for lv in levels: | |
| result.append({ | |
| "level": lv["level_num"], "xp_required": lv["xp_required"], | |
| "free_reward": lv["free_reward"], "premium_reward": lv["premium_reward"], | |
| "claimed": claimed.get(lv["level_num"], False), | |
| "unlocked": (user.get("xp", 0) or 0) >= lv["xp_required"], | |
| }) | |
| return {"ok": True, "data": result} | |