126 lines
4.4 KiB
Python
126 lines
4.4 KiB
Python
from django.db import models
|
|
|
|
from events.models import Event
|
|
|
|
|
|
class GameQuerySet(models.QuerySet):
|
|
def enabled_for_event(self, event):
|
|
return self.filter(event_games__event=event, event_games__enabled=True)
|
|
|
|
|
|
class Game(models.Model):
|
|
steam_app_id = models.PositiveIntegerField(null=True, blank=True)
|
|
name = models.CharField(max_length=255)
|
|
path = models.CharField(max_length=100)
|
|
custom_path = models.BooleanField(default=False)
|
|
image = models.URLField(null=True, blank=True)
|
|
description = models.TextField(blank=True, default="")
|
|
# Vertical (600x900) cover for games/showcase, empty = Steam's library capsule
|
|
library_image = models.URLField(max_length=500, blank=True, default="")
|
|
|
|
# Steam store info, refreshed in the background (see games.tasks).
|
|
# Prices are in cents, in steam_currency.
|
|
steam_price_initial = models.PositiveIntegerField(null=True, blank=True)
|
|
steam_price_final = models.PositiveIntegerField(null=True, blank=True)
|
|
steam_discount_percent = models.PositiveSmallIntegerField(default=0)
|
|
steam_currency = models.CharField(max_length=3, blank=True, default="")
|
|
steam_is_free = models.BooleanField(default=False)
|
|
steam_short_description = models.TextField(blank=True, default="")
|
|
steam_header_image = models.URLField(max_length=500, blank=True, default="")
|
|
steam_info_updated_at = models.DateTimeField(null=True, blank=True)
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
objects = models.Manager.from_queryset(GameQuerySet)()
|
|
|
|
class Meta:
|
|
ordering = ["name"]
|
|
|
|
def __str__(self) -> str:
|
|
if self.steam_app_id:
|
|
return f"{self.name} ({self.steam_app_id})"
|
|
return self.name
|
|
|
|
@property
|
|
def store_url(self) -> str:
|
|
if not self.steam_app_id:
|
|
return ""
|
|
return f"https://store.steampowered.com/app/{self.steam_app_id}"
|
|
|
|
@property
|
|
def library_image_url(self) -> str:
|
|
"""Vertical cover, like in the Steam library. Empty if there's none."""
|
|
if self.library_image or not self.steam_app_id:
|
|
return self.library_image
|
|
return f"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/{self.steam_app_id}/library_600x900.jpg"
|
|
|
|
|
|
class EventGame(models.Model):
|
|
event = models.ForeignKey(
|
|
Event,
|
|
on_delete=models.CASCADE,
|
|
related_name="event_games",
|
|
)
|
|
game = models.ForeignKey(
|
|
Game,
|
|
on_delete=models.CASCADE,
|
|
related_name="event_games",
|
|
)
|
|
enabled = models.BooleanField(default=True)
|
|
|
|
apibot_token = models.CharField(
|
|
max_length=512,
|
|
blank=True,
|
|
null=True,
|
|
help_text=(
|
|
"Bearer token for the legacy PolyLAN AAndT API (from the AAndT's "
|
|
"'apibot' admin page), used to auto-sync Scopes and their assigned users."
|
|
),
|
|
)
|
|
|
|
class Meta:
|
|
constraints = [
|
|
models.UniqueConstraint(
|
|
fields=["event", "game"],
|
|
name="unique_event_game",
|
|
),
|
|
]
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.game.name} @ {self.event.name} ({'enabled' if self.enabled else 'disabled'})"
|
|
|
|
|
|
class PlanningSlot(models.Model):
|
|
"""One slot of the event planning, imported from the legacy PolyLAN planning
|
|
(see the import_planning command)."""
|
|
|
|
event = models.ForeignKey(
|
|
Event,
|
|
on_delete=models.CASCADE,
|
|
related_name="planning_slots",
|
|
)
|
|
# pk of the slot in the legacy planning, to update it on re-import
|
|
source_pk = models.PositiveIntegerField()
|
|
title = models.CharField(max_length=255)
|
|
begin = models.DateTimeField()
|
|
end = models.DateTimeField()
|
|
column = models.PositiveSmallIntegerField(default=0)
|
|
color = models.CharField(max_length=7, blank=True, default="")
|
|
# Multi-anims (e.g. "Fils rouges") run several games over the whole event
|
|
is_multi_anims = models.BooleanField(default=False)
|
|
# Names of the games run in this slot (the legacy "aandts")
|
|
game_names = models.JSONField(default=list, blank=True)
|
|
|
|
class Meta:
|
|
ordering = ["begin", "column"]
|
|
constraints = [
|
|
models.UniqueConstraint(
|
|
fields=["event", "source_pk"],
|
|
name="unique_event_planning_slot",
|
|
),
|
|
]
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.title} @ {self.event.name} ({self.begin:%a %H:%M})"
|