From 9efdf90312842e23a3076a2e61612aad27801524 Mon Sep 17 00:00:00 2001 From: krateng Date: Sun, 5 May 2024 18:37:46 +0200 Subject: [PATCH] Add import for ghan64 last.fm exporter, GH-339 --- README.md | 2 +- maloja/proccontrol/tasks/import_scrobbles.py | 58 +++++++++++++++----- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d1fb4dd..d78ad5d 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ When not running in a container, you can run the application with `maloja run`. If you would like to import your previous scrobbles, use the command `maloja import *filename*`. This works on: -* a Last.fm export generated by [benfoxall's website](https://benjaminbenben.com/lastfm-to-csv/) ([GitHub page](https://github.com/benfoxall/lastfm-to-csv)) +* a Last.fm export generated by [ghan64's website](https://lastfm.ghan.nl/export/) * an official [Spotify data export file](https://www.spotify.com/us/account/privacy/) * an official [ListenBrainz export file](https://listenbrainz.org/profile/export/) * the export of another Maloja instance diff --git a/maloja/proccontrol/tasks/import_scrobbles.py b/maloja/proccontrol/tasks/import_scrobbles.py index 986b86f..1c828e9 100644 --- a/maloja/proccontrol/tasks/import_scrobbles.py +++ b/maloja/proccontrol/tasks/import_scrobbles.py @@ -35,35 +35,39 @@ def import_scrobbles(inputf): importfunc = None - if re.match(r".*\.csv",filename): - typeid,typedesc = "lastfm","Last.fm" + if re.match(r".*\.csv", filename): + typeid,typedesc = "lastfm", "Last.fm (benjaminbenben export)" importfunc = parse_lastfm - elif re.match(r"Streaming_History_Audio.+\.json",filename): - typeid,typedesc = "spotify","Spotify" + elif re.match(r"Streaming_History_Audio.+\.json", filename): + typeid,typedesc = "spotify", "Spotify" importfunc = parse_spotify_lite - elif re.match(r"endsong_[0-9]+\.json",filename): - typeid,typedesc = "spotify","Spotify" + elif re.match(r"endsong_[0-9]+\.json", filename): + typeid,typedesc = "spotify", "Spotify" importfunc = parse_spotify - elif re.match(r"StreamingHistory[0-9]+\.json",filename): - typeid,typedesc = "spotify","Spotify" + elif re.match(r"StreamingHistory[0-9]+\.json", filename): + typeid,typedesc = "spotify", "Spotify" importfunc = parse_spotify_lite_legacy - elif re.match(r"maloja_export[_0-9]*\.json",filename): - typeid,typedesc = "maloja","Maloja" + elif re.match(r"maloja_export[_0-9]*\.json", filename): + typeid,typedesc = "maloja", "Maloja" importfunc = parse_maloja # username_lb-YYYY-MM-DD.json - elif re.match(r".*_lb-[0-9-]+\.json",filename): - typeid,typedesc = "listenbrainz","ListenBrainz" + elif re.match(r".*_lb-[0-9-]+\.json", filename): + typeid,typedesc = "listenbrainz", "ListenBrainz" importfunc = parse_listenbrainz - elif re.match(r"\.scrobbler\.log",filename): - typeid,typedesc = "rockbox","Rockbox" + elif re.match(r"\.scrobbler\.log", filename): + typeid,typedesc = "rockbox", "Rockbox" importfunc = parse_rockbox + elif re.match(r"recenttracks-.*\.json", filename): + typeid, typedesc = "lastfm", "Last.fm (ghan export)" + importfunc = parse_lastfm_ghan + elif re.match(r".*\.json",filename): try: with open(filename,'r') as fd: @@ -143,6 +147,7 @@ def import_scrobbles(inputf): return result + def parse_spotify_lite_legacy(inputf): pth = os.path # use absolute paths internally for peace of mind. just change representation for console output @@ -255,6 +260,7 @@ def parse_spotify_lite(inputf): print() + def parse_spotify(inputf): pth = os.path # use absolute paths internally for peace of mind. just change representation for console output @@ -366,6 +372,7 @@ def parse_spotify(inputf): print() + def parse_lastfm(inputf): with open(inputf,'r',newline='') as inputfd: @@ -400,6 +407,29 @@ def parse_lastfm(inputf): yield ('FAIL',None,f"{row} (Line {line}) could not be parsed. Scrobble not imported. ({repr(e)})") continue + +def parse_lastfm_ghan(inputf): + with open(inputf, 'r') as inputfd: + data = json.load(inputfd) + + skip = 50000 + for entry in data: + for track in entry['track']: + skip -= 1 + #if skip: continue + #print(track) + #input() + + yield ('CONFIDENT_IMPORT', { + 'track_title': track['name'], + 'track_artists': track['artist']['#text'], + 'track_length': None, + 'album_name': track['album']['#text'], + 'scrobble_time': int(track['date']['uts']), + 'scrobble_duration': None + }, '') + + def parse_listenbrainz(inputf): with open(inputf,'r') as inputfd: