72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
import json
|
|
from datetime import date, timedelta
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import PositiveInt
|
|
from starlette import status
|
|
|
|
from zangramru.db.models.puzzle import Puzzle
|
|
from zangramru.services.puzzles import PuzzleGeneratorDep
|
|
from zangramru.settings import settings
|
|
|
|
from .schema import DailyPuzzleDTO, PuzzleOutputDTO
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/random")
|
|
def random_puzzle(generator: PuzzleGeneratorDep) -> PuzzleOutputDTO:
|
|
"""Generate a random puzzle."""
|
|
puzzle = generator.generate(target=10)
|
|
return PuzzleOutputDTO.model_validate(puzzle, from_attributes=True)
|
|
|
|
|
|
@router.get("/daily")
|
|
async def daily_puzzle(
|
|
generator: PuzzleGeneratorDep,
|
|
number: PositiveInt | None = None,
|
|
) -> DailyPuzzleDTO:
|
|
"""Generate a random puzzle."""
|
|
# Because they start at one, so we need to subtract one.
|
|
target_date = date.today()
|
|
if number is not None:
|
|
target_date = settings.start_date + timedelta(days=number - 1)
|
|
|
|
if target_date > date.today():
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Doesn't exist",
|
|
)
|
|
|
|
number = (target_date - settings.start_date).days
|
|
|
|
daily_puzzle = await Puzzle.objects().where(Puzzle.number == number).first()
|
|
|
|
if daily_puzzle is not None:
|
|
board = [list(daily_puzzle.board[i * 4 : i * 4 + 4]) for i in range(4)]
|
|
return DailyPuzzleDTO(
|
|
number=(date.today() - settings.start_date).days,
|
|
board=board,
|
|
solutions=json.loads(daily_puzzle.solutions),
|
|
extra=json.loads(daily_puzzle.extra),
|
|
word_defs=json.loads(daily_puzzle.definitions),
|
|
)
|
|
puzzle = generator.generate(target=10)
|
|
compressedboard = "".join("".join(row) for row in puzzle.board)
|
|
await Puzzle(
|
|
{
|
|
Puzzle.board: compressedboard,
|
|
Puzzle.number: number,
|
|
Puzzle.solutions: json.dumps(puzzle.solutions),
|
|
Puzzle.definitions: json.dumps(puzzle.word_defs),
|
|
Puzzle.extra: json.dumps(puzzle.extra),
|
|
}
|
|
).save()
|
|
return DailyPuzzleDTO(
|
|
number=number,
|
|
board=puzzle.board,
|
|
solutions=puzzle.solutions,
|
|
extra=puzzle.extra,
|
|
word_defs=puzzle.word_defs,
|
|
)
|