Browse Source

Add album_artist idea

Colin Powell 2 years ago
parent
commit
db32777f28

+ 1 - 1
vrobbler/apps/music/admin.py

@@ -11,7 +11,7 @@ class AlbumAdmin(admin.ModelAdmin):
     list_display = (
     list_display = (
         "name",
         "name",
         "year",
         "year",
-        "primary_artist",
+        "album_artist",
         "theaudiodb_genre",
         "theaudiodb_genre",
         "theaudiodb_mood",
         "theaudiodb_mood",
         "musicbrainz_id",
         "musicbrainz_id",

+ 6 - 0
vrobbler/apps/music/constants.py

@@ -1,3 +1,9 @@
+VARIOUS_ARTIST_DICT = {
+    "name": "Various Artists",
+    "theaudiodb_id": "113641",
+    "musicbrainz_id": "89ad4ac3-39f7-470e-963a-56509c546377",
+}
+
 JELLYFIN_POST_KEYS = {
 JELLYFIN_POST_KEYS = {
     "ITEM_TYPE": "ItemType",
     "ITEM_TYPE": "ItemType",
     "RUN_TIME": "RunTime",
     "RUN_TIME": "RunTime",

+ 25 - 0
vrobbler/apps/music/migrations/0021_album_album_artist.py

@@ -0,0 +1,25 @@
+# Generated by Django 4.1.5 on 2023-03-15 16:22
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("music", "0020_album_bandcamp_id_artist_bandcamp_id"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="album",
+            name="album_artist",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.DO_NOTHING,
+                related_name="albums",
+                to="music.artist",
+            ),
+        ),
+    ]

+ 20 - 0
vrobbler/apps/music/migrations/0022_artist_theaudiodb_id.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.5 on 2023-03-15 16:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("music", "0021_album_album_artist"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="artist",
+            name="theaudiodb_id",
+            field=models.CharField(
+                blank=True, max_length=255, null=True, unique=True
+            ),
+        ),
+    ]

+ 19 - 10
vrobbler/apps/music/models.py

@@ -1,4 +1,3 @@
-import requests
 import logging
 import logging
 from tempfile import NamedTemporaryFile
 from tempfile import NamedTemporaryFile
 from typing import Dict, Optional
 from typing import Dict, Optional
@@ -6,19 +5,17 @@ from urllib.request import urlopen
 from uuid import uuid4
 from uuid import uuid4
 
 
 import musicbrainzngs
 import musicbrainzngs
+import requests
 from django.conf import settings
 from django.conf import settings
 from django.core.files.base import ContentFile, File
 from django.core.files.base import ContentFile, File
 from django.db import models
 from django.db import models
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 from django_extensions.db.models import TimeStampedModel
 from django_extensions.db.models import TimeStampedModel
+from music.allmusic import get_allmusic_slug, scrape_data_from_allmusic
+from music.bandcamp import get_bandcamp_slug
+from music.theaudiodb import lookup_album_from_tadb, lookup_artist_from_tadb
 from scrobbles.mixins import ScrobblableMixin
 from scrobbles.mixins import ScrobblableMixin
-from music.theaudiodb import lookup_artist_from_tadb, lookup_album_from_tadb
-from vrobbler.apps.music.allmusic import (
-    get_allmusic_slug,
-    scrape_data_from_allmusic,
-)
-from vrobbler.apps.music.bandcamp import get_bandcamp_slug
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}
 BNULL = {"blank": True, "null": True}
@@ -28,6 +25,7 @@ class Artist(TimeStampedModel):
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
     name = models.CharField(max_length=255)
     name = models.CharField(max_length=255)
     biography = models.TextField(**BNULL)
     biography = models.TextField(**BNULL)
+    theaudiodb_id = models.CharField(max_length=255, unique=True, **BNULL)
     theaudiodb_genre = models.CharField(max_length=255, **BNULL)
     theaudiodb_genre = models.CharField(max_length=255, **BNULL)
     theaudiodb_mood = models.CharField(max_length=255, **BNULL)
     theaudiodb_mood = models.CharField(max_length=255, **BNULL)
     musicbrainz_id = models.CharField(max_length=255, **BNULL)
     musicbrainz_id = models.CharField(max_length=255, **BNULL)
@@ -129,6 +127,9 @@ class Artist(TimeStampedModel):
 class Album(TimeStampedModel):
 class Album(TimeStampedModel):
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
     name = models.CharField(max_length=255)
     name = models.CharField(max_length=255)
+    album_artist = models.ForeignKey(
+        Artist, related_name="albums", on_delete=models.DO_NOTHING, **BNULL
+    )
     artists = models.ManyToManyField(Artist)
     artists = models.ManyToManyField(Artist)
     year = models.IntegerField(**BNULL)
     year = models.IntegerField(**BNULL)
     musicbrainz_id = models.CharField(max_length=255, unique=True, **BNULL)
     musicbrainz_id = models.CharField(max_length=255, unique=True, **BNULL)
@@ -175,9 +176,17 @@ class Album(TimeStampedModel):
             .order_by("-scrobble_count")
             .order_by("-scrobble_count")
         )
         )
 
 
-    @property
-    def primary_artist(self):
-        return self.artists.first()
+    def fix_album_artist(self):
+        from music.utils import get_or_create_various_artists
+
+        multiple_artists = self.artists.count() > 1
+        if not self.album_artist:
+            if multiple_artists:
+                self.album_artist = get_or_create_various_artists()
+            else:
+                self.album_artist = self.artists.first()
+
+            self.save(update_fields=["album_artist"])
 
 
     def scrape_allmusic(self, force=False) -> None:
     def scrape_allmusic(self, force=False) -> None:
         if not self.allmusic_id or force:
         if not self.allmusic_id or force:

+ 10 - 1
vrobbler/apps/music/utils.py

@@ -7,6 +7,7 @@ from music.musicbrainz import (
     lookup_artist_from_mb,
     lookup_artist_from_mb,
     lookup_track_from_mb,
     lookup_track_from_mb,
 )
 )
+from music.constants import VARIOUS_ARTIST_DICT
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
@@ -50,7 +51,7 @@ def get_or_create_album(
 
 
     logger.debug(f"Looking up album {name} and mbid: {mbid}")
     logger.debug(f"Looking up album {name} and mbid: {mbid}")
 
 
-    album = Album.objects.filter(artist=artist, name=name).first()
+    album = Album.objects.filter(album_artist=artist, name=name).first()
 
 
     if not album and name:
     if not album and name:
         album = Album.objects.create(name=name, musicbrainz_id=mbid)
         album = Album.objects.create(name=name, musicbrainz_id=mbid)
@@ -102,3 +103,11 @@ def get_or_create_track(
         )
         )
 
 
     return track
     return track
+
+
+def get_or_create_various_artists():
+    artist = Artist.objects.filter(name="Various Artists").first()
+    if not artist:
+        artist = Artist.objects.create(**VARIOUS_ARTIST_DICT)
+        logger.info("Created Various Artists placeholder")
+    return artist