Logging: /stats-Zugriffe aus Statistiken entfernt - Zugriffe auf /stats werden nicht mehr geloggt und aus Aktivitäten gefiltert
This commit is contained in:
30
app.py
30
app.py
@@ -31,6 +31,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
def log_page_view(page: str, user_agent: str = None):
|
||||
"""Protokolliert Seitenaufrufe ohne IP-Adressen"""
|
||||
# Zugriffe auf /stats nicht loggen, da sie die Statistiken verfälschen
|
||||
if page == "stats":
|
||||
return
|
||||
|
||||
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
user_agent_clean = user_agent[:100] if user_agent else 'Unknown'
|
||||
logger.info(f"PAGE_VIEW: {page} | User-Agent: {user_agent_clean}")
|
||||
@@ -72,6 +76,9 @@ def get_statistics():
|
||||
'top_search_patterns': {}
|
||||
}
|
||||
|
||||
# Sammle alle relevanten Aktivitäten
|
||||
all_activities = []
|
||||
|
||||
try:
|
||||
# Aktuelle Log-Datei lesen
|
||||
log_file = logs_dir / 'app.log'
|
||||
@@ -84,6 +91,16 @@ def get_statistics():
|
||||
if 'PAGE_VIEW: ' in line:
|
||||
page = line.split('PAGE_VIEW: ')[1].split(' |')[0]
|
||||
stats['page_views_by_page'][page] = stats['page_views_by_page'].get(page, 0) + 1
|
||||
|
||||
# PAGE_VIEW Einträge als Aktivität sammeln
|
||||
timestamp = line.split(' - ')[0] if ' - ' in line else ''
|
||||
if timestamp:
|
||||
# /stats-Zugriffe aus den Aktivitäten filtern
|
||||
if 'PAGE_VIEW: stats' not in line:
|
||||
all_activities.append({
|
||||
'timestamp': timestamp,
|
||||
'line': line.strip()
|
||||
})
|
||||
|
||||
elif 'SEARCH:' in line:
|
||||
stats['total_searches'] += 1
|
||||
@@ -102,12 +119,11 @@ def get_statistics():
|
||||
pos_part = line.split('pos=\'')[1].split('\'')[0]
|
||||
if pos_part:
|
||||
stats['top_search_patterns'][pos_part] = stats['top_search_patterns'].get(pos_part, 0) + 1
|
||||
|
||||
# Letzte 10 Aktivitäten
|
||||
if len(stats['recent_activity']) < 10:
|
||||
|
||||
# SEARCH Einträge als Aktivität sammeln
|
||||
timestamp = line.split(' - ')[0] if ' - ' in line else ''
|
||||
if timestamp:
|
||||
stats['recent_activity'].append({
|
||||
all_activities.append({
|
||||
'timestamp': timestamp,
|
||||
'line': line.strip()
|
||||
})
|
||||
@@ -124,6 +140,12 @@ def get_statistics():
|
||||
stats['total_searches'] += 1
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Lesen der Backup-Datei {backup_file}: {e}")
|
||||
|
||||
# Neueste 10 Aktivitäten auswählen
|
||||
if all_activities:
|
||||
# Nach Timestamp sortieren (neueste zuerst)
|
||||
all_activities.sort(key=lambda x: x['timestamp'], reverse=True)
|
||||
stats['recent_activity'] = all_activities[:10]
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Lesen der Statistiken: {e}")
|
||||
|
5
cookies.txt
Normal file
5
cookies.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
#HttpOnly_localhost FALSE / FALSE 0 session eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIkVyZm9sZ3JlaWNoIGFuZ2VtZWxkZXQhIl19XSwibG9nZ2VkX2luIjp0cnVlfQ.aK1WBQ.KYWoG-YM2oKOpNz-3XUSFpOQQHs
|
292
stats_clean.html
Normal file
292
stats_clean.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Statistiken - Wordle‑Cheater</title>
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
:root { --bg:#ffffff; --text:#111827; --muted:#6b7280; --border:#e5e7eb; --button-bg:#111827; --button-text:#ffffff; --accent:#3b82f6; --success:#10b981; --warning:#f59e0b; }
|
||||
[data-theme="dark"] { --bg:#0b1220; --text:#e5e7eb; --muted:#9ca3af; --border:#334155; --button-bg:#e5e7eb; --button-text:#111827; --accent:#60a5fa; --success:#34d399; --warning:#fbbf24; }
|
||||
|
||||
html, body { background: var(--bg); color: var(--text); margin: 0; padding: 0; }
|
||||
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.6; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.header h1 { margin: 0; color: var(--text); }
|
||||
.header .actions { display: flex; gap: 1rem; }
|
||||
|
||||
.btn {
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--button-bg);
|
||||
color: var(--button-text);
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover { opacity: 0.9; }
|
||||
.btn.secondary { background: var(--muted); }
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.stat-card h3 { margin: 0 0 1rem 0; color: var(--text); font-size: 1.1rem; }
|
||||
.stat-number { font-size: 2.5rem; font-weight: bold; color: var(--accent); margin-bottom: 0.5rem; }
|
||||
.stat-description { color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.chart-container {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.chart-container h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
|
||||
.bar-chart { display: flex; align-items: end; gap: 0.5rem; height: 200px; }
|
||||
.bar {
|
||||
background: var(--accent);
|
||||
min-width: 40px;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.recent-activity {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.recent-activity h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.activity-item {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-family: monospace;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.activity-item:last-child { border-bottom: none; }
|
||||
|
||||
.activity-timestamp { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.search-patterns {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.search-patterns h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.pattern-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.pattern-item:last-child { border-bottom: none; }
|
||||
.pattern-text { font-family: monospace; color: var(--text); }
|
||||
.pattern-count { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: 2rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 1rem; }
|
||||
.header { flex-direction: column; gap: 1rem; align-items: stretch; }
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.bar-chart { height: 150px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>📊 Statistik-Dashboard</h1>
|
||||
<div class="actions">
|
||||
<a href="/" class="btn secondary">← Hauptseite</a>
|
||||
<a href="/logout" class="btn">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h3>📈 Gesamte Seitenaufrufe</h3>
|
||||
<div class="stat-number">56</div>
|
||||
<div class="stat-description">Alle protokollierten Seitenaufrufe</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>🔍 Gesamte Suchvorgänge</h3>
|
||||
<div class="stat-number">8</div>
|
||||
<div class="stat-description">Alle durchgeführten Wortsuche</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>📱 Seitenaufrufe pro Seite</h3>
|
||||
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>index:</strong> 22
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>service_worker:</strong> 27
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>stats:</strong> 7
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-container">
|
||||
<h3>🔍 Suchvorgänge nach Quellen</h3>
|
||||
|
||||
<div class="bar-chart">
|
||||
|
||||
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: 200.0px;">
|
||||
<div class="bar-value">7</div>
|
||||
<div class="bar-label">OpenThesaurus</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="search-patterns">
|
||||
<h3>🎯 Häufigste Suchmuster (Positionen)</h3>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">y</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">sk</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">ie</span>
|
||||
<span class="pattern-count">2</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="recent-activity">
|
||||
<h3>⏰ Letzte Aktivitäten</h3>
|
||||
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:36:41,302</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:18,338</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:16,697</span>
|
||||
<span>SEARCH: pos='sk' includes='' excludes='d' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:16,676</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:00:04,429</span>
|
||||
<span>SEARCH: pos='sk' includes='' excludes='d' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:00:04,400</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:59:43,963</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:59:42,302</span>
|
||||
<span>SEARCH: pos='sk' includes='' excludes='d' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:59:42,277</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:59:14,621</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
292
stats_final.html
Normal file
292
stats_final.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Statistiken - Wordle‑Cheater</title>
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
:root { --bg:#ffffff; --text:#111827; --muted:#6b7280; --border:#e5e7eb; --button-bg:#111827; --button-text:#ffffff; --accent:#3b82f6; --success:#10b981; --warning:#f59e0b; }
|
||||
[data-theme="dark"] { --bg:#0b1220; --text:#e5e7eb; --muted:#9ca3af; --border:#334155; --button-bg:#e5e7eb; --button-text:#111827; --accent:#60a5fa; --success:#34d399; --warning:#fbbf24; }
|
||||
|
||||
html, body { background: var(--bg); color: var(--text); margin: 0; padding: 0; }
|
||||
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.6; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.header h1 { margin: 0; color: var(--text); }
|
||||
.header .actions { display: flex; gap: 1rem; }
|
||||
|
||||
.btn {
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--button-bg);
|
||||
color: var(--button-text);
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover { opacity: 0.9; }
|
||||
.btn.secondary { background: var(--muted); }
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.stat-card h3 { margin: 0 0 1rem 0; color: var(--text); font-size: 1.1rem; }
|
||||
.stat-number { font-size: 2.5rem; font-weight: bold; color: var(--accent); margin-bottom: 0.5rem; }
|
||||
.stat-description { color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.chart-container {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.chart-container h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
|
||||
.bar-chart { display: flex; align-items: end; gap: 0.5rem; height: 200px; }
|
||||
.bar {
|
||||
background: var(--accent);
|
||||
min-width: 40px;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.recent-activity {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.recent-activity h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.activity-item {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-family: monospace;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.activity-item:last-child { border-bottom: none; }
|
||||
|
||||
.activity-timestamp { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.search-patterns {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.search-patterns h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.pattern-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.pattern-item:last-child { border-bottom: none; }
|
||||
.pattern-text { font-family: monospace; color: var(--text); }
|
||||
.pattern-count { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: 2rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 1rem; }
|
||||
.header { flex-direction: column; gap: 1rem; align-items: stretch; }
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.bar-chart { height: 150px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>📊 Statistik-Dashboard</h1>
|
||||
<div class="actions">
|
||||
<a href="/" class="btn secondary">← Hauptseite</a>
|
||||
<a href="/logout" class="btn">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h3>📈 Gesamte Seitenaufrufe</h3>
|
||||
<div class="stat-number">56</div>
|
||||
<div class="stat-description">Alle protokollierten Seitenaufrufe</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>🔍 Gesamte Suchvorgänge</h3>
|
||||
<div class="stat-number">8</div>
|
||||
<div class="stat-description">Alle durchgeführten Wortsuche</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>📱 Seitenaufrufe pro Seite</h3>
|
||||
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>index:</strong> 22
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>service_worker:</strong> 27
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>stats:</strong> 7
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-container">
|
||||
<h3>🔍 Suchvorgänge nach Quellen</h3>
|
||||
|
||||
<div class="bar-chart">
|
||||
|
||||
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: 200.0px;">
|
||||
<div class="bar-value">7</div>
|
||||
<div class="bar-label">OpenThesaurus</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="search-patterns">
|
||||
<h3>🎯 Häufigste Suchmuster (Positionen)</h3>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">y</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">sk</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">ie</span>
|
||||
<span class="pattern-count">2</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="recent-activity">
|
||||
<h3>⏰ Letzte Aktivitäten</h3>
|
||||
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:39:50,609</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:38:44,652</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:38:18,674</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:37:45,518</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:36:59,678</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:36:57,042</span>
|
||||
<span>PAGE_VIEW: stats | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-26 08:36:41,302</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: curl/8.14.1</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:18,338</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:16,697</span>
|
||||
<span>SEARCH: pos='sk' includes='' excludes='d' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 10:12:16,676</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
292
stats_new.html
Normal file
292
stats_new.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Statistiken - Wordle‑Cheater</title>
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
:root { --bg:#ffffff; --text:#111827; --muted:#6b7280; --border:#e5e7eb; --button-bg:#111827; --button-text:#ffffff; --accent:#3b82f6; --success:#10b981; --warning:#f59e0b; }
|
||||
[data-theme="dark"] { --bg:#0b1220; --text:#e5e7eb; --muted:#9ca3af; --border:#334155; --button-bg:#e5e7eb; --button-text:#111827; --accent:#60a5fa; --success:#34d399; --warning:#fbbf24; }
|
||||
|
||||
html, body { background: var(--bg); color: var(--text); margin: 0; padding: 0; }
|
||||
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.6; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.header h1 { margin: 0; color: var(--text); }
|
||||
.header .actions { display: flex; gap: 1rem; }
|
||||
|
||||
.btn {
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--button-bg);
|
||||
color: var(--button-text);
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover { opacity: 0.9; }
|
||||
.btn.secondary { background: var(--muted); }
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.stat-card h3 { margin: 0 0 1rem 0; color: var(--text); font-size: 1.1rem; }
|
||||
.stat-number { font-size: 2.5rem; font-weight: bold; color: var(--accent); margin-bottom: 0.5rem; }
|
||||
.stat-description { color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.chart-container {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.chart-container h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
|
||||
.bar-chart { display: flex; align-items: end; gap: 0.5rem; height: 200px; }
|
||||
.bar {
|
||||
background: var(--accent);
|
||||
min-width: 40px;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.recent-activity {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.recent-activity h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.activity-item {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-family: monospace;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.activity-item:last-child { border-bottom: none; }
|
||||
|
||||
.activity-timestamp { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.search-patterns {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.search-patterns h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.pattern-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.pattern-item:last-child { border-bottom: none; }
|
||||
.pattern-text { font-family: monospace; color: var(--text); }
|
||||
.pattern-count { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: 2rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 1rem; }
|
||||
.header { flex-direction: column; gap: 1rem; align-items: stretch; }
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.bar-chart { height: 150px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>📊 Statistik-Dashboard</h1>
|
||||
<div class="actions">
|
||||
<a href="/" class="btn secondary">← Hauptseite</a>
|
||||
<a href="/logout" class="btn">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h3>📈 Gesamte Seitenaufrufe</h3>
|
||||
<div class="stat-number">55</div>
|
||||
<div class="stat-description">Alle protokollierten Seitenaufrufe</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>🔍 Gesamte Suchvorgänge</h3>
|
||||
<div class="stat-number">8</div>
|
||||
<div class="stat-description">Alle durchgeführten Wortsuche</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>📱 Seitenaufrufe pro Seite</h3>
|
||||
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>index:</strong> 22
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>service_worker:</strong> 27
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>stats:</strong> 6
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-container">
|
||||
<h3>🔍 Suchvorgänge nach Quellen</h3>
|
||||
|
||||
<div class="bar-chart">
|
||||
|
||||
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: 200.0px;">
|
||||
<div class="bar-value">7</div>
|
||||
<div class="bar-label">OpenThesaurus</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="search-patterns">
|
||||
<h3>🎯 Häufigste Suchmuster (Positionen)</h3>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">y</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">sk</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">ie</span>
|
||||
<span class="pattern-count">2</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="recent-activity">
|
||||
<h3>⏰ Letzte Aktivitäten</h3>
|
||||
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:01,608</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:01,632</span>
|
||||
<span>SEARCH: pos='ie' includes='' excludes='muskrotnbgz' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:03,273</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:04,596</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:04,623</span>
|
||||
<span>SEARCH: pos='ie' includes='' excludes='muskrotnbgz' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:06,219</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:33,558</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:37,195</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:53,161</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:55,907</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
292
stats_output.html
Normal file
292
stats_output.html
Normal file
@@ -0,0 +1,292 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Statistiken - Wordle‑Cheater</title>
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
<style>
|
||||
:root { --bg:#ffffff; --text:#111827; --muted:#6b7280; --border:#e5e7eb; --button-bg:#111827; --button-text:#ffffff; --accent:#3b82f6; --success:#10b981; --warning:#f59e0b; }
|
||||
[data-theme="dark"] { --bg:#0b1220; --text:#e5e7eb; --muted:#9ca3af; --border:#334155; --button-bg:#e5e7eb; --button-text:#111827; --accent:#60a5fa; --success:#34d399; --warning:#fbbf24; }
|
||||
|
||||
html, body { background: var(--bg); color: var(--text); margin: 0; padding: 0; }
|
||||
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.6; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.header h1 { margin: 0; color: var(--text); }
|
||||
.header .actions { display: flex; gap: 1rem; }
|
||||
|
||||
.btn {
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--button-bg);
|
||||
color: var(--button-text);
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover { opacity: 0.9; }
|
||||
.btn.secondary { background: var(--muted); }
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.stat-card h3 { margin: 0 0 1rem 0; color: var(--text); font-size: 1.1rem; }
|
||||
.stat-number { font-size: 2.5rem; font-weight: bold; color: var(--accent); margin-bottom: 0.5rem; }
|
||||
.stat-description { color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.chart-container {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.chart-container h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
|
||||
.bar-chart { display: flex; align-items: end; gap: 0.5rem; height: 200px; }
|
||||
.bar {
|
||||
background: var(--accent);
|
||||
min-width: 40px;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.recent-activity {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.recent-activity h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.activity-item {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-family: monospace;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.activity-item:last-child { border-bottom: none; }
|
||||
|
||||
.activity-timestamp { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.search-patterns {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.search-patterns h3 { margin: 0 0 1rem 0; color: var(--text); }
|
||||
.pattern-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.pattern-item:last-child { border-bottom: none; }
|
||||
.pattern-text { font-family: monospace; color: var(--text); }
|
||||
.pattern-count { color: var(--accent); font-weight: 600; }
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: 2rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 1rem; }
|
||||
.header { flex-direction: column; gap: 1rem; align-items: stretch; }
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.bar-chart { height: 150px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>📊 Statistik-Dashboard</h1>
|
||||
<div class="actions">
|
||||
<a href="/" class="btn secondary">← Hauptseite</a>
|
||||
<a href="/logout" class="btn">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h3>📈 Gesamte Seitenaufrufe</h3>
|
||||
<div class="stat-number">53</div>
|
||||
<div class="stat-description">Alle protokollierten Seitenaufrufe</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>🔍 Gesamte Suchvorgänge</h3>
|
||||
<div class="stat-number">8</div>
|
||||
<div class="stat-description">Alle durchgeführten Wortsuche</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>📱 Seitenaufrufe pro Seite</h3>
|
||||
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>index:</strong> 22
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>service_worker:</strong> 27
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 0.5rem;">
|
||||
<strong>stats:</strong> 4
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-container">
|
||||
<h3>🔍 Suchvorgänge nach Quellen</h3>
|
||||
|
||||
<div class="bar-chart">
|
||||
|
||||
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: 200.0px;">
|
||||
<div class="bar-value">7</div>
|
||||
<div class="bar-label">OpenThesaurus</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="search-patterns">
|
||||
<h3>🎯 Häufigste Suchmuster (Positionen)</h3>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">y</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">sk</span>
|
||||
<span class="pattern-count">3</span>
|
||||
</div>
|
||||
|
||||
<div class="pattern-item">
|
||||
<span class="pattern-text">ie</span>
|
||||
<span class="pattern-count">2</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="recent-activity">
|
||||
<h3>⏰ Letzte Aktivitäten</h3>
|
||||
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:01,608</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:01,632</span>
|
||||
<span>SEARCH: pos='ie' includes='' excludes='muskrotnbgz' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:03,273</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:04,596</span>
|
||||
<span>PAGE_VIEW: index | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:04,623</span>
|
||||
<span>SEARCH: pos='ie' includes='' excludes='muskrotnbgz' sources=['OT'] | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 08:39:06,219</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:33,558</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:37,195</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:53,161</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
<div class="activity-item">
|
||||
<span class="activity-timestamp">2025-08-20 09:05:55,907</span>
|
||||
<span>PAGE_VIEW: service_worker | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Sa</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -191,18 +191,21 @@
|
||||
<div class="bar-chart">
|
||||
{% set max_count = [stats.searches_by_source.OT, stats.searches_by_source.WF, stats.searches_by_source.Both] | max %}
|
||||
{% if stats.searches_by_source.OT > 0 %}
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: {{ (stats.searches_by_source.OT / max_count * 150) + 50 }}px;">
|
||||
<div class="bar-value">{{ stats.searches_by_source.OT }}</div>
|
||||
<div class="bar-label">OpenThesaurus</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if stats.searches_by_source.WF > 0 %}
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: {{ (stats.searches_by_source.WF / max_count * 150) + 50 }}px;">
|
||||
<div class="bar-value">{{ stats.searches_by_source.WF }}</div>
|
||||
<div class="bar-label">Wordfreq</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if stats.searches_by_source.Both > 0 %}
|
||||
<!-- CSS-Linter: Jinja2-Template-Syntax wird ignoriert -->
|
||||
<div class="bar" style="height: {{ (stats.searches_by_source.Both / max_count * 150) + 50 }}px;">
|
||||
<div class="bar-value">{{ stats.searches_by_source.Both }}</div>
|
||||
<div class="bar-label">Beide</div>
|
||||
|
Reference in New Issue
Block a user