Files
2026-06-29 09:52:02 +02:00

52 lines
1.5 KiB
Python

"""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()