From b525252af1249c6c11c2b6d43f4fe813863ddb99 Mon Sep 17 00:00:00 2001 From: alim4r <7687869+alim4r@users.noreply.github.com> Date: Wed, 20 Apr 2022 15:59:33 +0200 Subject: [PATCH 1/4] Add reparse scrobble feature --- maloja/apis/native_v1.py | 6 ++++ maloja/database/__init__.py | 38 +++++++++++++++++------ maloja/database/sqldb.py | 20 ++++++++++++ maloja/web/jinja/partials/scrobbles.jinja | 16 ++++++++++ maloja/web/static/js/edit.js | 9 ++++++ 5 files changed, 80 insertions(+), 9 deletions(-) diff --git a/maloja/apis/native_v1.py b/maloja/apis/native_v1.py index 1d7f232..7b56a05 100644 --- a/maloja/apis/native_v1.py +++ b/maloja/apis/native_v1.py @@ -589,3 +589,9 @@ def get_export(**keys): def delete_scrobble(timestamp): """Internal Use Only""" database.remove_scrobble(timestamp) + +@api.post("reparse_scrobble") +@authenticated_function(api=True) +def reparse_scrobble(timestamp): + """Internal Use Only""" + database.reparse_scrobble(timestamp) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index d83c8f3..ba3499f 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -102,7 +102,35 @@ 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) + + if not scrobble: + 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 +157,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}") diff --git a/maloja/database/sqldb.py b/maloja/database/sqldb.py index 1623d57..8888587 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -277,6 +277,17 @@ def delete_scrobble(scrobble_id,dbconn=None): dbconn.execute(op) +@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 @@ -691,7 +702,16 @@ def get_artist(id,dbconn=None): return artist_db_to_dict(artistinfo) +@cached_wrapper +@connection_provider +def get_scrobble(timestamp,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([scrobble], True)[0] ##### MAINTENANCE diff --git a/maloja/web/jinja/partials/scrobbles.jinja b/maloja/web/jinja/partials/scrobbles.jinja index 1fb1cbd..9fac4d0 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 %} + + + + + + + +
+ + + +
+
+ + + diff --git a/maloja/web/static/js/edit.js b/maloja/web/static/js/edit.js index 0a415ba..8e0ef16 100644 --- a/maloja/web/static/js/edit.js +++ b/maloja/web/static/js/edit.js @@ -10,3 +10,12 @@ function deleteScrobble(id,element) { neo.xhttpreq("/apis/mlj_1/delete_scrobble",data={'timestamp':id},method="POST",callback=(()=>null),json=true); } + +function toggleReparseConfirm(element) { + element.parentElement.parentElement.classList.toggle('active'); +} + +function reparseScrobble(id) { + neo.xhttpreq("/apis/mlj_1/reparse_scrobble",data={'timestamp':id},method="POST",callback=(()=>null),json=true); + +} From c457b58ab8e1792fa2c1eb8f82dd5e850c6f9c9f Mon Sep 17 00:00:00 2001 From: alim4r <7687869+alim4r@users.noreply.github.com> Date: Wed, 20 Apr 2022 20:18:28 +0200 Subject: [PATCH 2/4] Quick fix for reparse confirmation & button placement --- maloja/web/jinja/partials/scrobbles.jinja | 6 +++--- maloja/web/static/css/maloja.css | 4 ++++ maloja/web/static/js/edit.js | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/maloja/web/jinja/partials/scrobbles.jinja b/maloja/web/jinja/partials/scrobbles.jinja index 9fac4d0..baeac8a 100644 --- a/maloja/web/jinja/partials/scrobbles.jinja +++ b/maloja/web/jinja/partials/scrobbles.jinja @@ -17,14 +17,14 @@ {{ entityrow.row(s.track) }} {% if adminmode %} - + - + -
+
diff --git a/maloja/web/static/css/maloja.css b/maloja/web/static/css/maloja.css index badbeb9..eaaf7f8 100644 --- a/maloja/web/static/css/maloja.css +++ b/maloja/web/static/css/maloja.css @@ -612,6 +612,10 @@ table.list td.searchProvider:hover { table.list td.delete_area { text-align: right; + width:0em; +} + +table.list td.delete_area.active { width:7em; } diff --git a/maloja/web/static/js/edit.js b/maloja/web/static/js/edit.js index 8e0ef16..6ce1c60 100644 --- a/maloja/web/static/js/edit.js +++ b/maloja/web/static/js/edit.js @@ -15,7 +15,9 @@ function toggleReparseConfirm(element) { element.parentElement.parentElement.classList.toggle('active'); } -function reparseScrobble(id) { +function reparseScrobble(id, element) { + toggleReparseConfirm(element); + neo.xhttpreq("/apis/mlj_1/reparse_scrobble",data={'timestamp':id},method="POST",callback=(()=>null),json=true); } From 85bb1f36ccb2c030cef2eeeee5473187accd6142 Mon Sep 17 00:00:00 2001 From: alim4r <7687869+alim4r@users.noreply.github.com> Date: Wed, 20 Apr 2022 21:48:41 +0200 Subject: [PATCH 3/4] Ignore scrobbles without a rawscrobble --- maloja/database/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index ba3499f..f8e1d5e 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -117,7 +117,7 @@ def reparse_scrobble(timestamp): log(f"Reparsing Scrobble {timestamp}") scrobble = sqldb.get_scrobble(timestamp) - if not scrobble: + if not scrobble or not scrobble['rawscrobble']: return scrobbledict = rawscrobble_to_scrobbledict(scrobble['rawscrobble']) From 6893fd745ad5ed65c1bf6121ed873c95cfeaf98e Mon Sep 17 00:00:00 2001 From: alim4r <7687869+alim4r@users.noreply.github.com> Date: Thu, 21 Apr 2022 18:28:59 +0200 Subject: [PATCH 4/4] Update get_scrobble parameters --- maloja/database/__init__.py | 4 +++- maloja/database/sqldb.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/maloja/database/__init__.py b/maloja/database/__init__.py index f8e1d5e..e50eaed 100644 --- a/maloja/database/__init__.py +++ b/maloja/database/__init__.py @@ -112,10 +112,11 @@ def incoming_scrobble(rawscrobble,fix=True,client=None,api=None,dbconn=None): #return {"status":"success","scrobble":scrobbledict} return scrobbledict + @waitfordb def reparse_scrobble(timestamp): log(f"Reparsing Scrobble {timestamp}") - scrobble = sqldb.get_scrobble(timestamp) + scrobble = sqldb.get_scrobble(timestamp=timestamp, include_internal=True) if not scrobble or not scrobble['rawscrobble']: return @@ -185,6 +186,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 8888587..be27292 100644 --- a/maloja/database/sqldb.py +++ b/maloja/database/sqldb.py @@ -704,14 +704,14 @@ def get_artist(id,dbconn=None): @cached_wrapper @connection_provider -def get_scrobble(timestamp,dbconn=None): +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([scrobble], True)[0] + return scrobbles_db_to_dict(rows=[scrobble], include_internal=include_internal)[0] ##### MAINTENANCE