4 Commits

3 changed files with 90 additions and 71 deletions

69
app.py
View File

@@ -132,19 +132,7 @@ def index():
return render_template('index.html', tage=tage, werktage=werktage, wochentag=wochentag, plusminus_result=plusminus_result, kw_berechnen=kw_berechnen, kw_datum=kw_datum, active_idx=active_idx)
@app.route('/stats', methods=['GET', 'POST'])
def stats():
stats_password = os.environ.get('STATS_PASSWORD', 'changeme')
if 'stats_auth' not in session:
if request.method == 'POST':
if request.form.get('password') == stats_password:
session['stats_auth'] = True
return redirect(url_for('stats'))
else:
return render_template('stats_login.html', error='Falsches Passwort!')
return render_template('stats_login.html', error=None)
# Auswertung der Logdatei
log_path = os.path.join('log', 'pageviews.log')
def parse_log_stats(log_path):
pageviews = 0
func_counts = {}
impressions_per_day = {}
@@ -154,7 +142,6 @@ def stats():
for line in f:
if 'PAGEVIEW' in line:
pageviews += 1
# Datum extrahieren (YYYY-MM-DD)
try:
date = line[:10]
if len(date) == 10 and date[4] == '-' and date[7] == '-':
@@ -167,26 +154,22 @@ def stats():
elif 'FUNC_API:' in line:
api = line.split('FUNC_API:')[1].strip()
api_counts[api] = api_counts.get(api, 0) + 1
return render_template('stats_dashboard.html', pageviews=pageviews, func_counts=func_counts, impressions_per_day=impressions_per_day, api_counts=api_counts)
return pageviews, func_counts, impressions_per_day, api_counts
@app.route('/monitor')
def monitor():
@app.route('/stats', methods=['GET', 'POST'])
def stats():
stats_password = os.environ.get('STATS_PASSWORD', 'changeme')
if 'stats_auth' not in session:
if request.method == 'POST':
if request.form.get('password') == stats_password:
session['stats_auth'] = True
return redirect(url_for('stats'))
else:
return render_template('stats_login.html', error='Falsches Passwort!')
return render_template('stats_login.html', error=None)
log_path = os.path.join('log', 'pageviews.log')
pageviews = 0
if os.path.exists(log_path):
with open(log_path, encoding='utf-8') as f:
for line in f:
if 'PAGEVIEW' in line:
pageviews += 1
uptime = int(time.time() - app_start_time)
return jsonify({
"status": "ok",
"message": "App running",
"time": datetime.now().isoformat(),
"uptime_seconds": uptime,
"pageviews_last_7_days": pageviews
})
pageviews, func_counts, impressions_per_day, api_counts = parse_log_stats(log_path)
return render_template('stats_dashboard.html', pageviews=pageviews, func_counts=func_counts, impressions_per_day=impressions_per_day, api_counts=api_counts)
# --- REST API ---
def log_api_usage(api_name):
@@ -298,27 +281,7 @@ def api_plusminus():
@app.route('/api/stats', methods=['GET'])
def api_stats():
log_path = os.path.join('log', 'pageviews.log')
pageviews = 0
func_counts = {}
impressions_per_day = {}
api_counts = {}
if os.path.exists(log_path):
with open(log_path, encoding='utf-8') as f:
for line in f:
if 'PAGEVIEW' in line:
pageviews += 1
try:
date = line[:10]
if len(date) == 10 and date[4] == '-' and date[7] == '-':
impressions_per_day[date] = impressions_per_day.get(date, 0) + 1
except Exception:
pass
elif 'FUNC:' in line:
func = line.split('FUNC:')[1].strip()
func_counts[func] = func_counts.get(func, 0) + 1
elif 'FUNC_API:' in line:
api = line.split('FUNC_API:')[1].strip()
api_counts[api] = api_counts.get(api, 0) + 1
pageviews, func_counts, impressions_per_day, api_counts = parse_log_stats(log_path)
return render_template('stats_dashboard.html', pageviews=pageviews, func_counts=func_counts, impressions_per_day=impressions_per_day, api_counts=api_counts)
@app.route('/api/monitor', methods=['GET'])

View File

@@ -146,22 +146,78 @@ button:focus, .accordion-header:focus {
.accordion-content.active {
display: block;
}
.header-tage { background: #2563eb; }
.header-tage.active, .header-tage:hover { background: #1e40af; }
.header-werktage { background: #059669; }
.header-werktage.active, .header-werktage:hover { background: #047857; }
.header-wochentag { background: #f59e42; color: #fff; }
.header-wochentag.active, .header-wochentag:hover { background: #d97706; }
.header-plusminus-tage { background: #a21caf; }
.header-plusminus-tage.active, .header-plusminus-tage:hover { background: #701a75; }
.header-plusminus-werktage { background: #0ea5e9; }
.header-plusminus-werktage.active, .header-plusminus-werktage:hover { background: #0369a1; }
.header-plusminus-wochenmonate { background: #f43f5e; }
.header-plusminus-wochenmonate.active, .header-plusminus-wochenmonate:hover { background: #be123c; }
.header-kw { background: #a78bfa; color: #1e293b; }
.header-kw.active, .header-kw:hover { background: #7c3aed; }
.header-kw-datum { background: #facc15; color: #1e293b; }
.header-kw-datum.active, .header-kw-datum:hover { background: #ca8a04; }
.header-tage {
background: #2563eb;
color: #fff;
}
.header-tage.active, .header-tage:hover {
background: #1e40af;
color: #fff;
}
.header-werktage {
background: #059669;
color: #fff;
}
.header-werktage.active, .header-werktage:hover {
background: #047857;
color: #fff;
}
.header-wochentag {
background: #f59e42;
color: #1e293b;
}
.header-wochentag.active, .header-wochentag:hover {
background: #d97706;
color: #fff;
}
.header-plusminus-tage {
background: #a21caf;
color: #fff;
}
.header-plusminus-tage.active, .header-plusminus-tage:hover {
background: #701a75;
color: #fff;
}
.header-plusminus-werktage {
background: #0ea5e9;
color: #fff;
}
.header-plusminus-werktage.active, .header-plusminus-werktage:hover {
background: #0369a1;
color: #fff;
}
.header-plusminus-wochenmonate {
background: #f43f5e;
color: #fff;
}
.header-plusminus-wochenmonate.active, .header-plusminus-wochenmonate:hover {
background: #be123c;
color: #fff;
}
.header-kw {
background: #a78bfa;
color: #1e293b;
}
.header-kw.active, .header-kw:hover {
background: #7c3aed;
color: #fff;
}
.header-kw-datum {
background: #facc15;
color: #1e293b;
}
.header-kw-datum.active, .header-kw-datum:hover {
background: #ca8a04;
color: #fff;
}
.header-plusminus {
background: #be123c;
color: #fff;
}
.header-plusminus.active, .header-plusminus:hover {
background: #7f1d1d;
color: #fff;
}
@media (max-width: 600px) {
.container {
margin: 1em;

View File

@@ -79,8 +79,8 @@
<div style="text-align:center; margin-bottom:1.2em;">
<div style="font-size:1.1em; font-style:italic; color:#64748b;">Elpatrons</div>
<h1 style="margin:0;">Datumsrechner</h1>
<div style="font-size:1.08em; color:#2563eb; margin-top:0.3em;">
Ein <em>freier</em> Datumsrechner: barriereFrei, werbeFrei, trackingFrei, lizenzFrei.
<div style="font-size:0.9em; color:#353535; margin-top:0.3em;">
Eine <em>freie</em> Web-App: barriere<em>frei</em>, werbe<em>frei</em>, tracking<em>frei</em>, lizenz<em>frei</em> und kosten<em>frei</em>.
</div>
</div>
<div class="accordion">