feat: evolution per player (optional)
This commit is contained in:
@@ -36,9 +36,15 @@ def canvas(request: HttpRequest, event_path: str):
|
||||
|
||||
@router.get(f"{PREFIX}/evolution.gif", auth=django_auth_is_staff)
|
||||
@decorate_view(require_game_enabled(path="place"))
|
||||
def evolution_gif(request: HttpRequest, event_path: str):
|
||||
"""Admin-only: replays the full placement history as an animated GIF."""
|
||||
return HttpResponse(build_evolution_gif(request.event), content_type="image/gif")
|
||||
def evolution_gif(request: HttpRequest, event_path: str, players: str = ""):
|
||||
"""Admin-only: replays the full placement history as an animated GIF.
|
||||
|
||||
`players` is an optional comma-separated list of usernames to only
|
||||
replay those players' placements (combined)."""
|
||||
usernames = [name.strip() for name in players.split(",") if name.strip()]
|
||||
return HttpResponse(
|
||||
build_evolution_gif(request.event, usernames), content_type="image/gif"
|
||||
)
|
||||
|
||||
|
||||
@router.get(f"{PREFIX}/placements.csv", auth=django_auth_is_staff)
|
||||
|
||||
@@ -25,22 +25,25 @@ _PALETTE_RGB = [
|
||||
]
|
||||
|
||||
|
||||
def build_evolution_gif(event: Event) -> bytes:
|
||||
def build_evolution_gif(event: Event, usernames: list[str] | None = None) -> bytes:
|
||||
"""Renders `event`'s full placement history as an animated GIF, upscaled
|
||||
for visibility. Returns GIF bytes, even if there are zero placements.
|
||||
|
||||
If `usernames` is given, only those players' placements are replayed
|
||||
(combined on the same board).
|
||||
|
||||
Always replays at the *current* grid dimensions - a placement made
|
||||
before a resize that now falls outside them is skipped rather than
|
||||
raising."""
|
||||
place_settings = PlaceSettings.current(event)
|
||||
width, height = place_settings.width, place_settings.height
|
||||
|
||||
placements = (
|
||||
PixelPlacement.objects.filter(event=event)
|
||||
.order_by("placed_at")
|
||||
.values_list("x", "y", "color_index")
|
||||
placements = PixelPlacement.objects.filter(event=event)
|
||||
if usernames:
|
||||
placements = placements.filter(player__username__in=usernames)
|
||||
placements = list(
|
||||
placements.order_by("placed_at").values_list("x", "y", "color_index")
|
||||
)
|
||||
placements = list(placements)
|
||||
|
||||
grid = bytearray(width * height)
|
||||
frames: list[Image.Image] = []
|
||||
|
||||
Reference in New Issue
Block a user