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
|