models.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import logging
  2. from typing import Dict, Optional
  3. from uuid import uuid4
  4. from django.conf import settings
  5. from django.db import models
  6. from django.utils.translation import gettext_lazy as _
  7. from django_extensions.db.models import TimeStampedModel
  8. from scrobbles.mixins import ScrobblableMixin
  9. logger = logging.getLogger(__name__)
  10. BNULL = {"blank": True, "null": True}
  11. class Producer(TimeStampedModel):
  12. name = models.CharField(max_length=255)
  13. uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
  14. def __str__(self):
  15. return f"{self.name}"
  16. class Podcast(TimeStampedModel):
  17. name = models.CharField(max_length=255)
  18. uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
  19. producer = models.ForeignKey(
  20. Producer, on_delete=models.DO_NOTHING, **BNULL
  21. )
  22. active = models.BooleanField(default=True)
  23. url = models.URLField(**BNULL)
  24. def __str__(self):
  25. return f"{self.name}"
  26. class Episode(ScrobblableMixin):
  27. COMPLETION_PERCENT = getattr(settings, 'PODCAST_COMPLETION_PERCENT', 90)
  28. podcast = models.ForeignKey(Podcast, on_delete=models.DO_NOTHING)
  29. number = models.IntegerField(**BNULL)
  30. pub_date = models.DateField(**BNULL)
  31. mopidy_uri = models.CharField(max_length=255, **BNULL)
  32. def __str__(self):
  33. return f"{self.title}"
  34. @property
  35. def subtitle(self):
  36. return self.podcast
  37. @property
  38. def info_link(self):
  39. return ""
  40. @classmethod
  41. def find_or_create(
  42. cls, podcast_dict: Dict, producer_dict: Dict, episode_dict: Dict
  43. ) -> Optional["Episode"]:
  44. """Given a data dict from Mopidy, finds or creates a podcast and
  45. producer before saving the epsiode so it can be scrobbled.
  46. """
  47. if not podcast_dict.get('name'):
  48. logger.warning(f"No name from source for podcast, not scrobbling")
  49. return
  50. producer = None
  51. if producer_dict.get('name'):
  52. producer, producer_created = Producer.objects.get_or_create(
  53. **producer_dict
  54. )
  55. if producer_created:
  56. logger.debug(f"Created new producer {producer}")
  57. else:
  58. logger.debug(f"Found producer {producer}")
  59. if producer:
  60. podcast_dict["producer_id"] = producer.id
  61. podcast, podcast_created = Podcast.objects.get_or_create(
  62. **podcast_dict
  63. )
  64. if podcast_created:
  65. logger.debug(f"Created new podcast {podcast}")
  66. else:
  67. logger.debug(f"Found podcast {podcast}")
  68. episode_dict['podcast_id'] = podcast.id
  69. episode, created = cls.objects.get_or_create(**episode_dict)
  70. if created:
  71. logger.debug(f"Created new episode: {episode}")
  72. else:
  73. logger.debug(f"Found episode {episode}")
  74. return episode