Files
search/web/app.py
T

247 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
import subprocess
import json
import time
import threading
from datetime import datetime
from pathlib import Path
from flask import Flask, jsonify, render_template_string
DB_DATA = Path("page_counts.json")
INTERVAL = 15 * 60 # 15 Minuten
app = Flask(__name__)
HTML = """
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JonasSearch – Pages</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body {
margin: 0;
background: #111;
color: #eee;
font-family: Arial, sans-serif;
}
.container {
max-width: 1200px;
margin: auto;
padding: 30px;
}
h1 {
margin-bottom: 5px;
}
.current {
font-size: 2.5rem;
margin: 20px 0;
}
.chart-container {
background: #1b1b1b;
padding: 20px;
border-radius: 15px;
}
</style>
</head>
<body>
<div class="container">
<h1>JonasSearch</h1>
<div>Indexed Pages</div>
<div class="current">
<span id="current">–</span> Pages
</div>
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
</div>
<script>
let chart = null;
async function update() {
const response = await fetch("/api/data");
const data = await response.json();
document.getElementById("current").textContent =
data.values.length
? data.values[data.values.length - 1].count.toLocaleString("de-DE")
: "–";
const labels = data.values.map(x =>
new Date(x.timestamp).toLocaleString("de-DE")
);
const values = data.values.map(x => x.count);
if (chart) {
chart.data.labels = labels;
chart.data.datasets[0].data = values;
chart.update();
return;
}
chart = new Chart(document.getElementById("chart"), {
type: "line",
data: {
labels: labels,
datasets: [{
label: "Pages",
data: values,
tension: 0.25,
pointRadius: 2,
fill: true
}]
},
options: {
responsive: true,
scales: {
x: {
ticks: {
color: "#aaa"
}
},
y: {
beginAtZero: false,
ticks: {
color: "#aaa"
}
}
},
plugins: {
legend: {
labels: {
color: "#eee"
}
}
}
}
});
}
update();
// Browser alle 30 Sekunden aktualisieren
setInterval(update, 30000);
</script>
</body>
</html>
"""
def load_data():
if not DB_DATA.exists():
return []
try:
with DB_DATA.open("r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return []
def save_data(data):
tmp = DB_DATA.with_suffix(".tmp")
with tmp.open("w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
tmp.replace(DB_DATA)
def get_page_count():
command = [
"sudo",
"-u",
"postgres",
"psql",
"-p",
"25432",
"-d",
"jonassearch",
"-t",
"-A",
"-c",
"SELECT COUNT(*) FROM pages;"
]
result = subprocess.run(
command,
capture_output=True,
text=True,
check=True
)
return int(result.stdout.strip())
def collect():
while True:
try:
count = get_page_count()
entry = {
"timestamp": datetime.now().isoformat(),
"count": count
}
data = load_data()
data.append(entry)
save_data(data)
print(
f"[{entry['timestamp']}] "
f"Pages: {count}"
)
except Exception as e:
print(f"Fehler beim Abrufen der Seitenzahl: {e}")
time.sleep(INTERVAL)
@app.route("/")
def index():
return render_template_string(HTML)
@app.route("/api/data")
def api_data():
return jsonify({
"values": load_data()
})
if __name__ == "__main__":
# Collector im Hintergrund starten
thread = threading.Thread(target=collect, daemon=True)
thread.start()
# Webserver
app.run(
host="0.0.0.0",
port=8081,
threaded=True
)