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})"