import sqlite3 from flask import Flask, render_template_string, redirect from datetime import datetime import os import json import requests import re from collections import defaultdict app = Flask(__name__) def is_youtube_id(videoid): return re.match(r'^[a-zA-Z0-9_-]{11}$', videoid) is not None def get_db_values(url="https://halhadus.rocks/assets/localwrapped/music.db"): if not os.path.exists("/var/www/swingmusic/.swingmusic/music.db"): try: download = requests.get(url) with open("/var/www/swingmusic/.swingmusic/music.db", "wb") as f: f.write(download.content) except: print("Could not download the database.") exit() def extract_filename(filepath): return os.path.basename(filepath) def get_scrobbles(): get_db_values() swing_conn = sqlite3.connect('/var/www/swingmusic/.swingmusic/swingmusic.db') swing_cursor = swing_conn.cursor() swing_cursor.execute('SELECT timestamp, duration, extra FROM scrobble ORDER BY timestamp DESC') scrobbles = swing_cursor.fetchall() swing_conn.close() music_conn = sqlite3.connect('/var/www/swingmusic/.swingmusic/music.db') music_cursor = music_conn.cursor() music_cursor.execute('SELECT listmusicname, listvideoid, filelocation FROM music') music_data = {extract_filename(row[2]): (row[0], row[1]) for row in music_cursor.fetchall()} music_conn.close() total_durations = defaultdict(int) enriched_data = [] for ts, duration, extra_json in scrobbles: try: extra = json.loads(extra_json.replace("'", '"')) filepath = extra.get("filepath", "") filename = extract_filename(filepath) if filename in music_data: title, videoid = music_data[filename] total_durations[(title, videoid)] += duration enriched_data.append({ 'title': title, 'videoid': videoid, 'duration': duration, 'timestamp': ts }) except json.JSONDecodeError: continue unique_tracks = {} for track in enriched_data: key = (track['title'], track['videoid']) if key not in unique_tracks: unique_tracks[key] = { 'title': track['title'], 'videoid': track['videoid'], 'total_duration': total_durations[key], 'last_played': track['timestamp'] } return sorted(unique_tracks.values(), key=lambda x: x['total_duration'], reverse=True) @app.route('/swingmusicwrapped.html') def swing_history(): tracks = get_scrobbles() return render_template_string('''
Cover | Song | Total Play Time | Last Play Date | Play |
---|---|---|---|---|
{% if is_youtube(track.videoid) %}
![]()
N/A
{% endif %}
|
{{ track.title }} | {{ (track.total_duration // 3600)|int }}h {{ ((track.total_duration % 3600) // 60)|int }}m | {{ datetime.fromtimestamp(track.last_played).strftime('%Y-%m-%d %H:%M') }} | ▶ YT Music |