fix and improve songs dashboard

This commit is contained in:
lelo 2025-05-10 19:49:57 +02:00
parent bdb4710f0c
commit 9971671688
2 changed files with 75 additions and 52 deletions

View File

@ -12,11 +12,8 @@ file_access_temp = []
app_config = auth.return_app_config() app_config = auth.return_app_config()
# Example database name; you can change to whatever you want:
DB_NAME = 'access_log.db'
# Create a single global connection to SQLite # Create a single global connection to SQLite
log_db = sqlite3.connect(DB_NAME, check_same_thread=False) log_db = sqlite3.connect("access_log.db", check_same_thread=False)
search_db = sqlite3.connect("search.db", check_same_thread=False) search_db = sqlite3.connect("search.db", check_same_thread=False)
# geo location # geo location
@ -144,6 +141,7 @@ def return_file_access():
return [] return []
def songs_dashboard(): def songs_dashboard():
# — SESSION & PARAM HANDLING (unchanged) —
if 'songs_dashboard_timeframe' not in session: if 'songs_dashboard_timeframe' not in session:
session['songs_dashboard_timeframe'] = "30" session['songs_dashboard_timeframe'] = "30"
timeframe_param = request.args.get("timeframe", session['songs_dashboard_timeframe']) timeframe_param = request.args.get("timeframe", session['songs_dashboard_timeframe'])
@ -159,50 +157,73 @@ def songs_dashboard():
site = request.args.get("site", session['songs_dashboard_site']) site = request.args.get("site", session['songs_dashboard_site'])
session['songs_dashboard_site'] = site session['songs_dashboard_site'] = site
# Determine cutoff_date based on the days parameter # — DETERMINE CUTOFF + TODAY STRINGS —
if timeframe_param == "all":
cutoff_date = None # No date filtering when analyzing all time
timeframe = "all" # Pass the string to the template if needed
else:
timeframe = int(timeframe_param)
now = datetime.now() now = datetime.now()
cutoff_date = now - timedelta(days=timeframe) params = [category, site]
date_clauses = []
if timeframe_param != "all":
cutoff = now - timedelta(days=int(timeframe_param))
date_clauses.append("performance_date >= ?")
params.append(cutoff.strftime("%Y-%m-%d"))
# filter out any future-dated rows at the DB level
date_clauses.append("performance_date <= ?")
params.append(now.strftime("%Y-%m-%d"))
where_sql = " AND ".join(["category = ?", "site = ?"] + date_clauses)
cursor = search_db.cursor() cursor = search_db.cursor()
# Query rows with category "Gemeinsamer Gesang" cursor.execute(
query = "SELECT titel, performance_date FROM files WHERE category = ? and site = ?" f"SELECT titel, performance_date FROM files WHERE {where_sql}",
cursor.execute(query, (category, site)) params
)
rows = cursor.fetchall() rows = cursor.fetchall()
# Group and count performances per titel (only if performance_date is within the timeframe, # — AGGREGATE COUNTS + LAST-PERFORMED, WITH ERROR LOGGING —
# or count all if cutoff_date is None)
performance_counts = defaultdict(int) performance_counts = defaultdict(int)
for titel, performance_date in rows: last_performed_dates = {}
if performance_date:
try: for titel, perf_date_str in rows:
# Convert date from "dd.mm.yyyy" format if not perf_date_str:
date_obj = datetime.strptime(performance_date, "%d.%m.%Y")
except ValueError:
continue continue
# If cutoff_date is None, count all dates; otherwise, filter by cutoff_date.
if cutoff_date is None or date_obj >= cutoff_date: perf_date_str = perf_date_str.strip()
try:
perf_date = datetime.strptime(perf_date_str, "%Y-%m-%d")
except ValueError:
print(f"[songs_dashboard] bad date format for “{titel}”: “{perf_date_str}")
continue
performance_counts[titel] += 1 performance_counts[titel] += 1
# Create a list of tuples: (count, titel), sorted in descending order by count. prev = last_performed_dates.get(titel)
performance_data = [(count, titel) for titel, count in performance_counts.items()] if prev is None or perf_date > prev:
performance_data.sort(reverse=True, key=lambda x: x[0]) last_performed_dates[titel] = perf_date
title_short = app_config.get('TITLE_SHORT', 'Default Title') # — BUILD LIST FOR TEMPLATE —
title_long = app_config.get('TITLE_LONG' , 'Default Title') performance_data = []
for titel, count in performance_counts.items():
last_str = last_performed_dates[titel].strftime("%d.%m.%Y")
performance_data.append({
"titel": titel,
"count": count,
"last_performed": last_str
})
return render_template('songs_dashboard.html', performance_data.sort(key=lambda x: x["count"], reverse=True)
# — RENDER —
return render_template(
'songs_dashboard.html',
timeframe=timeframe_param, timeframe=timeframe_param,
performance_data=performance_data, performance_data=performance_data,
site=site, site=site,
category=category, category=category,
admin_enabled=auth.is_admin(), admin_enabled=auth.is_admin(),
title_short=title_short, title_short=app_config.get('TITLE_SHORT', 'Default Title'),
title_long=title_long) title_long= app_config.get('TITLE_LONG', 'Default Title'),
)
@require_secret @require_secret
def connections(): def connections():

View File

@ -134,13 +134,15 @@
<tr> <tr>
<th>Anzahl</th> <th>Anzahl</th>
<th>Titel</th> <th>Titel</th>
<th>Zuletzt gesungen</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for count, titel in performance_data %} {% for item in performance_data %}
<tr> <tr>
<td>{{ count }}</td> <td>{{ item['count'] }}</td>
<td>{{ titel }}</td> <td>{{ item['titel'] }}</td>
<td>{{ item['last_performed'] }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>