models.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. from emus.settings import RETROPIE_WEBRETRO_SYSTEM_MAP
  2. from enum import Enum
  3. from django.conf import settings
  4. from django.core.validators import MaxValueValidator, MinValueValidator
  5. from django.db import models
  6. from django.urls import reverse
  7. from django_extensions.db.models import TimeStampedModel
  8. from django_extensions.db.fields import AutoSlugField
  9. from emus.utils import ChoiceEnum
  10. def get_screenshot_upload_path(instance, filename):
  11. return f"{instance.game_system.retropie_slug}/screenshots/{filename}"
  12. def get_marquee_upload_path(instance, filename):
  13. return f"{instance.game_system.retropie_slug}/marquee/{filename}"
  14. def get_video_upload_path(instance, filename):
  15. return f"{instance.game_system.retropie_slug}/videos/{filename}"
  16. def get_rom_upload_path(instance, filename):
  17. return f"{instance.game_system.retropie_slug}/{filename}"
  18. class Region(Enum):
  19. USA = "US"
  20. EUROPE = "EU"
  21. JAPAN = "JP"
  22. class BaseModel(TimeStampedModel):
  23. """A base model for providing name and slugged fields for organizational models"""
  24. name = models.CharField(max_length=255)
  25. slug = AutoSlugField(populate_from="name")
  26. class Meta:
  27. ordering = ["name"]
  28. abstract = True
  29. def slugify_function(self, content):
  30. for element in settings.REMOVE_FROM_SLUGS:
  31. content = content.replace(element, "-")
  32. return content.lower()
  33. def __str__(self):
  34. return self.name
  35. class Genre(BaseModel):
  36. def get_absolute_url(self):
  37. return reverse("games:genre_detail", args=[self.slug])
  38. class Publisher(BaseModel):
  39. def get_absolute_url(self):
  40. return reverse("games:publisher_detail", args=[self.slug])
  41. class Developer(BaseModel):
  42. def get_absolute_url(self):
  43. return reverse("games:developer_detail", args=[self.slug])
  44. class GameSystem(BaseModel):
  45. retropie_slug = models.CharField(
  46. blank=True,
  47. null=True,
  48. max_length=50,
  49. )
  50. @property
  51. def webretro_core(self):
  52. return settings.RETROPIE_WEBRETRO_SYSTEM_MAP.get(self.retropie_slug, None)
  53. def get_absolute_url(self):
  54. return reverse("games:game_system_detail", args=[self.slug])
  55. class Game(BaseModel):
  56. class Region(ChoiceEnum):
  57. US = "USA"
  58. EU = "Europe"
  59. JP = "Japan"
  60. X = "Unknown"
  61. game_system = models.ForeignKey(
  62. GameSystem,
  63. on_delete=models.SET_NULL,
  64. null=True,
  65. )
  66. release_date = models.DateField(
  67. blank=True,
  68. null=True,
  69. )
  70. developer = models.ForeignKey(
  71. Developer,
  72. on_delete=models.SET_NULL,
  73. blank=True,
  74. null=True,
  75. )
  76. publisher = models.ForeignKey(
  77. Publisher,
  78. on_delete=models.SET_NULL,
  79. blank=True,
  80. null=True,
  81. )
  82. genre = models.ManyToManyField(
  83. Genre,
  84. )
  85. players = models.SmallIntegerField(
  86. default=1,
  87. )
  88. kid_game = models.BooleanField(
  89. default=False,
  90. )
  91. description = models.TextField(
  92. blank=True,
  93. null=True,
  94. )
  95. rating = models.FloatField(
  96. blank=True,
  97. null=True,
  98. validators=[MaxValueValidator(1), MinValueValidator(0)],
  99. )
  100. video = models.FileField(
  101. blank=True,
  102. null=True,
  103. max_length=300,
  104. upload_to=get_video_upload_path,
  105. )
  106. marquee = models.ImageField(
  107. blank=True,
  108. null=True,
  109. max_length=300,
  110. upload_to=get_marquee_upload_path,
  111. )
  112. screenshot = models.ImageField(
  113. blank=True,
  114. null=True,
  115. max_length=300,
  116. upload_to=get_screenshot_upload_path,
  117. )
  118. rom_file = models.FileField(
  119. blank=True,
  120. null=True,
  121. max_length=300,
  122. upload_to=get_rom_upload_path,
  123. )
  124. hack = models.BooleanField(
  125. default=False,
  126. )
  127. hack_version = models.CharField(
  128. max_length=255,
  129. blank=True,
  130. null=True,
  131. )
  132. english_patched = models.BooleanField(
  133. default=False,
  134. )
  135. english_patched_version = models.CharField(
  136. max_length=50,
  137. blank=True,
  138. null=True,
  139. )
  140. undub = models.BooleanField(
  141. default=False,
  142. )
  143. featured = models.BooleanField(
  144. default=False,
  145. )
  146. region = models.CharField(
  147. max_length=10,
  148. choices=Region.choices(),
  149. blank=True,
  150. null=True,
  151. )
  152. class Meta:
  153. ordering = ["game_system", "name"]
  154. def __str__(self):
  155. return f"{self.name} for {self.game_system}"
  156. def rating_by_100(self) -> float:
  157. if self.rating:
  158. return int(100 * self.rating)
  159. return int(0)
  160. def get_absolute_url(self):
  161. return reverse("games:game_detail", args=[self.slug])
  162. def get_play_url(self):
  163. if self.game_system.retropie_slug in RETROPIE_WEBRETRO_SYSTEM_MAP.keys():
  164. return reverse("games:game_play_detail", args=[self.slug])