Phase 7: sync_shared.py - Mojibake-fail-safe + Doku
- has_mojibake_markers Heuristik: erkennt Doppel/Triple-Encoded UTF-8 (typische Latin-1-Sicht-Sequenzen wie ä ö ¤ Æ). - fix_mojibake raises RuntimeError wenn ftfy fehlt UND Mojibake erkannt ist - verhindert Mojibake-Reimport durch Sync. - main() faengt RuntimeError und exit 2 mit klarer Fehlermeldung. - CLAUDE.md: Voraussetzung ftfy + fail-safe-Erklaerung erganzt.
Dieser Commit ist enthalten in:
@@ -183,6 +183,11 @@ shared:
|
|||||||
grund: "Verwaltungs-Fork mit tenant_id-Filter weg + Historie + Config-Konstanten"
|
grund: "Verwaltungs-Fork mit tenant_id-Filter weg + Historie + Config-Konstanten"
|
||||||
hinweis: "Auto-Sync schreibt NICHT. Drift wird gemeldet, manuell entscheiden."
|
hinweis: "Auto-Sync schreibt NICHT. Drift wird gemeldet, manuell entscheiden."
|
||||||
|
|
||||||
|
voraussetzung:
|
||||||
|
ftfy installieren: "pip install ftfy" (im venv des Repos)
|
||||||
|
grund: "Sync-Skript fixed Mojibake aus Monitor-Originalen automatisch."
|
||||||
|
fail_safe: "Ohne ftfy bricht das Skript ab wenn Mojibake erkannt - schuetzt vor Mojibake-Reimport."
|
||||||
|
|
||||||
beim_drift:
|
beim_drift:
|
||||||
nicht_locked: "einfach --apply, dann committen"
|
nicht_locked: "einfach --apply, dann committen"
|
||||||
locked: "diff anschauen, ueberlegen ob die Monitor-Aenderung im Verwaltungs-Fork sinnvoll ist"
|
locked: "diff anschauen, ueberlegen ob die Monitor-Aenderung im Verwaltungs-Fork sinnvoll ist"
|
||||||
|
|||||||
@@ -51,11 +51,31 @@ DEFAULT_MONITOR = Path("/home/claude-dev/AegisSight-Monitor")
|
|||||||
DEFAULT_VERWALTUNG = Path(__file__).resolve().parent.parent
|
DEFAULT_VERWALTUNG = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
def has_mojibake_markers(text: str) -> bool:
|
||||||
|
"""Heuristik: Doppel/Triple-Encoded UTF-8 erkennen.
|
||||||
|
|
||||||
|
Echte deutsche Umlaute kommen als "ü" / "ä" / "ö" / "ß" - Single-Byte-Zeichen
|
||||||
|
aus latin-1-Sicht ("Ã", "Â", "Æ") sind ein starkes Mojibake-Indiz.
|
||||||
|
"""
|
||||||
|
return any(seq in text for seq in ("ä", "ö", "ü", "ß", "Ä", "Ö", "Ü", "¤", "Æ"))
|
||||||
|
|
||||||
|
|
||||||
def fix_mojibake(text: str) -> tuple[str, bool]:
|
def fix_mojibake(text: str) -> tuple[str, bool]:
|
||||||
"""Repariert Doppel-Encoded UTF-8 falls vorhanden. Gibt (text, fixed?) zurück."""
|
"""Repariert Doppel-Encoded UTF-8 falls vorhanden. Gibt (text, fixed?) zurück.
|
||||||
|
|
||||||
|
Raises RuntimeError wenn Mojibake erkannt wird aber ftfy nicht installiert ist
|
||||||
|
(dann würde ein Sync den Mojibake unrepariert ins Verwaltungs-Repo schreiben -
|
||||||
|
dagegen schützt fail-fast).
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
import ftfy # type: ignore
|
import ftfy # type: ignore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
if has_mojibake_markers(text):
|
||||||
|
raise RuntimeError(
|
||||||
|
"Monitor-Source enthält Mojibake (Doppel-Encoded UTF-8) und ftfy "
|
||||||
|
"ist nicht installiert. Sync würde Mojibake ins Verwaltungs-Repo "
|
||||||
|
"schreiben.\n Lösung: pip install ftfy (im venv des Repos)"
|
||||||
|
)
|
||||||
return text, False
|
return text, False
|
||||||
fixed = ftfy.fix_text(text)
|
fixed = ftfy.fix_text(text)
|
||||||
return fixed, fixed != text
|
return fixed, fixed != text
|
||||||
@@ -126,7 +146,11 @@ def main() -> int:
|
|||||||
return 2
|
return 2
|
||||||
|
|
||||||
src_text = src_path.read_text(encoding="utf-8")
|
src_text = src_path.read_text(encoding="utf-8")
|
||||||
src_text, fixed_mojibake = fix_mojibake(src_text)
|
try:
|
||||||
|
src_text, fixed_mojibake = fix_mojibake(src_text)
|
||||||
|
except RuntimeError as e:
|
||||||
|
print(f"FEHLER beim Verarbeiten von {monitor_rel}:\n {e}", file=sys.stderr)
|
||||||
|
return 2
|
||||||
src_text = patch_imports_for_shared(src_text)
|
src_text = patch_imports_for_shared(src_text)
|
||||||
|
|
||||||
existing = dst_path.read_text(encoding="utf-8") if dst_path.exists() else ""
|
existing = dst_path.read_text(encoding="utf-8") if dst_path.exists() else ""
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren