import os
import re
import fitz
from pathlib import Path
from datetime import datetime
ALL_DIR = Path("/home/matrixhasyou/mutt/exported_emails/all")
OUTPUT_HTML = Path("/home/matrixhasyou/mutt/chronology.html")
def parse_pdf(filepath):
try:
doc = fitz.open(filepath)
text = ""
for page_num in range(min(5, len(doc))):
text += doc[page_num].get_text()
doc.close()
return text
except Exception as e:
return ""
def is_valid_reply(text):
text_lower = text.lower()
formal_markers = [
'ваше обращение рассмотрено', 'сообщаем вам', 'уведомляем',
'в соответствии с', 'в пределах компетенции',
'направляем в ваш адрес', 'в рамках действующего',
'разъясняем', 'доводим до вашего сведения',
'отказано', 'рассмотрев ваше', 'информация предоставляется'
]
substantive_markers = [
'удовлетворено', 'приняты меры', 'выявлены нарушения',
'обязать устранить', 'проведена проверка', 'выдано предписание',
'штраф наложен', 'материалы переданы', 'перерасчет', 'исполнено'
]
indicators = ['ответ на обращение', 'рассмотрение', 'сообщаем', 'уведомляем', 'обращение', 'запрос']
if any(kw in text_lower for kw in formal_markers + substantive_markers + indicators):
return True
return False
def extract_meta_from_text(text):
date_match = re.search(r'Date:\s*(.*?)\n', text)
from_match = re.search(r'From:\s*(.*?)\n', text)
to_match = re.search(r'To:\s*(.*?)\n', text)
subject_match = re.search(r'Subject:\s*(.*?)\n', text)
return {
'date': date_match.group(1).strip() if date_match else "",
'from': from_match.group(1).strip() if from_match else "",
'to': to_match.group(1).strip() if to_match else "",
'subject': subject_match.group(1).strip() if subject_match else ""
}
def clean_text_for_html(text):
# Убираем технические заголовки из начала текста, если они есть
lines = text.split('\n')
cleaned = []
in_headers = True
for line in lines:
if in_headers and (line.startswith('From:') or line.startswith('To:') or line.startswith('Date:') or line.startswith('Subject:') or line.startswith('Message-ID:')):
continue
if line.strip() == '':
if in_headers: continue
in_headers = False
cleaned.append(line)
res = "\n".join(cleaned).strip()
# Ограничиваем длину текста
if len(res) > 2000:
res = res[:2000] + "...\n[ТЕКСТ СОКРАЩЕН]"
# Escape HTML
res = res.replace("&", "&").replace("<", "<").replace(">", ">")
# Convert newlines to br
res = res.replace("\n", "
")
return res
all_emails = []
stats = {'sent': 0, 'replies': 0, 'skipped': 0}
print("Parsing emails...")
for f in ALL_DIR.glob("*.pdf"):
parts = f.stem.split('_', 3)
if len(parts) < 4: continue
domain = parts[0]
date_str = parts[1]
sender = parts[2]
subject = parts[3]
if sender.lower() in ['no-reply', 'noreply', 'notification']:
stats['skipped'] += 1
continue
text = parse_pdf(f)
if not text.strip(): continue
meta = extract_meta_from_text(text)
is_sent = False
if sender == 'ktybdsq' or 'ktybdsq@gmail.com' in meta['from'].lower():
is_sent = True
if is_sent:
stats['sent'] += 1
all_emails.append({'file': f.name, 'date': date_str, 'subject': subject, 'text': text, 'meta': meta, 'is_sent': True})
else:
if is_valid_reply(text):
stats['replies'] += 1
all_emails.append({'file': f.name, 'date': date_str, 'subject': subject, 'text': text, 'meta': meta, 'is_sent': False})
else:
stats['skipped'] += 1
print(f"Stats: {stats}")
all_emails.sort(key=lambda x: x['date'])
# Generate HTML
html = """
Архив юридически значимой переписки с контролирующими органами.