- monitoring.py: taeglicher Scan-Adapter aller aktiven BL, kein Auto-Fetch (#135) - monitoring_digest.html: Mail-Template mit '0-Kontext'-Hinweis - abgeordnetenwatch.py + sync_*.py: Phase 1 Roll-Call-Voting (#106) - 17 Parlamente (16 BL + BT) - 9 BL-spezifische Drucksachen-Patterns + Date-Title-Fallback - 28977 Votes fuer BUND in DB - wahlprogramm_check.py: fehlende Programme erkennen (#128) - NI-Skip-Liste, NRW Empty-Query-Fallback Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
129 lines
5.4 KiB
HTML
129 lines
5.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>GWÖ-Monitor {{ scan_date }}</title>
|
|
</head>
|
|
<body style="font-family:Helvetica,Arial,sans-serif;max-width:640px;margin:0 auto;padding:20px;color:#333">
|
|
|
|
<h2 style="color:#007a80;margin-bottom:4px">GWÖ-Antragsprüfer — Monitoring {{ scan_date }}</h2>
|
|
<p style="color:#666;margin-top:4px;font-size:0.9em">Täglicher Scan aller aktiven Bundesländer</p>
|
|
|
|
{% if new_total == 0 %}
|
|
<div style="background:#f0fafa;border-left:3px solid #009da5;padding:10px 14px;margin:12px 0;font-size:0.95em;color:#444">
|
|
<b style="color:#007a80">Heute keine Änderungen.</b> Alle {{ total_seen }} in den Landtags-Portalen sichtbaren Drucksachen sind bereits seit dem letzten Scan bekannt. Das heißt: die Portale haben seit gestern keine neuen Anträge publiziert — nicht: der Scan war erfolglos.
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Kennzahlen-Block -->
|
|
<table style="width:100%;border-collapse:collapse;margin:16px 0">
|
|
<tr style="background:#f0fafa">
|
|
<td style="padding:10px 14px;border:1px solid #c8e6e6;font-weight:bold">Neue Drucksachen seit letztem Scan</td>
|
|
<td style="padding:10px 14px;border:1px solid #c8e6e6;font-size:1.4em;color:#007a80;font-weight:bold">{{ new_total }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:10px 14px;border:1px solid #ddd">Im Portal aktuell sichtbar (inkl. bekannter)</td>
|
|
<td style="padding:10px 14px;border:1px solid #ddd">{{ total_seen }}</td>
|
|
</tr>
|
|
<tr style="background:#fffbf0">
|
|
<td style="padding:10px 14px;border:1px solid #ddd">Kosten-Schätzung (alle analysieren)</td>
|
|
<td style="padding:10px 14px;border:1px solid #ddd">
|
|
<b>{{ "%.4f"|format(estimated_cost_eur) }} EUR</b>
|
|
<span style="font-size:0.8em;color:#888"> (Qwen Plus, Näherung)</span>
|
|
</td>
|
|
</tr>
|
|
{% if errors %}
|
|
<tr style="background:#fff3f3">
|
|
<td style="padding:10px 14px;border:1px solid #f5c0c0;color:#c00">Adapter-Fehler</td>
|
|
<td style="padding:10px 14px;border:1px solid #f5c0c0;color:#c00;font-weight:bold">{{ errors|length }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
|
|
<!-- Fehler-Details -->
|
|
{% if errors %}
|
|
<div style="background:#fff3f3;border-left:3px solid #c00;padding:10px 14px;margin:12px 0">
|
|
<b style="color:#c00">Fehler-Details:</b>
|
|
<ul style="margin:6px 0 0;padding-left:18px;font-size:0.9em">
|
|
{% for e in errors %}
|
|
<li>{{ e }}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Bundesland-Übersicht -->
|
|
<h3 style="color:#007a80;border-bottom:1px solid #c8e6e6;padding-bottom:6px">Bundesland-Übersicht</h3>
|
|
<table style="width:100%;border-collapse:collapse;font-size:0.9em">
|
|
<thead>
|
|
<tr style="background:#e6f4f4">
|
|
<th style="padding:7px 10px;border:1px solid #c8e6e6;text-align:left">BL</th>
|
|
<th style="padding:7px 10px;border:1px solid #c8e6e6;text-align:right">Gesehen</th>
|
|
<th style="padding:7px 10px;border:1px solid #c8e6e6;text-align:right">Neu</th>
|
|
<th style="padding:7px 10px;border:1px solid #c8e6e6;text-align:left">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in results %}
|
|
<tr style="{% if r.error %}background:#fff8f8{% elif r.new_count > 0 %}background:#f8fff8{% endif %}">
|
|
<td style="padding:6px 10px;border:1px solid #ddd;font-weight:bold">{{ r.bundesland }}</td>
|
|
<td style="padding:6px 10px;border:1px solid #ddd;text-align:right">{{ r.total_seen }}</td>
|
|
<td style="padding:6px 10px;border:1px solid #ddd;text-align:right;color:{% if r.new_count > 0 %}#007a80{% else %}#999{% endif %}">
|
|
{{ r.new_count }}
|
|
</td>
|
|
<td style="padding:6px 10px;border:1px solid #ddd;font-size:0.85em">
|
|
{% if r.error %}
|
|
<span style="color:#c00">✗ {{ r.error[:100] }}</span>
|
|
{% elif r.new_count > 0 %}
|
|
<span style="color:#2a7a2a">✓ {{ r.new_count }} neue</span>
|
|
{% else %}
|
|
<span style="color:#999">keine Änderung</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<!-- Neue Drucksachen -->
|
|
{% if new_docs %}
|
|
<h3 style="color:#007a80;border-bottom:1px solid #c8e6e6;padding-bottom:6px;margin-top:24px">
|
|
Neue Drucksachen ({{ new_docs|length }})
|
|
</h3>
|
|
{% for doc in new_docs[:30] %}
|
|
<div style="border-left:3px solid #007a80;padding:6px 12px;margin:8px 0;background:#f9f9f9;font-size:0.9em">
|
|
<span style="color:#007a80;font-weight:bold">{{ doc.bundesland }}</span>
|
|
<span style="color:#555;margin-left:8px">{{ doc.drucksache }}</span>
|
|
{% if doc.datum %}
|
|
<span style="color:#888;font-size:0.85em;margin-left:8px">{{ doc.datum }}</span>
|
|
{% endif %}
|
|
<br>
|
|
<span style="color:#333">{{ (doc.title or doc.drucksache or '')[:120] }}</span>
|
|
{% if doc.fraktionen %}
|
|
<br><span style="color:#777;font-size:0.85em">
|
|
{% if doc.fraktionen is iterable and doc.fraktionen is not string %}
|
|
{{ doc.fraktionen | join(', ') }}
|
|
{% else %}
|
|
{{ doc.fraktionen }}
|
|
{% endif %}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
{% if new_docs|length > 30 %}
|
|
<p style="color:#666;font-size:0.9em">… und {{ new_docs|length - 30 }} weitere neue Drucksachen.</p>
|
|
{% endif %}
|
|
{% else %}
|
|
<p style="color:#888;font-style:italic">Keine neuen Drucksachen heute.</p>
|
|
{% endif %}
|
|
|
|
<!-- Footer -->
|
|
<hr style="border:none;border-top:1px solid #ddd;margin:24px 0">
|
|
<p style="font-size:0.8em;color:#aaa">
|
|
GWÖ-Antragsprüfer Monitoring · Kosten-Schätzung basiert auf Qwen-Plus-Preisen (DashScope, April 2026) ·
|
|
Nur Metadaten — kein LLM-Call im Scan
|
|
</p>
|
|
</body>
|
|
</html>
|