Преглед на файлове

Fix scrobbling tracks with featured artists

Colin Powell преди 2 години
родител
ревизия
cc82504262

+ 11 - 8
vrobbler/apps/music/utils.py

@@ -2,7 +2,7 @@ import logging
 
 from scrobbles.musicbrainz import (
     lookup_album_dict_from_mb,
-    lookup_artist_id_from_mb,
+    lookup_artist_from_mb,
 )
 
 logger = logging.getLogger(__name__)
@@ -12,16 +12,18 @@ from music.models import Artist, Album, Track
 
 
 def get_or_create_artist(name: str, mbid: str = None) -> Artist:
+    if 'feat.' in name:
+        name = name.split('feat.')[0]
     if mbid:
-        artist, artist_created = Artist.objects.get_or_create(
-            name=name, musicbrainz_id=mbid
-        )
+        artist, created = Artist.objects.get_or_create(musicbrainz_id=mbid)
     else:
-        artist, artist_created = Artist.objects.get_or_create(name=name)
+        artist, created = Artist.objects.get_or_create(name=name)
 
-    if not mbid:
-        artist.musicbrainz_id = lookup_artist_id_from_mb(artist.name)
-        artist.save(update_fields=["musicbrainz_id"])
+    if created or not mbid:
+        artist_dict = lookup_artist_from_mb(name)
+        artist.musicbrainz_id = artist_dict["id"]
+        artist.name = artist_dict["name"]
+        artist.save(update_fields=["musicbrainz_id", "name"])
     return artist
 
 
@@ -80,6 +82,7 @@ def get_or_create_track(
             title=title, artist=artist, album=album
         ).first()
 
+    # TODO Can we look up mbid for tracks?
     if not track:
         track = Track.objects.create(
             title=title,

+ 1 - 1
vrobbler/apps/podcasts/models.py

@@ -7,7 +7,7 @@ from django.db import models
 from django.utils.translation import gettext_lazy as _
 from django_extensions.db.models import TimeStampedModel
 
-from vrobbler.apps.scrobbles.mixins import ScrobblableMixin
+from scrobbles.mixins import ScrobblableMixin
 
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}

+ 2 - 2
vrobbler/apps/scrobbles/models.py

@@ -8,11 +8,11 @@ from django.utils import timezone
 from django_extensions.db.models import TimeStampedModel
 from music.models import Artist, Track
 from podcasts.models import Episode
+from profiles.utils import now_user_timezone
+from scrobbles.lastfm import LastFM
 from scrobbles.utils import check_scrobble_for_finish
 from sports.models import SportEvent
 from videos.models import Series, Video
-from vrobbler.apps.profiles.utils import now_user_timezone
-from vrobbler.apps.scrobbles.lastfm import LastFM
 
 logger = logging.getLogger(__name__)
 User = get_user_model()

+ 19 - 2
vrobbler/apps/scrobbles/musicbrainz.py

@@ -73,7 +73,7 @@ def lookup_album_dict_from_mb(release_name: str, artist_name: str) -> dict:
     }
 
 
-def lookup_artist_id_from_mb(artist_name: str) -> str:
+def lookup_artist_from_mb(artist_name: str) -> str:
     musicbrainzngs.set_useragent('vrobbler', '0.3.0')
 
     top_result = musicbrainzngs.search_artists(artist=artist_name)[
@@ -87,4 +87,21 @@ def lookup_artist_id_from_mb(artist_name: str) -> str:
         )
         return ""
 
-    return top_result["id"]
+    return top_result
+
+
+def lookup_track_from_mb(artist_name: str) -> str:
+    musicbrainzngs.set_useragent('vrobbler', '0.3.0')
+
+    top_result = musicbrainzngs.search_recordings(artist=artist_name)[
+        'artist-list'
+    ][0]
+    score = int(top_result.get('ext:score'))
+    if score < 85:
+        logger.debug(
+            "Artist lookup score below 85 threshold",
+            extra={"result": top_result},
+        )
+        return ""
+
+    return top_result

+ 0 - 7
vrobbler/apps/scrobbles/scrobblers.py

@@ -124,13 +124,6 @@ def jellyfin_scrobble_track(
     data_dict: dict, user_id: Optional[int]
 ) -> Optional[Scrobble]:
 
-    if not data_dict.get("Provider_musicbrainztrack", None):
-        # TODO we should be able to look up tracks via MB rather than error out
-        logger.error(
-            "No MBrainz Track ID received. This is likely because all metadata is bad, not scrobbling"
-        )
-        return
-
     null_position_on_progress = (
         data_dict.get("PlaybackPosition") == "00:00:00"
         and data_dict.get("NotificationType") == "PlaybackProgress"

+ 20 - 9
vrobbler/apps/scrobbles/views.py

@@ -13,6 +13,12 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import FormView
 from django.views.generic.edit import CreateView
 from django.views.generic.list import ListView
+from music.aggregators import (
+    scrobble_counts,
+    top_artists,
+    top_tracks,
+    week_of_scrobbles,
+)
 from rest_framework import status
 from rest_framework.decorators import (
     api_view,
@@ -26,9 +32,10 @@ from scrobbles.constants import (
     JELLYFIN_AUDIO_ITEM_TYPES,
     JELLYFIN_VIDEO_ITEM_TYPES,
 )
+from scrobbles.export import export_scrobbles
 from scrobbles.forms import ExportScrobbleForm, ScrobbleForm
 from scrobbles.imdb import lookup_video_from_imdb
-from scrobbles.models import AudioScrobblerTSVImport, Scrobble
+from scrobbles.models import AudioScrobblerTSVImport, LastFmImport, Scrobble
 from scrobbles.scrobblers import (
     jellyfin_scrobble_track,
     jellyfin_scrobble_video,
@@ -41,16 +48,9 @@ from scrobbles.serializers import (
     AudioScrobblerTSVImportSerializer,
     ScrobbleSerializer,
 )
+from scrobbles.tasks import process_lastfm_import
 from scrobbles.thesportsdb import lookup_event_from_thesportsdb
 
-from vrobbler.apps.music.aggregators import (
-    scrobble_counts,
-    top_artists,
-    top_tracks,
-    week_of_scrobbles,
-)
-from vrobbler.apps.scrobbles.export import export_scrobbles
-
 logger = logging.getLogger(__name__)
 
 
@@ -176,6 +176,17 @@ class AudioScrobblerImportCreateView(
         return HttpResponseRedirect(self.get_success_url())
 
 
+@permission_classes([IsAuthenticated])
+@api_view(['GET'])
+def lastfm_import(request):
+    lfm_import = LastFmImport.objects.create(user=request.user)
+
+    process_lastfm_import.delay(lfm_import.id)
+
+    success_url = reverse_lazy('vrobbler-home')
+    return HttpResponseRedirect(success_url)
+
+
 @csrf_exempt
 @api_view(['GET'])
 def scrobble_endpoint(request):

+ 1 - 5
vrobbler/apps/sports/models.py

@@ -7,12 +7,8 @@ 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 sqlalchemy import update
 from scrobbles.mixins import ScrobblableMixin
-from vrobbler.apps.sports.utils import (
-    get_players_from_event,
-    get_round_name_from_event,
-)
+from sports.utils import get_players_from_event, get_round_name_from_event
 
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}