Compare commits
4 Commits
de47c379b5
...
25b0de1cce
Author | SHA1 | Date | |
---|---|---|---|
25b0de1cce | |||
8d10c6f891 | |||
e44e55af53 | |||
34eeed8753 |
69
app.py
69
app.py
@@ -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'])
|
||||
|
@@ -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;
|
||||
|
@@ -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">
|
||||
|
Reference in New Issue
Block a user