add today function

This commit is contained in:
lelo 2025-05-20 18:46:43 +00:00
parent a0f972f38a
commit 83bb62ad32
4 changed files with 120 additions and 14 deletions

View File

@ -7,8 +7,10 @@ from collections import defaultdict
import json import json
import os import os
import auth import auth
import helperfunctions as hf
file_access_temp = [] file_access_temp = []
folder_today = []
app_config = auth.return_app_config() app_config = auth.return_app_config()
@ -98,11 +100,13 @@ def parse_timestamp(ts_str):
raise raise
def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id, cached): def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id, cached):
"""Insert a file access record into the database and prune entries older than 10 minutes.""" """Insert a file access record into the database and prune entries older than 10 minutes,
global file_access_temp and track todays files separately in folder_today."""
# Create a timezone-aware timestamp (local time with offset) global file_access_temp, folder_today
timestamp = datetime.now(timezone.utc).astimezone()
iso_ts = timestamp.isoformat() # Create a timezone-aware timestamp
now = datetime.now(timezone.utc).astimezone()
iso_ts = now.isoformat()
# Convert the IP address to a location # Convert the IP address to a location
city, country = lookup_location(ip_address) city, country = lookup_location(ip_address)
@ -114,17 +118,46 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (iso_ts, rel_path, filesize, mime, city, country, user_agent, device_id, cached)) ''', (iso_ts, rel_path, filesize, mime, city, country, user_agent, device_id, cached))
# Remove entries older than 10 minutes using our robust parser. # Prune temp entries older than 10 minutes
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10) cutoff = now - timedelta(minutes=10)
file_access_temp[:] = [ file_access_temp[:] = [
entry for entry in file_access_temp entry for entry in file_access_temp
if parse_timestamp(entry[0]) >= cutoff_time if parse_timestamp(entry[0]) >= cutoff
] ]
# Add the new entry at the beginning of the list # Keep only today's entries in folder_today
file_access_temp.insert(0, [iso_ts, rel_path, filesize, mime, f"{city}, {country}", user_agent, device_id, cached]) date_str = iso_ts.split('T', 1)[0]
folder_today[:] = [
entry for entry in folder_today
if entry['date_str'] == date_str
]
# If this new access is from today, record it
# Compare the helpers YYYY-MM-DD string to todays ISO date string
date_from_path = hf.extract_date_from_string(rel_path)
if date_from_path == date_str:
# get just the folder part (everything before the final '/')
folder_path = rel_path.rsplit('/', 1)[0] if '/' in rel_path else rel_path
# only append if that folder isn't already in folder_today
if not any(entry['rel_path'] == folder_path for entry in folder_today):
folder_today.append({'date_str': date_str, 'rel_path': folder_path})
# Finally, insert the new access at the top of the temp log
file_access_temp.insert(0, [
iso_ts,
rel_path,
filesize,
mime,
f"{city}, {country}",
user_agent,
device_id,
cached
])
return True return True
def return_file_access(): def return_file_access():
"""Return recent file access logs from memory (the last 10 minutes).""" """Return recent file access logs from memory (the last 10 minutes)."""
global file_access_temp global file_access_temp
@ -140,6 +173,14 @@ def return_file_access():
else: else:
return [] return []
def return_folder_today():
global folder_today
if folder_today:
return folder_today
else:
return []
def songs_dashboard(): def songs_dashboard():
# — SESSION & PARAM HANDLING (unchanged) — # — SESSION & PARAM HANDLING (unchanged) —
if 'songs_dashboard_timeframe' not in session: if 'songs_dashboard_timeframe' not in session:

20
app.py
View File

@ -23,6 +23,7 @@ import search
import auth import auth
import analytics as a import analytics as a
import folder_secret_config_editor as fsce import folder_secret_config_editor as fsce
import helperfunctions as hf
app_config = auth.return_app_config() app_config = auth.return_app_config()
BASE_DIR = os.path.realpath(app_config['BASE_DIR']) BASE_DIR = os.path.realpath(app_config['BASE_DIR'])
@ -243,6 +244,7 @@ def serve_sw():
@app.route('/api/path/<path:subpath>') @app.route('/api/path/<path:subpath>')
@auth.require_secret @auth.require_secret
def api_browse(subpath): def api_browse(subpath):
if subpath == '': # root directory if subpath == '': # root directory
foldernames = [] foldernames = []
for foldername, _ in session['folders'].items(): for foldername, _ in session['folders'].items():
@ -251,7 +253,20 @@ def api_browse(subpath):
return jsonify({ return jsonify({
'breadcrumbs': generate_breadcrumbs(), 'breadcrumbs': generate_breadcrumbs(),
'directories': foldernames, 'directories': foldernames,
'files': [] 'files': [],
'folder_today': a.return_folder_today()
})
if subpath == 'today':
foldernames = []
for item in a.return_folder_today():
foldernames.append({'name': item['rel_path'], 'path': item['rel_path']})
return jsonify({
'breadcrumbs': generate_breadcrumbs(),
'directories': foldernames,
'files': [],
'folder_today': []
}) })
root, *relative_parts = subpath.split('/') root, *relative_parts = subpath.split('/')
@ -283,7 +298,8 @@ def api_browse(subpath):
response = { response = {
'breadcrumbs': breadcrumbs, 'breadcrumbs': breadcrumbs,
'directories': directories, 'directories': directories,
'files': files 'files': files,
'folder_today': a.return_folder_today()
} }
# If a filename was selected include it. # If a filename was selected include it.

46
helperfunctions.py Normal file
View File

@ -0,0 +1,46 @@
from datetime import datetime
import re
def extract_date_from_string(string_with_date):
# grab X.Y.Z where X,Y,Z are 14 digits
m = re.search(r'(\d{1,4}\.\d{1,2}\.\d{1,4})', string_with_date)
if not m:
return None
date_str = m.group(1)
parts = date_str.split('.')
# 1) Unambiguous “last group = YYYY”
if len(parts) == 3 and len(parts[2]) == 4:
fmt = '%d.%m.%Y'
# 2) Unambiguous “first group = YYYY”
elif len(parts) == 3 and len(parts[0]) == 4:
fmt = '%Y.%m.%d'
# 3) Ambiguous “XX.XX.XX” → prefer DD.MM.YY, fallback to YY.MM.DD
elif len(parts) == 3 and all(len(p) == 2 for p in parts):
# try last-group-as-year first
try:
dt = datetime.strptime(date_str, '%d.%m.%y')
return dt.strftime('%Y-%m-%d')
except ValueError:
# fallback to first-group-as-year
fmt = '%y.%m.%d'
else:
# optional: handle ISO with dashes
if '-' in date_str:
try:
dt = datetime.strptime(date_str, '%Y-%m-%d')
return dt.strftime('%Y-%m-%d')
except ValueError:
return None
return None
# parse with whichever fmt we settled on
try:
dt = datetime.strptime(date_str, fmt)
return dt.strftime('%Y-%m-%d')
except ValueError:
return None

View File

@ -111,6 +111,9 @@ function renderContent(data) {
contentHTML += '</div>'; contentHTML += '</div>';
} else { } else {
contentHTML += '<ul>'; contentHTML += '<ul>';
if (data.breadcrumbs.length === 1 && Array.isArray(data.folder_today) && data.folder_today.length > 0) {
contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="today">📅 Heute</a></li>`;
}
data.directories.forEach(dir => { data.directories.forEach(dir => {
if (admin_enabled && data.breadcrumbs.length != 1 && dir.share) { if (admin_enabled && data.breadcrumbs.length != 1 && dir.share) {
share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`; share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`;