# -*- coding: utf-8 -*- """ Hunspell-Korrekturschicht. Woerterbuch-basierte Korrektur (~6ms/Wort). """ from pathlib import Path from trixy_core.stt.layers.base import CorrectionLayer from trixy_core.utils.debug import pdebug, pwarn try: import hunspell _HAS_HUNSPELL = True except ImportError: _HAS_HUNSPELL = False class HunspellLayer(CorrectionLayer): """Hunspell woerterbuch-basierte Korrektur.""" NAME = "hunspell" def __init__(self) -> None: self._hobj: "hunspell.HunSpell | None" = None self._protected_words: set[str] = set() def is_available(self) -> bool: """Prueft ob pyhunspell installiert ist.""" return _HAS_HUNSPELL def initialize(self, config: dict, language: str, protected_words: list[str]) -> bool: """Laedt Hunspell-Woerterbuch.""" if not _HAS_HUNSPELL: return False dict_path = config.get("hunspell_dict_path", f"/usr/share/hunspell/{language}_DE") # Hunspell braucht .dic und .aff Dateien dic_file = Path(f"{dict_path}.dic") aff_file = Path(f"{dict_path}.aff") if not dic_file.exists() or not aff_file.exists(): pdebug(f"[Hunspell] Woerterbuch nicht gefunden: {dict_path}") return False try: self._hobj = hunspell.HunSpell(str(aff_file), str(dic_file)) self._protected_words = {w.lower() for w in protected_words} # Geschuetzte Woerter zum Woerterbuch hinzufuegen for word in protected_words: self._hobj.add(word) pdebug(f"[Hunspell] Woerterbuch geladen: {dict_path}") return True except Exception as e: pwarn(f"[Hunspell] Initialisierung fehlgeschlagen: {e}") self._hobj = None return False def correct(self, text: str) -> str: """Prueft jedes Wort einzeln und schlaegt Korrekturen vor.""" if not self._hobj or not text.strip(): return text try: words = text.split() corrected_words = [] changed = False for word in words: # Geschuetzte Woerter ueberspringen if word.lower() in self._protected_words: corrected_words.append(word) continue # Wort pruefen (Satzzeichen entfernen fuer Pruefung) clean_word = word.strip(".,!?;:\"'()") if not clean_word: corrected_words.append(word) continue if self._hobj.spell(clean_word): # Wort ist korrekt corrected_words.append(word) else: # Wort ist falsch — Vorschlaege holen suggestions = self._hobj.suggest(clean_word) if suggestions: # Ersten Vorschlag verwenden (bester Match) suggestion = suggestions[0] # Satzzeichen beibehalten prefix = word[:len(word) - len(word.lstrip(".,!?;:\"'()"))] if word != word.lstrip(".,!?;:\"'()") else "" suffix = word[len(word.rstrip(".,!?;:\"'()")):] if word != word.rstrip(".,!?;:\"'()") else "" corrected_words.append(f"{prefix}{suggestion}{suffix}") changed = True else: corrected_words.append(word) if changed: result = " ".join(corrected_words) pdebug(f"[Hunspell] '{text}' → '{result}'") return result return text except Exception as e: pdebug(f"[Hunspell] Fehler bei Korrektur: {e}") return text def shutdown(self) -> None: """Gibt Ressourcen frei.""" self._hobj = None