"""HTML aus E-Mail-Artikeln sicher in lesbaren Text umwandeln. Bewusst ohne externe Bibliothek und ohne Ausgabe von HTML: So können weder Schadcode noch nachgeladene Bilder/Tracking-Pixel aus Support-Mails ausgeführt werden. Block-Tags werden zu Zeilenumbrüchen, der Rest entfernt. """ import re from html.parser import HTMLParser _BLOCK = {"p", "div", "br", "li", "tr", "table", "blockquote", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "section", "article", "header"} _DROP = {"script", "style", "head", "title"} class _Extractor(HTMLParser): def __init__(self): super().__init__(convert_charrefs=True) self.parts = [] self._skip = 0 def handle_starttag(self, tag, attrs): if tag in _DROP: self._skip += 1 elif tag in _BLOCK: self.parts.append("\n") def handle_endtag(self, tag): if tag in _DROP and self._skip: self._skip -= 1 elif tag in _BLOCK: self.parts.append("\n") def handle_data(self, data): if not self._skip: self.parts.append(data) def clean_html(html: str) -> str: if not html: return "" p = _Extractor() try: p.feed(html) except Exception: # noqa: BLE001 - bei kaputtem HTML lieber Rohtext return re.sub(r"<[^>]+>", "", html).strip() text = "".join(p.parts) # Mehrfache Leerzeichen/Leerzeilen zusammenfassen text = re.sub(r"[ \t]+", " ", text) text = re.sub(r" *\n *", "\n", text) text = re.sub(r"\n{3,}", "\n\n", text) return text.strip()