api / routers /gamification.py
jamelloverz-sketch
PopCorn API v3.5 - Media metadata, people, images, open CORS
c18e004
Raw
History Blame Contribute Delete
4.17 kB
"""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
@router.get("/xp")
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
}
}
@router.get("/quests/daily")
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}
@router.get("/quests/weekly")
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}
@router.post("/quests/{quest_id}/progress")
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}}
@router.get("/season-pass")
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}