utils.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import logging
  2. import re
  3. from typing import Optional
  4. from music.musicbrainz import (
  5. lookup_album_dict_from_mb,
  6. lookup_artist_from_mb,
  7. lookup_track_from_mb,
  8. )
  9. from music.constants import VARIOUS_ARTIST_DICT
  10. logger = logging.getLogger(__name__)
  11. from music.models import Album, Artist, Track
  12. def get_or_create_artist(name: str, mbid: str = None) -> Artist:
  13. artist = None
  14. if "feat." in name.lower():
  15. name = re.split("feat.", name, flags=re.IGNORECASE)[0].strip()
  16. if "featuring" in name.lower():
  17. name = re.split("featuring", name, flags=re.IGNORECASE)[0].strip()
  18. if "&" in name.lower():
  19. name = re.split("&", name, flags=re.IGNORECASE)[0].strip()
  20. artist_dict = lookup_artist_from_mb(name)
  21. mbid = mbid or artist_dict.get("id", None)
  22. if mbid:
  23. artist = Artist.objects.filter(musicbrainz_id=mbid).first()
  24. if not artist:
  25. artist = Artist.objects.create(name=name, musicbrainz_id=mbid)
  26. artist.fix_metadata()
  27. return artist
  28. def get_or_create_album(
  29. name: str, artist: Artist, mbid: str = None
  30. ) -> Optional[Album]:
  31. album = None
  32. album_dict = lookup_album_dict_from_mb(name, artist_name=artist.name)
  33. name = name or album_dict.get("title", None)
  34. if not name:
  35. logger.debug(
  36. f"Cannot get or create album by {artist} with no name ({name})"
  37. )
  38. return
  39. album = Album.objects.filter(
  40. musicbrainz_id=mbid, name=name, artists__in=[artist]
  41. ).first()
  42. if not album:
  43. mbid_group = album_dict.get("mb_group_id")
  44. album = Album.objects.filter(
  45. musicbrainz_releasegroup_id=mbid_group
  46. ).first()
  47. if not album and name:
  48. mbid = mbid or album_dict["mb_id"]
  49. album, album_created = Album.objects.get_or_create(musicbrainz_id=mbid)
  50. if album_created:
  51. album.name = name
  52. album.year = album_dict["year"]
  53. album.musicbrainz_releasegroup_id = album_dict["mb_group_id"]
  54. album.musicbrainz_albumartist_id = artist.musicbrainz_id
  55. album.save(
  56. update_fields=[
  57. "name",
  58. "musicbrainz_id",
  59. "year",
  60. "musicbrainz_releasegroup_id",
  61. "musicbrainz_albumartist_id",
  62. ]
  63. )
  64. album.artists.add(artist)
  65. album.fix_album_artist()
  66. album.fetch_artwork()
  67. album.scrape_allmusic()
  68. if not album:
  69. logger.warn(f"No album found for {name} and {mbid}")
  70. album.fix_album_artist()
  71. return album
  72. def get_or_create_track(
  73. title: str,
  74. artist: Artist,
  75. album: Album = None,
  76. mbid: str = None,
  77. run_time_seconds=None,
  78. ) -> Track:
  79. track = None
  80. if not mbid and album:
  81. try:
  82. mbid = lookup_track_from_mb(
  83. title,
  84. artist.musicbrainz_id,
  85. album.musicbrainz_id,
  86. ).get("id", 0)
  87. except TypeError:
  88. pass
  89. if mbid:
  90. track = Track.objects.filter(musicbrainz_id=mbid).first()
  91. if not track:
  92. track = Track.objects.create(
  93. title=title,
  94. artist=artist,
  95. album=album,
  96. musicbrainz_id=mbid,
  97. run_time_seconds=run_time_seconds,
  98. )
  99. return track
  100. def get_or_create_various_artists():
  101. artist = Artist.objects.filter(name="Various Artists").first()
  102. if not artist:
  103. artist = Artist.objects.create(**VARIOUS_ARTIST_DICT)
  104. logger.info("Created Various Artists placeholder")
  105. return artist