from emus.settings import RETROPIE_WEBRETRO_SYSTEM_MAP from enum import Enum from django.conf import settings from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.urls import reverse from django_extensions.db.models import TimeStampedModel from django_extensions.db.fields import AutoSlugField from emus.utils import ChoiceEnum def get_screenshot_upload_path(instance, filename): return f"{instance.game_system.retropie_slug}/screenshots/{filename}" def get_marquee_upload_path(instance, filename): return f"{instance.game_system.retropie_slug}/marquee/{filename}" def get_video_upload_path(instance, filename): return f"{instance.game_system.retropie_slug}/videos/{filename}" def get_rom_upload_path(instance, filename): return f"{instance.game_system.retropie_slug}/{filename}" class Region(Enum): USA = "US" EUROPE = "EU" JAPAN = "JP" class BaseModel(TimeStampedModel): """A base model for providing name and slugged fields for organizational models""" name = models.CharField(max_length=255) slug = AutoSlugField(populate_from="name") class Meta: ordering = ["name"] abstract = True def slugify_function(self, content): for element in settings.REMOVE_FROM_SLUGS: content = content.replace(element, "-") return content.lower() def __str__(self): return self.name class Genre(BaseModel): def get_absolute_url(self): return reverse("games:genre_detail", args=[self.slug]) class Publisher(BaseModel): def get_absolute_url(self): return reverse("games:publisher_detail", args=[self.slug]) class Developer(BaseModel): def get_absolute_url(self): return reverse("games:developer_detail", args=[self.slug]) class GameSystem(BaseModel): retropie_slug = models.CharField( blank=True, null=True, max_length=50, ) @property def webretro_core(self): return settings.RETROPIE_WEBRETRO_SYSTEM_MAP.get(self.retropie_slug, None) def get_absolute_url(self): return reverse("games:game_system_detail", args=[self.slug]) class Game(BaseModel): class Region(ChoiceEnum): US = "USA" EU = "Europe" JP = "Japan" X = "Unknown" game_system = models.ForeignKey( GameSystem, on_delete=models.SET_NULL, null=True, ) release_date = models.DateField( blank=True, null=True, ) developer = models.ForeignKey( Developer, on_delete=models.SET_NULL, blank=True, null=True, ) publisher = models.ForeignKey( Publisher, on_delete=models.SET_NULL, blank=True, null=True, ) genre = models.ManyToManyField( Genre, ) players = models.SmallIntegerField( default=1, ) kid_game = models.BooleanField( default=False, ) description = models.TextField( blank=True, null=True, ) rating = models.FloatField( blank=True, null=True, validators=[MaxValueValidator(1), MinValueValidator(0)], ) video = models.FileField( blank=True, null=True, max_length=300, upload_to=get_video_upload_path, ) marquee = models.ImageField( blank=True, null=True, max_length=300, upload_to=get_marquee_upload_path, ) screenshot = models.ImageField( blank=True, null=True, max_length=300, upload_to=get_screenshot_upload_path, ) rom_file = models.FileField( blank=True, null=True, max_length=300, upload_to=get_rom_upload_path, ) hack = models.BooleanField( default=False, ) hack_version = models.CharField( max_length=255, blank=True, null=True, ) english_patched = models.BooleanField( default=False, ) english_patched_version = models.CharField( max_length=50, blank=True, null=True, ) undub = models.BooleanField( default=False, ) featured = models.BooleanField( default=False, ) region = models.CharField( max_length=10, choices=Region.choices(), blank=True, null=True, ) class Meta: ordering = ["game_system", "name"] def __str__(self): return f"{self.name} for {self.game_system}" def rating_by_100(self) -> float: if self.rating: return int(100 * self.rating) return int(0) def get_absolute_url(self): return reverse("games:game_detail", args=[self.slug]) def get_play_url(self): if self.game_system.retropie_slug in RETROPIE_WEBRETRO_SYSTEM_MAP.keys(): return reverse("games:game_play_detail", args=[self.slug])