diff --git a/maloja/apis/native_v1.py b/maloja/apis/native_v1.py index 1fd5a77..48cb2f5 100644 --- a/maloja/apis/native_v1.py +++ b/maloja/apis/native_v1.py @@ -677,3 +677,9 @@ def merge_artists(target_id,source_ids): return { "status":"success" } + +@api.post("reparse_scrobble") +@authenticated_function(api=True) +def reparse_scrobble(timestamp): + """Internal Use Only""" + database.reparse_scrobble(timestamp) \ No newline at end of file diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index 5b56455..98b1ba1 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -102,7 +102,36 @@ def incoming_scrobble(rawscrobble,fix=True,client=None,api=None,dbconn=None): log(f"Incoming scrobble [Client: {client} | API: {api}]: {rawscrobble}") - # raw scrobble to processed info + scrobbledict = rawscrobble_to_scrobbledict(rawscrobble, fix, client); + + sqldb.add_scrobble(scrobbledict,dbconn=dbconn) + proxy_scrobble_all(scrobbledict['track']['artists'],scrobbledict['track']['title'],scrobbledict['time']) + + dbcache.invalidate_caches(scrobbledict['time']) + + #return {"status":"success","scrobble":scrobbledict} + return scrobbledict + + +@waitfordb +def reparse_scrobble(timestamp): + log(f"Reparsing Scrobble {timestamp}") + scrobble = sqldb.get_scrobble(timestamp=timestamp, include_internal=True) + + if not scrobble or not scrobble['rawscrobble']: + return + + scrobbledict = rawscrobble_to_scrobbledict(scrobble['rawscrobble']) + + track_id = sqldb.get_track_id(scrobbledict['track']) + + # check if id changed + if sqldb.get_track_id(scrobble['track']) != track_id: + sqldb.update_scrobble_track_id(timestamp, track_id) + + +def rawscrobble_to_scrobbledict(rawscrobble, fix=True, client=None): + # raw scrobble to processed info scrobbleinfo = {**rawscrobble} if fix: scrobbleinfo['track_artists'],scrobbleinfo['track_title'] = cla.fullclean(scrobbleinfo['track_artists'],scrobbleinfo['track_title']) @@ -129,17 +158,9 @@ def incoming_scrobble(rawscrobble,fix=True,client=None,api=None,dbconn=None): "rawscrobble":rawscrobble } - - sqldb.add_scrobble(scrobbledict,dbconn=dbconn) - proxy_scrobble_all(scrobbledict['track']['artists'],scrobbledict['track']['title'],scrobbledict['time']) - - dbcache.invalidate_caches(scrobbledict['time']) - - #return {"status":"success","scrobble":scrobbledict} return scrobbledict - @waitfordb def remove_scrobble(timestamp): log(f"Deleting Scrobble {timestamp}") @@ -203,6 +224,7 @@ def get_scrobbles(dbconn=None,**keys): #return result[keys['page']*keys['perpage']:(keys['page']+1)*keys['perpage']] return list(reversed(result)) + @waitfordb def get_scrobbles_num(dbconn=None,**keys): (since,to) = keys.get('timerange').timestamps() diff --git a/maloja/database/sqldb.py b/maloja/database/sqldb.py index 516c63b..7b0150e 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -280,6 +280,17 @@ def delete_scrobble(scrobble_id,dbconn=None): return True +@connection_provider +def update_scrobble_track_id(scrobble_id, track_id, dbconn=None): + + with SCROBBLE_LOCK: + + op = DB['scrobbles'].update().where( + DB['scrobbles'].c.timestamp == scrobble_id + ).values(track_id=track_id) + + dbconn.execute(op) + ### these will 'get' the ID of an entity, creating it if necessary @cached_wrapper @@ -776,7 +787,16 @@ def get_artist(id,dbconn=None): return artist_db_to_dict(artistinfo,dbconn=dbconn) +@cached_wrapper +@connection_provider +def get_scrobble(timestamp, include_internal=False, dbconn=None): + op = DB['scrobbles'].select().where( + DB['scrobbles'].c.timestamp==timestamp + ) + result = dbconn.execute(op).all() + scrobble = result[0] + return scrobbles_db_to_dict(rows=[scrobble], include_internal=include_internal)[0] ##### MAINTENANCE diff --git a/maloja/web/jinja/partials/scrobbles.jinja b/maloja/web/jinja/partials/scrobbles.jinja index 1fb1cbd..baeac8a 100644 --- a/maloja/web/jinja/partials/scrobbles.jinja +++ b/maloja/web/jinja/partials/scrobbles.jinja @@ -17,6 +17,22 @@ {{ entityrow.row(s.track) }} {% if adminmode %} +