From 2914f3838e2bb34cdaa13a968b6ecc2b1b93613d Mon Sep 17 00:00:00 2001 From: Robert Roos Date: Thu, 13 Jun 2024 23:56:06 +0200 Subject: [PATCH] Inserting new records/updating existing, evaluating if new listen The code has been updated to do a check if the song from YouTube Music history has been played today, if no a new local record is created and song scrobbled to Last.fm. If yes the local record is updated if the position in the array the song was found in is less than before then scrobbled to Last.fm. This makes it possible to track songs being played multiple times a day. The code should work both if you want to scrobble only e.g. once per day, or (recommended) with a 3-5 minute intervall. --- start.py | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/start.py b/start.py index 00130cc..5ce6629 100644 --- a/start.py +++ b/start.py @@ -53,7 +53,8 @@ def __init__(self): track_name TEXT, artist_name TEXT, album_name TEXT, - scrobbled_at TEXT DEFAULT CURRENT_TIMESTAMP + scrobbled_at TEXT DEFAULT CURRENT_TIMESTAMP, + array_position INTEGER ) ''') self.conn.commit() @@ -103,26 +104,48 @@ def execute(self): history = ytmusic.get_history() i = 0 cursor = self.conn.cursor() - for item in history: + for index, item in enumerate(history): if item["played"] == "Today": record = { "artistName": item["artists"][0]["name"], "trackName": item["title"], "ts": self.formatted_date, "albumName": item["album"]["name"] if "album" in item and item["album"] is not None else None, + "arrayPosition": index, } if record["artistName"].endswith(" - Topic"): continue if record["albumName"] is None: record["albumName"] = record["trackName"] + scroble = cursor.execute( 'SELECT * FROM scrobbles WHERE track_name = :trackName AND artist_name = :artistName AND album_name = :albumName', { "trackName": record["trackName"], "artistName": record["artistName"], "albumName": record["albumName"] }).fetchone() - if scroble: + + if scroble is None: + # No existing record, insert a new one + cursor.execute(''' + INSERT INTO scrobbles (track_name, artist_name, album_name, scrobbled_at, array_position) + VALUES (:trackName, :artistName, :albumName, :ts, :arrayPosition) + ''', record) + self.conn.commit() + print(f"Inserted new scrobble for {record['trackName']} by {record['artistName']}.") + elif scroble[5] > record["arrayPosition"]: + # Existing record found and needs to be updated + cursor.execute(''' + UPDATE scrobbles + SET scrobbled_at = :ts, array_position = :arrayPosition + WHERE track_name = :trackName AND artist_name = :artistName AND album_name = :albumName + ''', record) + self.conn.commit() + print(f"Updated scrobble for {record['trackName']} by {record['artistName']} with new array position.") + else: + # Existing record found and no update is needed continue + xml_response = lastpy.scrobble( record["trackName"], record["artistName"], @@ -135,21 +158,16 @@ def execute(self): accepted = scrobbles.get('accepted') ignored = scrobbles.get('ignored') if accepted == '0' and ignored == '1': - print("Error scrobbling " + record["trackName"] + - " by " + record["artistName"] + ".") + print(f"Error scrobbling {record['trackName']} by {record['artistName']}.") print(xml_response) else: - cursor.execute(''' - INSERT INTO scrobbles (track_name, artist_name, album_name, scrobbled_at) - VALUES (:trackName, :artistName, :albumName, :ts) - ''', record) - self.conn.commit() i += 1 - print("Scrobbled " + str(i) + " songs") + + print(f"Scrobbled {i} songs") cursor.close() self.conn.close() if __name__ == '__main__': - Process().execute() + Process().execute() \ No newline at end of file