From 33bbc535cd17cd582596d94830398f974e8a1371 Mon Sep 17 00:00:00 2001 From: Guido Date: Fri, 21 Aug 2026 14:23:12 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Skript=20zum=20Pr=C3=BCfen=20der=20Date?= =?UTF-8?q?nbank-Sicherungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Listet je Backup, wie viele Schlagwörter, Budget-Vorlagen und kategorisierte Buchungen darin stecken. Nach einem Datenverlust sieht man damit auf einen Blick, welche Sicherung noch vollständig ist – statt nach Zeitstempel zu raten. Co-Authored-By: Claude Opus 4.8 --- backend/scripts/pruefe_backups.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 backend/scripts/pruefe_backups.py diff --git a/backend/scripts/pruefe_backups.py b/backend/scripts/pruefe_backups.py new file mode 100644 index 0000000..f500beb --- /dev/null +++ b/backend/scripts/pruefe_backups.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +"""Listet je Backup, wie viele Schlagwörter/Budget-Vorlagen/kategorisierte +Buchungen darin stecken. So sieht man, welches Backup noch heil ist.""" +import glob, os, sqlite3, sys + +muster = sys.argv[1] if len(sys.argv) > 1 else "/var/lib/certain-finance/backups/*.db" +print(f"{'Datei':<34}{'Schlagw.':>9}{'Budget':>8}{'Buch.m.Kat':>12}") +for f in sorted(glob.glob(muster)): + try: + con = sqlite3.connect(f"file:{f}?mode=ro", uri=True) + def z(sql): + try: + return con.execute(sql).fetchone()[0] + except sqlite3.Error: + return "-" + print(f"{os.path.basename(f):<34}" + f"{z('SELECT COUNT(*) FROM categorization_rules'):>9}" + f"{z('SELECT COUNT(*) FROM budget_template_lines'):>8}" + f"{z('SELECT COUNT(*) FROM transactions WHERE category_id IS NOT NULL'):>12}") + con.close() + except Exception as e: + print(f"{os.path.basename(f):<34} Fehler: {e}")