models.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import logging
  2. from typing import Dict
  3. from uuid import uuid4
  4. from django.conf import settings
  5. from django.db import models
  6. from django.urls import reverse
  7. from django.utils.translation import gettext_lazy as _
  8. from django_extensions.db.models import TimeStampedModel
  9. from scrobbles.mixins import ScrobblableMixin
  10. logger = logging.getLogger(__name__)
  11. BNULL = {"blank": True, "null": True}
  12. class League(TimeStampedModel):
  13. name = models.CharField(max_length=255)
  14. uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
  15. logo = models.ImageField(upload_to="sports/league-logos/", **BNULL)
  16. abbreviation_str = models.CharField(max_length=10, **BNULL)
  17. thesportsdb_id = models.IntegerField(**BNULL)
  18. def __str__(self):
  19. return self.name
  20. @property
  21. def abbreviation(self):
  22. return self.abbreviation_str
  23. class Team(TimeStampedModel):
  24. name = models.CharField(max_length=255)
  25. uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
  26. league = models.ForeignKey(League, on_delete=models.DO_NOTHING, **BNULL)
  27. thesportsdb_id = models.IntegerField(**BNULL)
  28. def __str__(self):
  29. return self.name
  30. class SportEvent(ScrobblableMixin):
  31. RESUME_LIMIT = getattr(settings, 'SPORT_RESUME_LIMIT', (12 * 60) * 60)
  32. COMPLETION_PERCENT = getattr(settings, 'SPORT_COMPLETION_PERCENT', 90)
  33. class Type(models.TextChoices):
  34. UNKNOWN = 'UK', _('Unknown')
  35. GAME = 'GA', _('Game')
  36. MATCH = 'MA', _('Match')
  37. MEET = 'ME', _('Meet')
  38. event_type = models.CharField(
  39. max_length=2,
  40. choices=Type.choices,
  41. default=Type.UNKNOWN,
  42. )
  43. league = models.ForeignKey(League, on_delete=models.DO_NOTHING, **BNULL)
  44. start = models.DateTimeField(**BNULL)
  45. home_team = models.ForeignKey(
  46. Team,
  47. on_delete=models.DO_NOTHING,
  48. related_name='home_event_set',
  49. **BNULL,
  50. )
  51. away_team = models.ForeignKey(
  52. Team,
  53. on_delete=models.DO_NOTHING,
  54. related_name='away_event_set',
  55. **BNULL,
  56. )
  57. season = models.CharField(max_length=255, **BNULL)
  58. def __str__(self):
  59. return f"{self.start.date()} - {self.league.abbreviation} - {self.home_team} v {self.away_team}"
  60. def get_absolute_url(self):
  61. return reverse("sports:event_detail", kwargs={'slug': self.uuid})
  62. @classmethod
  63. def find_or_create(cls, data_dict: Dict) -> "Event":
  64. """Given a data dict from Jellyfin, does the heavy lifting of looking up
  65. the video and, if need, TV Series, creating both if they don't yet
  66. exist.
  67. """
  68. league_dict = {
  69. "abbreviation_str": data_dict.get("LeagueName", ""),
  70. "thesportsdb_id": data_dict.get("LeagueId", ""),
  71. }
  72. league, _created = League.objects.get_or_create(**league_dict)
  73. home_team_dict = {
  74. "name": data_dict.get("HomeTeamName", ""),
  75. "thesportsdb_id": data_dict.get("HomeTeamId", ""),
  76. "league": league,
  77. }
  78. home_team, _created = Team.objects.get_or_create(**home_team_dict)
  79. away_team_dict = {
  80. "name": data_dict.get("AwayTeamName", ""),
  81. "thesportsdb_id": data_dict.get("AwayTeamId", ""),
  82. "league": league,
  83. }
  84. away_team, _created = Team.objects.get_or_create(**away_team_dict)
  85. event_dict = {
  86. "title": data_dict.get("Name"),
  87. "event_type": data_dict.get("ItemType"),
  88. "home_team": home_team,
  89. "away_team": away_team,
  90. "start": data_dict['Start'],
  91. "league": league,
  92. "run_time_ticks": data_dict.get("RunTimeTicks"),
  93. "run_time": data_dict.get("RunTime", ""),
  94. }
  95. event, _created = cls.objects.get_or_create(**event_dict)
  96. return event