models.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import logging
  2. from typing import Dict, Optional
  3. from django.db import models
  4. from django_extensions.db.models import TimeStampedModel
  5. from django.utils.translation import gettext_lazy as _
  6. from vrobbler.apps.music.constants import JELLYFIN_POST_KEYS as KEYS
  7. logger = logging.getLogger(__name__)
  8. BNULL = {"blank": True, "null": True}
  9. class Album(TimeStampedModel):
  10. name = models.CharField(max_length=255)
  11. year = models.IntegerField(**BNULL)
  12. musicbrainz_id = models.CharField(max_length=255, **BNULL)
  13. musicbrainz_releasegroup_id = models.CharField(max_length=255, **BNULL)
  14. musicbrainz_albumartist_id = models.CharField(max_length=255, **BNULL)
  15. def __str__(self):
  16. return self.name
  17. class Artist(TimeStampedModel):
  18. name = models.CharField(max_length=255)
  19. musicbrainz_id = models.CharField(max_length=255, **BNULL)
  20. def __str__(self):
  21. return self.name
  22. class Track(TimeStampedModel):
  23. title = models.CharField(max_length=255, **BNULL)
  24. artist = models.ForeignKey(Artist, on_delete=models.DO_NOTHING)
  25. album = models.ForeignKey(Album, on_delete=models.DO_NOTHING, **BNULL)
  26. musicbrainz_id = models.CharField(max_length=255, **BNULL)
  27. run_time = models.CharField(max_length=8, **BNULL)
  28. run_time_ticks = models.PositiveBigIntegerField(**BNULL)
  29. def __str__(self):
  30. return f"{self.title} by {self.artist}"
  31. @classmethod
  32. def find_or_create(
  33. cls, artist_dict: Dict, album_dict: Dict, track_dict: Dict
  34. ) -> Optional["Track"]:
  35. """Given a data dict from Jellyfin, does the heavy lifting of looking up
  36. the video and, if need, TV Series, creating both if they don't yet
  37. exist.
  38. """
  39. if not artist_dict.get('name') or not artist_dict.get(
  40. 'musicbrainz_id'
  41. ):
  42. logger.warning(
  43. f"No artist or artist musicbrainz ID found in message from Jellyfin, not scrobbling"
  44. )
  45. return
  46. artist, artist_created = Artist.objects.get_or_create(**artist_dict)
  47. if artist_created:
  48. logger.debug(f"Created new album {artist}")
  49. else:
  50. logger.debug(f"Found album {artist}")
  51. album, album_created = Album.objects.get_or_create(**album_dict)
  52. if album_created:
  53. logger.debug(f"Created new album {album}")
  54. else:
  55. logger.debug(f"Found album {album}")
  56. track_dict['album_id'] = getattr(album, "id", None)
  57. track_dict['artist_id'] = artist.id
  58. track, created = cls.objects.get_or_create(**track_dict)
  59. if created:
  60. logger.debug(f"Created new track: {track}")
  61. else:
  62. logger.debug(f"Found track{track}")
  63. return track