Dramatically simplify the scrobblig code

This commit is contained in:
2023-01-12 21:33:45 -05:00
parent 507b3aaaf2
commit 3f8b29f5ee
13 changed files with 273 additions and 199 deletions

View File

@ -1,11 +1,14 @@
import logging
from typing import Optional
from dateutil.parser import parse
from django.utils import timezone
from music.constants import JELLYFIN_POST_KEYS
from music.models import Track
from podcasts.models import Episode
from scrobbles.models import Scrobble
from scrobbles.utils import parse_mopidy_uri
from scrobbles.utils import convert_to_seconds, parse_mopidy_uri
from videos.models import Video
logger = logging.getLogger(__name__)
@ -41,7 +44,7 @@ def mopidy_scrobble_podcast(
"timestamp": timezone.now(),
"playback_position_ticks": data_dict.get("playback_time_ticks"),
"source": "Mopidy",
"status": data_dict.get("status"),
"mopidy_status": data_dict.get("status"),
}
scrobble = None
@ -79,10 +82,11 @@ def mopidy_scrobble_track(
"timestamp": timezone.now(),
"playback_position_ticks": data_dict.get("playback_time_ticks"),
"source": "Mopidy",
"status": data_dict.get("status"),
"mopidy_status": data_dict.get("status"),
}
scrobble = None
if track:
# Jellyfin MB ids suck, so always overwrite with Mopidy if they're offering
track.musicbrainz_id = data_dict.get("musicbrainz_track_id")
@ -91,3 +95,84 @@ def mopidy_scrobble_track(
track, user_id, mopidy_data
)
return scrobble
def create_jellyfin_scrobble_dict(data_dict: dict, user_id: int) -> dict:
jellyfin_status = "resumed"
if data_dict.get("IsPaused"):
jellyfin_status = "paused"
if data_dict.get("PlayedToCompletion"):
jellyfin_status = "stopped"
return {
"user_id": user_id,
"timestamp": parse(data_dict.get("UtcTimestamp")),
"playback_position_ticks": data_dict.get("PlaybackPositionTicks")
// 10000,
"playback_position": convert_to_seconds(
data_dict.get("PlaybackPosition")
),
"source": "Jellyfin",
"source_id": data_dict.get('MediaSourceId'),
"jellyfin_status": jellyfin_status,
}
def jellyfin_scrobble_track(
data_dict: dict, user_id: Optional[int]
) -> Optional[Scrobble]:
if not data_dict.get("Provider_musicbrainztrack", None):
logger.error(
"No MBrainz Track ID received. This is likely because all metadata is bad, not scrobbling"
)
return
artist_dict = {
'name': data_dict.get(JELLYFIN_POST_KEYS["ARTIST_NAME"], None),
'musicbrainz_id': data_dict.get(
JELLYFIN_POST_KEYS["ARTIST_MB_ID"], None
),
}
album_dict = {
"name": data_dict.get(JELLYFIN_POST_KEYS["ALBUM_NAME"], None),
"musicbrainz_id": data_dict.get(JELLYFIN_POST_KEYS['ALBUM_MB_ID']),
}
# Convert ticks from Jellyfin from microseconds to nanoseconds
# Ain't nobody got time for nanoseconds
track_dict = {
"title": data_dict.get("Name", ""),
"run_time_ticks": data_dict.get(
JELLYFIN_POST_KEYS["RUN_TIME_TICKS"], None
)
// 10000,
"run_time": convert_to_seconds(
data_dict.get(JELLYFIN_POST_KEYS["RUN_TIME"], None)
),
}
track = Track.find_or_create(artist_dict, album_dict, track_dict)
# Prefer Mopidy MD IDs to Jellyfin, so skip if we already have one
if not track.musicbrainz_id:
track.musicbrainz_id = data_dict.get(
JELLYFIN_POST_KEYS["TRACK_MB_ID"], None
)
track.save()
scrobble_dict = create_jellyfin_scrobble_dict(data_dict, user_id)
return Scrobble.create_or_update_for_track(track, user_id, scrobble_dict)
def jellyfin_scrobble_video(data_dict: dict, user_id: Optional[int]):
if not data_dict.get("Provider_imdb", None):
logger.error(
"No IMDB ID received. This is likely because all metadata is bad, not scrobbling"
)
return
video = Video.find_or_create(data_dict)
scrobble_dict = create_jellyfin_scrobble_dict(data_dict, user_id)
return Scrobble.create_or_update_for_video(video, user_id, scrobble_dict)