Add challenges preview + makefile
This commit is contained in:
@@ -10,6 +10,9 @@ from app.schemas import (
|
||||
ChallengeResponse,
|
||||
MessageResponse,
|
||||
GameShort,
|
||||
ChallengePreview,
|
||||
ChallengesPreviewResponse,
|
||||
ChallengesSaveRequest,
|
||||
)
|
||||
from app.services.gpt import GPTService
|
||||
|
||||
@@ -136,9 +139,9 @@ async def create_challenge(
|
||||
)
|
||||
|
||||
|
||||
@router.post("/marathons/{marathon_id}/generate-challenges", response_model=MessageResponse)
|
||||
async def generate_challenges(marathon_id: int, current_user: CurrentUser, db: DbSession):
|
||||
"""Generate challenges for all games in marathon using GPT"""
|
||||
@router.post("/marathons/{marathon_id}/preview-challenges", response_model=ChallengesPreviewResponse)
|
||||
async def preview_challenges(marathon_id: int, current_user: CurrentUser, db: DbSession):
|
||||
"""Generate challenges preview for all games in marathon using GPT (without saving)"""
|
||||
# Check marathon
|
||||
result = await db.execute(select(Marathon).where(Marathon.id == marathon_id))
|
||||
marathon = result.scalar_one_or_none()
|
||||
@@ -159,7 +162,7 @@ async def generate_challenges(marathon_id: int, current_user: CurrentUser, db: D
|
||||
if not games:
|
||||
raise HTTPException(status_code=400, detail="No games in marathon")
|
||||
|
||||
generated_count = 0
|
||||
preview_challenges = []
|
||||
for game in games:
|
||||
# Check if game already has challenges
|
||||
existing = await db.scalar(
|
||||
@@ -172,8 +175,9 @@ async def generate_challenges(marathon_id: int, current_user: CurrentUser, db: D
|
||||
challenges_data = await gpt_service.generate_challenges(game.title, game.genre)
|
||||
|
||||
for ch_data in challenges_data:
|
||||
challenge = Challenge(
|
||||
preview_challenges.append(ChallengePreview(
|
||||
game_id=game.id,
|
||||
game_title=game.title,
|
||||
title=ch_data.title,
|
||||
description=ch_data.description,
|
||||
type=ch_data.type,
|
||||
@@ -182,18 +186,78 @@ async def generate_challenges(marathon_id: int, current_user: CurrentUser, db: D
|
||||
estimated_time=ch_data.estimated_time,
|
||||
proof_type=ch_data.proof_type,
|
||||
proof_hint=ch_data.proof_hint,
|
||||
is_generated=True,
|
||||
)
|
||||
db.add(challenge)
|
||||
generated_count += 1
|
||||
))
|
||||
|
||||
except Exception as e:
|
||||
# Log error but continue with other games
|
||||
print(f"Error generating challenges for {game.title}: {e}")
|
||||
|
||||
return ChallengesPreviewResponse(challenges=preview_challenges)
|
||||
|
||||
|
||||
@router.post("/marathons/{marathon_id}/save-challenges", response_model=MessageResponse)
|
||||
async def save_challenges(
|
||||
marathon_id: int,
|
||||
data: ChallengesSaveRequest,
|
||||
current_user: CurrentUser,
|
||||
db: DbSession,
|
||||
):
|
||||
"""Save previewed challenges to database"""
|
||||
# Check marathon
|
||||
result = await db.execute(select(Marathon).where(Marathon.id == marathon_id))
|
||||
marathon = result.scalar_one_or_none()
|
||||
if not marathon:
|
||||
raise HTTPException(status_code=404, detail="Marathon not found")
|
||||
|
||||
if marathon.status != MarathonStatus.PREPARING.value:
|
||||
raise HTTPException(status_code=400, detail="Cannot add challenges to active or finished marathon")
|
||||
|
||||
await check_participant(db, current_user.id, marathon_id)
|
||||
|
||||
# Verify all games belong to this marathon
|
||||
result = await db.execute(
|
||||
select(Game.id).where(Game.marathon_id == marathon_id)
|
||||
)
|
||||
valid_game_ids = set(row[0] for row in result.fetchall())
|
||||
|
||||
saved_count = 0
|
||||
for ch_data in data.challenges:
|
||||
if ch_data.game_id not in valid_game_ids:
|
||||
continue # Skip challenges for invalid games
|
||||
|
||||
# Validate type
|
||||
ch_type = ch_data.type
|
||||
if ch_type not in ["completion", "no_death", "speedrun", "collection", "achievement", "challenge_run"]:
|
||||
ch_type = "completion"
|
||||
|
||||
# Validate difficulty
|
||||
difficulty = ch_data.difficulty
|
||||
if difficulty not in ["easy", "medium", "hard"]:
|
||||
difficulty = "medium"
|
||||
|
||||
# Validate proof_type
|
||||
proof_type = ch_data.proof_type
|
||||
if proof_type not in ["screenshot", "video", "steam"]:
|
||||
proof_type = "screenshot"
|
||||
|
||||
challenge = Challenge(
|
||||
game_id=ch_data.game_id,
|
||||
title=ch_data.title[:100],
|
||||
description=ch_data.description,
|
||||
type=ch_type,
|
||||
difficulty=difficulty,
|
||||
points=max(1, min(500, ch_data.points)),
|
||||
estimated_time=ch_data.estimated_time,
|
||||
proof_type=proof_type,
|
||||
proof_hint=ch_data.proof_hint,
|
||||
is_generated=True,
|
||||
)
|
||||
db.add(challenge)
|
||||
saved_count += 1
|
||||
|
||||
await db.commit()
|
||||
|
||||
return MessageResponse(message=f"Generated {generated_count} challenges")
|
||||
return MessageResponse(message=f"Сохранено {saved_count} заданий")
|
||||
|
||||
|
||||
@router.patch("/challenges/{challenge_id}", response_model=ChallengeResponse)
|
||||
|
||||
Reference in New Issue
Block a user