Browse Source

Add first pass at AudioDB fetching

Colin Powell 2 years ago
parent
commit
a0101bf1ae

+ 28 - 0
vrobbler/apps/music/migrations/0010_artist_biography_artist_theaudiodb_genre_and_more.py

@@ -0,0 +1,28 @@
+# Generated by Django 4.1.5 on 2023-02-27 03:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('music', '0009_alter_track_musicbrainz_id_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='artist',
+            name='biography',
+            field=models.TextField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='artist',
+            name='theaudiodb_genre',
+            field=models.CharField(blank=True, max_length=255, null=True),
+        ),
+        migrations.AddField(
+            model_name='artist',
+            name='theaudiodb_mood',
+            field=models.CharField(blank=True, max_length=255, null=True),
+        ),
+    ]

+ 20 - 0
vrobbler/apps/music/migrations/0011_artist_thumbnail.py

@@ -0,0 +1,20 @@
+# Generated by Django 4.1.5 on 2023-02-27 04:04
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('music', '0010_artist_biography_artist_theaudiodb_genre_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='artist',
+            name='thumbnail',
+            field=models.ImageField(
+                blank=True, null=True, upload_to='artist/'
+            ),
+        ),
+    ]

+ 24 - 1
vrobbler/apps/music/models.py

@@ -1,15 +1,18 @@
 import logging
+from tempfile import NamedTemporaryFile
 from typing import Dict, Optional
+from urllib.request import urlopen
 from uuid import uuid4
 
 import musicbrainzngs
 from django.conf import settings
-from django.core.files.base import ContentFile
+from django.core.files.base import File
 from django.db import models
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django_extensions.db.models import TimeStampedModel
 from scrobbles.mixins import ScrobblableMixin
+from scrobbles.theaudiodb import lookup_artist_from_tadb
 
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}
@@ -18,7 +21,11 @@ BNULL = {"blank": True, "null": True}
 class Artist(TimeStampedModel):
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
     name = models.CharField(max_length=255)
+    biography = models.TextField(**BNULL)
+    theaudiodb_genre = models.CharField(max_length=255, **BNULL)
+    theaudiodb_mood = models.CharField(max_length=255, **BNULL)
     musicbrainz_id = models.CharField(max_length=255, **BNULL)
+    thumbnail = models.ImageField(upload_to="artist/", **BNULL)
 
     class Meta:
         unique_together = [['name', 'musicbrainz_id']]
@@ -53,6 +60,22 @@ class Artist(TimeStampedModel):
 
         return ChartRecord.objects.filter(track__artist=self).order_by('-year')
 
+    def fix_metadata(self):
+        tadb_info = lookup_artist_from_tadb(self.name)
+        if not tadb_info:
+            logger.warn(f"No response from TADB for artist {self.name}")
+            return
+
+        self.biography = tadb_info['biography']
+        self.theaudiodb_genre = tadb_info['genre']
+        self.theaudiodb_mood = tadb_info['mood']
+
+        img_temp = NamedTemporaryFile(delete=True)
+        img_temp.write(urlopen(tadb_info['thumb_url']).read())
+        img_temp.flush()
+        img_filename = f"{self.name}_{self.uuid}.jpg"
+        self.thumbnail.save(img_filename, File(img_temp))
+
 
 class Album(TimeStampedModel):
     uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)

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

@@ -36,7 +36,7 @@ def get_or_create_artist(name: str, mbid: str = None) -> Artist:
         logger.debug(
             f"Created artist {artist.name} ({artist.musicbrainz_id}) "
         )
-        # TODO Enrich artist with MB data
+        artist.fix_metadata()
 
     return artist
 

+ 33 - 0
vrobbler/apps/scrobbles/theaudiodb.py

@@ -0,0 +1,33 @@
+import json
+import logging
+
+import requests
+from django.conf import settings
+
+THEAUDIODB_API_KEY = getattr(settings, "THEAUDIODB_API_KEY")
+SEARCH_URL = f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/search.php?s="
+
+logger = logging.getLogger(__name__)
+
+
+def lookup_artist_from_tadb(name: str) -> dict:
+    artist_info = {}
+    response = requests.get(SEARCH_URL + name)
+
+    if response.status_code != 200:
+        logger.warn(f"Bad response from TADB: {response.status_code}")
+        return {}
+
+    if not response.content:
+        logger.warn(f"Bad content from TADB: {response.content}")
+        return {}
+
+    results = json.loads(response.content)
+    artist = results['artists'][0]
+
+    artist_info['biography'] = artist['strBiographyEN']
+    artist_info['genre'] = artist['strGenre']
+    artist_info['mood'] = artist['strMood']
+    artist_info['thumb_url'] = artist['strArtistThumb']
+
+    return artist_info

+ 1 - 5
vrobbler/settings.py

@@ -51,13 +51,9 @@ DELETE_STALE_SCROBBLES = os.getenv("VROBBLER_DELETE_STALE_SCROBBLES", True)
 # Used to dump data coming from srobbling sources, helpful for building new inputs
 DUMP_REQUEST_DATA = os.getenv("VROBBLER_DUMP_REQUEST_DATA", False)
 
-
 THESPORTSDB_API_KEY = os.getenv("VROBBLER_THESPORTSDB_API_KEY", "2")
-THESPORTSDB_BASE_URL = os.getenv(
-    "VROBBLER_THESPORTSDB_BASE_URL", "https://www.thesportsdb.com/api/v1/json/"
-)
+THEAUDIODB_API_KEY = os.getenv("VROBBLER_THEAUDIODB_API_KEY", "2")
 TMDB_API_KEY = os.getenv("VROBBLER_TMDB_API_KEY", "")
-
 LASTFM_API_KEY = os.getenv("VROBBLER_LASTFM_API_KEY")
 LASTFM_SECRET_KEY = os.getenv("VROBBLER_LASTFM_SECRET_KEY")