models.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. @classmethod
  35. def find_or_create(
  36. cls, podcast_dict: Dict, producer_dict: Dict, episode_dict: Dict
  37. ) -> Optional["Episode"]:
  38. """Given a data dict from Mopidy, finds or creates a podcast and
  39. producer before saving the epsiode so it can be scrobbled.
  40. """
  41. if not podcast_dict.get('name'):
  42. logger.warning(f"No name from source for podcast, not scrobbling")
  43. return
  44. producer = None
  45. if producer_dict.get('name'):
  46. producer, producer_created = Producer.objects.get_or_create(
  47. **producer_dict
  48. )
  49. if producer_created:
  50. logger.debug(f"Created new producer {producer}")
  51. else:
  52. logger.debug(f"Found producer {producer}")
  53. if producer:
  54. podcast_dict["producer_id"] = producer.id
  55. podcast, podcast_created = Podcast.objects.get_or_create(
  56. **podcast_dict
  57. )
  58. if podcast_created:
  59. logger.debug(f"Created new podcast {podcast}")
  60. else:
  61. logger.debug(f"Found podcast {podcast}")
  62. episode_dict['podcast_id'] = podcast.id
  63. episode, created = cls.objects.get_or_create(**episode_dict)
  64. if created:
  65. logger.debug(f"Created new episode: {episode}")
  66. else:
  67. logger.debug(f"Found episode {episode}")
  68. return episode