Fix lastfm importing
This commit is contained in:
@ -11,15 +11,21 @@ logger = logging.getLogger(__name__)
|
||||
from music.models import Artist, Album, Track
|
||||
|
||||
|
||||
def get_or_create_artist(name: str) -> Artist:
|
||||
artist, artist_created = Artist.objects.get_or_create(name=name)
|
||||
if artist_created:
|
||||
def get_or_create_artist(name: str, mbid: str = None) -> Artist:
|
||||
if mbid:
|
||||
artist, artist_created = Artist.objects.get_or_create(
|
||||
name=name, musicbrainz_id=mbid
|
||||
)
|
||||
else:
|
||||
artist, 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"])
|
||||
return artist
|
||||
|
||||
|
||||
def get_or_create_album(name: str, artist: Artist) -> Album:
|
||||
def get_or_create_album(name: str, artist: Artist, mbid: str = None) -> Album:
|
||||
album = None
|
||||
album_created = False
|
||||
albums = Album.objects.filter(name__iexact=name)
|
||||
@ -31,11 +37,11 @@ def get_or_create_album(name: str, artist: Artist) -> Album:
|
||||
album = potential_album
|
||||
if not album:
|
||||
album_created = True
|
||||
album = Album.objects.create(name=name)
|
||||
album = Album.objects.create(name=name, musicbrainz_id=mbid)
|
||||
album.save()
|
||||
album.artists.add(artist)
|
||||
|
||||
if album_created:
|
||||
if album_created or not mbid:
|
||||
album_dict = lookup_album_dict_from_mb(
|
||||
album.name, artist_name=artist.name
|
||||
)
|
||||
|
||||
@ -5,6 +5,7 @@ from datetime import datetime, timedelta
|
||||
import pylast
|
||||
import pytz
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from music.utils import (
|
||||
get_or_create_album,
|
||||
get_or_create_artist,
|
||||
@ -71,8 +72,8 @@ class LastFM:
|
||||
ten_seconds_eariler = timestamp - timedelta(seconds=15)
|
||||
ten_seconds_later = timestamp + timedelta(seconds=15)
|
||||
existing = Scrobble.objects.filter(
|
||||
created__gte=ten_seconds_eariler,
|
||||
created__lte=ten_seconds_later,
|
||||
timestamp__gte=ten_seconds_eariler,
|
||||
timestamp__lte=ten_seconds_later,
|
||||
track=track,
|
||||
).first()
|
||||
if existing:
|
||||
@ -112,32 +113,42 @@ class LastFM:
|
||||
def get_last_scrobbles(self, time_from=None, time_to=None):
|
||||
"""Given a user, Last.fm api key, and secret key, grab a list of scrobbled
|
||||
tracks"""
|
||||
lfm_params = {}
|
||||
scrobbles = []
|
||||
if time_from:
|
||||
time_from = int(time_from.timestamp())
|
||||
lfm_params["time_from"] = int(time_from.timestamp())
|
||||
if time_to:
|
||||
time_to = int(time_to.timestamp())
|
||||
lfm_params["time_to"] = int(time_to.timestamp())
|
||||
|
||||
# if not time_from and not time_to:
|
||||
lfm_params['limit'] = None
|
||||
|
||||
found_scrobbles = self.user.get_recent_tracks(**lfm_params)
|
||||
|
||||
if not time_from and not time_to:
|
||||
found_scrobbles = self.user.get_recent_tracks(limit=None)
|
||||
else:
|
||||
found_scrobbles = self.user.get_recent_tracks(
|
||||
time_from=time_from, time_to=time_to
|
||||
)
|
||||
for scrobble in found_scrobbles:
|
||||
run_time_ticks = scrobble.track.get_duration()
|
||||
run_time = run_time_ticks / 1000
|
||||
try:
|
||||
run_time_ticks = scrobble.track.get_duration()
|
||||
run_time = int(run_time_ticks / 1000)
|
||||
except pylast.MalformedResponseError:
|
||||
run_time_ticks = None
|
||||
run_time = None
|
||||
logger.warn(f"Track {scrobble.track} has no duration")
|
||||
|
||||
timestamp = datetime.utcfromtimestamp(
|
||||
int(scrobble.timestamp)
|
||||
).replace(tzinfo=pytz.utc)
|
||||
artist = scrobble.track.get_artist().name
|
||||
|
||||
logger.debug(f"{artist},{scrobble.track.title},{timestamp}")
|
||||
scrobbles.append(
|
||||
{
|
||||
"artist": scrobble.track.get_artist().name,
|
||||
"artist": artist,
|
||||
"album": scrobble.album,
|
||||
"title": scrobble.track.title,
|
||||
"mbid": scrobble.track.get_mbid(),
|
||||
"run_time": int(run_time),
|
||||
"run_time": run_time,
|
||||
"run_time_ticks": run_time_ticks,
|
||||
"timestamp": datetime.utcfromtimestamp(
|
||||
int(scrobble.timestamp)
|
||||
).replace(tzinfo=pytz.utc),
|
||||
"timestamp": timestamp,
|
||||
}
|
||||
)
|
||||
return scrobbles
|
||||
|
||||
@ -62,9 +62,12 @@ def lookup_album_dict_from_mb(release_name: str, artist_name: str) -> dict:
|
||||
extra={"result": top_result},
|
||||
)
|
||||
return {}
|
||||
print(top_result)
|
||||
year = None
|
||||
if top_result.get("date"):
|
||||
year = parse(top_result["date"]).year
|
||||
|
||||
return {
|
||||
"year": parse(top_result["date"]).year,
|
||||
"year": year,
|
||||
"mb_id": top_result["id"],
|
||||
"mb_group_id": top_result["release-group"]["id"],
|
||||
}
|
||||
|
||||
@ -10,6 +10,11 @@ from scrobbles.models import Scrobble
|
||||
from scrobbles.utils import convert_to_seconds, parse_mopidy_uri
|
||||
from videos.models import Video
|
||||
from sports.models import SportEvent
|
||||
from vrobbler.apps.music.utils import (
|
||||
get_or_create_album,
|
||||
get_or_create_artist,
|
||||
get_or_create_track,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -57,23 +62,23 @@ def mopidy_scrobble_podcast(
|
||||
def mopidy_scrobble_track(
|
||||
data_dict: dict, user_id: Optional[int]
|
||||
) -> Optional[Scrobble]:
|
||||
artist_dict = {
|
||||
"name": data_dict.get("artist", None),
|
||||
"musicbrainz_id": data_dict.get("musicbrainz_artist_id", None),
|
||||
}
|
||||
|
||||
album_dict = {
|
||||
"name": data_dict.get("album"),
|
||||
"musicbrainz_id": data_dict.get("musicbrainz_album_id"),
|
||||
}
|
||||
|
||||
track_dict = {
|
||||
"title": data_dict.get("name"),
|
||||
"run_time_ticks": data_dict.get("run_time_ticks"),
|
||||
"run_time": data_dict.get("run_time"),
|
||||
}
|
||||
|
||||
track = Track.find_or_create(artist_dict, album_dict, track_dict)
|
||||
artist = get_or_create_artist(
|
||||
data_dict.get("artist"),
|
||||
mbid=data_dict.get("musicbrainz_artist_id", None),
|
||||
)
|
||||
album = get_or_create_album(
|
||||
data_dict.get("album"),
|
||||
artist=artist,
|
||||
mbid=data_dict.get("musicbrainz_album_id"),
|
||||
)
|
||||
track = get_or_create_track(
|
||||
title=data_dict.get("name"),
|
||||
mbid=data_dict.get("musicbrainz_track_id"),
|
||||
artist=artist,
|
||||
album=album,
|
||||
run_time_ticks=data_dict.get("run_time_ticks"),
|
||||
run_time=data_dict.get("run_time"),
|
||||
)
|
||||
|
||||
# Now we run off a scrobble
|
||||
mopidy_data = {
|
||||
@ -136,38 +141,30 @@ def jellyfin_scrobble_track(
|
||||
logger.error("No playback position tick from Jellyfin, aborting")
|
||||
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
|
||||
),
|
||||
}
|
||||
artist = get_or_create_artist(
|
||||
data_dict.get(JELLYFIN_POST_KEYS["ARTIST_NAME"]),
|
||||
mbid=data_dict.get(JELLYFIN_POST_KEYS["ARTIST_MB_ID"]),
|
||||
)
|
||||
album = get_or_create_album(
|
||||
data_dict.get(JELLYFIN_POST_KEYS["ALBUM_NAME"]),
|
||||
artist=artist,
|
||||
mbid=data_dict.get(JELLYFIN_POST_KEYS['ALBUM_MB_ID']),
|
||||
)
|
||||
|
||||
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()
|
||||
run_time_ticks = (
|
||||
data_dict.get(JELLYFIN_POST_KEYS["RUN_TIME_TICKS"]) // 10000
|
||||
)
|
||||
run_time = convert_to_seconds(
|
||||
data_dict.get(JELLYFIN_POST_KEYS["RUN_TIME"])
|
||||
)
|
||||
track = get_or_create_track(
|
||||
title=data_dict.get("Name"),
|
||||
mbid=data_dict.get(JELLYFIN_POST_KEYS["TRACK_MB_ID"]),
|
||||
artist=artist,
|
||||
album=album,
|
||||
run_time_ticks=run_time_ticks,
|
||||
run_time=run_time,
|
||||
)
|
||||
|
||||
scrobble_dict = build_scrobble_dict(data_dict, user_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user