/
EgorG23Bey
/
email_client
Обзор
Документация
Войти
/
EgorG23Bey
/
email_client
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
parser.py
143 строки
3 KB
EgorG23
update impt
12 июл 2026, 23:51
12 июл 2026, 23:51
0663458
Код
Авторство
О чём код?
import re from email import message_from_bytes from email.header import decode_header from bs4 import BeautifulSoup from models import EmailMessage def decode_mime_header(header): """ Декодирует MIME-заголовки (например, тему письма). """ if not header: return "" decoded = decode_header(header) result = "" for text, encoding in decoded: if isinstance(text, bytes): result += text.decode(encoding or "utf-8", errors="ignore") else: result += text return result def extract_links(text: str) -> list[str]: """ Извлекает все URL из текста. """ pattern = r"https?://[^\s\"'>]+" return re.findall(pattern, text) def html_to_text(html: str) -> str: """ Превращает HTML в обычный текст. """ soup = BeautifulSoup(html, "lxml") return soup.get_text(separator="\n", strip=True) def parse_email(raw_email: bytes) -> EmailMessage: """ Парсит письмо IMAP -> EmailMessage """ msg = message_from_bytes(raw_email) sender = decode_mime_header(msg.get("From")) receiver = decode_mime_header(msg.get("To")) subject = decode_mime_header(msg.get("Subject")) date = decode_mime_header(msg.get("Date")) text = "" html = "" if msg.is_multipart(): for part in msg.walk(): content_type = part.get_content_type() disposition = str(part.get("Content-Disposition")) if "attachment" in disposition: continue try: payload = part.get_payload(decode=True) if payload is None: continue charset = part.get_content_charset() or "utf-8" content = payload.decode(charset, errors="ignore") except Exception: continue if content_type == "text/plain": text += content elif content_type == "text/html": html += content else: payload = msg.get_payload(decode=True) charset = msg.get_content_charset() or "utf-8" content = payload.decode(charset, errors="ignore") if msg.get_content_type() == "text/html": html = content else: text = content if not text and html: text = html_to_text(html) links = extract_links(text) if html: soup = BeautifulSoup(html, "lxml") for a in soup.find_all("a", href=True): links.append(a["href"]) links = list(set(links)) return EmailMessage( sender=sender, receiver=receiver, subject=subject, text=text, html=html, links=links, date=date )