Compare commits

..

No commits in common. "f1ff833d89742026bb70ed19aff34ecf9af4ed5b" and "ef8655b886fa6910b2cf59a5dc3f8f2bd9dbe5c3" have entirely different histories.

3 changed files with 66 additions and 81 deletions

8
app.py
View File

@ -249,7 +249,6 @@ 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):
toplist_categories = app_config.get('toplist_categories', None)
if subpath == '': # root directory if subpath == '': # root directory
foldernames = [] foldernames = []
@ -261,8 +260,7 @@ def api_browse(subpath):
'directories': foldernames, 'directories': foldernames,
'files': [], 'files': [],
'folder_today': a.return_folder_today(), 'folder_today': a.return_folder_today(),
'folder_yesterday': a.return_folder_yesterday(), 'folder_yesterday': a.return_folder_yesterday()
'toplist_enabled': bool(toplist_categories)
}) })
if subpath == 'heute' or subpath == 'gestern': if subpath == 'heute' or subpath == 'gestern':
@ -287,11 +285,13 @@ def api_browse(subpath):
files = [] files = []
split_path = subpath.split('/') split_path = subpath.split('/')
valid_categories = ['Predigt', 'Erzählung', 'Gedicht', 'Gemeinsamer Gesang', 'Chor', 'Kinderchor', 'Jugendchor', 'Orchester', 'Instrumental', 'Gruppenlied']
if len(split_path) == 1 and split_path[0] == 'toplist': if len(split_path) == 1 and split_path[0] == 'toplist':
foldernames = [ foldernames = [
{ {
'name': categorie, 'path': 'toplist/' + categorie 'name': categorie, 'path': 'toplist/' + categorie
} for categorie in toplist_categories } for categorie in valid_categories
] ]
elif len(split_path) > 1 and split_path[0] == 'toplist': elif len(split_path) > 1 and split_path[0] == 'toplist':
files = hf.generate_top_list(split_path[1]) files = hf.generate_top_list(split_path[1])

View File

@ -1,71 +1,54 @@
from flask import session from flask import session
from datetime import datetime
import re import re
import os import os
import sqlite3 import sqlite3
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional
log_db = sqlite3.connect("access_log.db", check_same_thread=False) log_db = sqlite3.connect("access_log.db", check_same_thread=False)
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('.')
# Precompiled regex to find date-like patterns: either dotted X.Y.Z or ISO dashed YYYY-MM-DD # 1) Unambiguous “last group = YYYY”
_DATE_REGEX = re.compile( if len(parts) == 3 and len(parts[2]) == 4:
r"(" # start group fmt = '%d.%m.%Y'
r"\d{4}-\d{1,2}-\d{1,2}" # ISO: YYYY-M-D or YYYY-MM-DD
r"|" # or
r"\d{1,4}\.\d{1,2}\.\d{1,4}" # dotted: X.Y.Z, where each is 14 digits (year may be 14)
r")"
)
# 2) Unambiguous “first group = YYYY”
elif len(parts) == 3 and len(parts[0]) == 4:
fmt = '%Y.%m.%d'
def _try_parse(date_str: str, fmt: str) -> Optional[datetime]: # 3) Ambiguous “XX.XX.XX” → prefer DD.MM.YY, fallback to YY.MM.DD
"""Try to parse date_str with fmt, return datetime or None.""" elif len(parts) == 3 and all(len(p) == 2 for p in parts):
# try last-group-as-year first
try: try:
return datetime.strptime(date_str, fmt) 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: except ValueError:
return None return None
def extract_date_from_string(text: str) -> Optional[str]:
"""
Extract the first date-like substring from text and return it in ISO format (YYYY-MM-DD).
Supports:
- ISO-style dates with dashes (YYYY-M-D or YYYY-MM-DD)
- Dotted dates (DD.MM.YYYY, YYYY.MM.DD, DD.MM.YY, YY.MM.DD)
"""
match = _DATE_REGEX.search(text)
if not match:
return None return None
date_str = match.group(1) # parse with whichever fmt we settled on
try:
# 1) ISO dashed format takes priority dt = datetime.strptime(date_str, fmt)
if '-' in date_str:
dt = _try_parse(date_str, '%Y-%m-%d')
return dt.strftime('%Y-%m-%d') if dt else None
# 2) Dotted formats
parts = date_str.split('.')
candidates = []
# Unambiguous: last part 4 digits → DD.MM.YYYY
if len(parts) == 3 and len(parts[2]) == 4:
candidates.append('%d.%m.%Y')
# Unambiguous: first part 4 digits → YYYY.MM.DD
if len(parts) == 3 and len(parts[0]) == 4:
candidates.append('%Y.%m.%d')
# Ambiguous two-digit groups: try DD.MM.YY, then YY.MM.DD
if len(parts) == 3 and all(len(p) == 2 for p in parts):
candidates.extend(['%d.%m.%y', '%y.%m.%d'])
# Try each candidate
for fmt in candidates:
dt = _try_parse(date_str, fmt)
if dt:
return dt.strftime('%Y-%m-%d') return dt.strftime('%Y-%m-%d')
except ValueError:
# no valid parse
return None return None
@ -84,28 +67,30 @@ def extract_structure_from_string(input_string):
# first part not a number # first part not a number
pass pass
# define your mapping: category → list of trigger-words if 'predig' in left_side.lower() or 'thema' in left_side.lower():
CATEGORY_KEYWORDS = { category = 'Predigt'
'Predigt': ['predig', 'thema'], elif 'wort' in left_side.lower() or 'einladung' in left_side.lower() or 'begrüßung' in left_side.lower() or 'ansprache' in left_side.lower() or 'einleitung' in left_side.lower() or 'aufruf zum' in left_side.lower() or 'zuruf zum' in left_side.lower():
'Vorwort': ['wort', 'einladung', 'begrüßung', 'ansprache', 'einleitung', 'aufruf zum', 'zuruf zum'], category = 'Vorwort'
'Kinderchor': ['kinderchor'], elif 'kinderchor' in left_side.lower():
'Jugendchor': ['jugendchor'], category = 'Kinderchor'
'Orchester': ['orchester', 'sinfonie', 'symphonie'], elif 'jugendchor' in left_side.lower():
'Chor': ['chor'], category = 'Jugendchor'
'Gemeinsamer Gesang': ['gemeinsam', 'gemeindelied', 'gemeinsamer gesang'], elif 'orchester' in input_string.lower() or 'sinfonie' in input_string.lower() or 'symphonie' in input_string.lower():
'Gruppenlied': ['gruppenlied', 'jugend', 'lied', 'musikgruppe'], category = 'Orchester'
'Gedicht': ['gedicht'], elif 'chor' in left_side.lower():
'Erzählung': ['vortrag', 'erzä', 'program'], category = 'Chor'
'Instrumental': ['instrumental', 'musikstück', 'harfenstück'], elif 'gemeinsam' in left_side.lower() or 'gemeindelied' in left_side.lower() or 'gemeinsamer gesang' in input_string.lower():
} category = 'Gemeinsamer Gesang'
elif 'gruppenlied' in left_side.lower() or 'jugend' in left_side.lower() or 'lied' in left_side.lower():
# walk the dict in your desired priority order category = 'Gruppenlied'
elif 'gedicht' in left_side.lower():
category = 'Gedicht'
elif 'vortrag' in left_side.lower() or 'erzä' in left_side.lower() or 'program' in left_side.lower():
category = 'Erzählung'
elif 'instrumental' in input_string.lower() or 'musikstück' in left_side.lower() or 'harfenstück' in left_side.lower():
category = 'Instrumental'
else:
category = None category = None
text = left_side.lower()
for cat, keywords in CATEGORY_KEYWORDS.items():
if any(kw in text for kw in keywords):
category = cat
break
if right_side: if right_side:
titel, name = right_side.split('-', 1) if '-' in right_side else (right_side, None) titel, name = right_side.split('-', 1) if '-' in right_side else (right_side, None)

View File

@ -113,7 +113,7 @@ function renderContent(data) {
} else if (data.breadcrumbs.length === 1 && Array.isArray(data.folder_yesterday) && data.folder_yesterday.length > 0) { } else if (data.breadcrumbs.length === 1 && Array.isArray(data.folder_yesterday) && data.folder_yesterday.length > 0) {
contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="gestern">📅 Gestern</a></li>`; contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="gestern">📅 Gestern</a></li>`;
} }
if (data.breadcrumbs.length === 1 && data.toplist_enabled) { if (data.breadcrumbs.length === 1 ) {
contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="toplist">🔥 oft angehört</a></li>`; contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="toplist">🔥 oft angehört</a></li>`;
} }
console.log(data.folder_today, data.folder_yesterday); console.log(data.folder_today, data.folder_yesterday);