import io import smtplib import ssl from email.message import EmailMessage from itsdangerous import URLSafeTimedSerializer import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from config import Config from pathlib import Path from weasyprint import HTML def generate_pdf_from_html(html_string, output_path, base_url=None): output_path = Path(output_path) output_path.parent.mkdir(parents=True, exist_ok=True) HTML(string=html_string, base_url=base_url).write_pdf(str(output_path)) return output_path serializer = URLSafeTimedSerializer(Config.SECRET_KEY) def generate_activation_token(email): return serializer.dumps(email, salt='account-activation') def verify_activation_token(token, max_age=86400): return serializer.loads(token, salt='account-activation', max_age=max_age) def send_mail(to_address, subject, body): msg = EmailMessage() msg['Subject'] = subject msg['From'] = Config.MAIL_SENDER msg['To'] = to_address msg.set_content(body) # SMTPS if Config.SMTP_PORT == 465: context = ssl.create_default_context() with smtplib.SMTP_SSL(Config.SMTP_SERVER, Config.SMTP_PORT, context=context) as server: if Config.SMTP_USERNAME: server.login(Config.SMTP_USERNAME, Config.SMTP_PASSWORD) server.send_message(msg) return # Normales SMTP, z. B. Port 25 with smtplib.SMTP(Config.SMTP_SERVER, Config.SMTP_PORT) as server: server.ehlo() if Config.MAIL_USE_TLS: server.starttls(context=ssl.create_default_context()) server.ehlo() if Config.SMTP_USERNAME and Config.SMTP_USERNAME.strip(): server.login(Config.SMTP_USERNAME, Config.SMTP_PASSWORD) server.send_message(msg) def create_assessment_chart(labels, yes_counts, output_path): fig, ax = plt.subplots(figsize=(11, 5)) x_values = list(range(len(labels))) ax.plot(x_values, yes_counts, marker='o') for x, y in zip(x_values, yes_counts): if y >= 7: color = 'green' elif y >= 4: color = 'orange' else: color = 'red' ax.scatter([x], [y], color=color, s=120) ax.set_xticks(x_values) ax.set_xticklabels(labels, rotation=20, ha='right') ax.set_ylim(0, 8) ax.set_ylabel('Anzahl JA-Antworten') ax.set_xlabel('Themen') ax.set_title('Assessment-Ergebnis') ax.grid(True, axis='y', alpha=0.3) fig.tight_layout() fig.savefig(output_path, dpi=150) plt.close(fig) def create_chart_bytes(labels, yes_counts): buffer = io.BytesIO() fig, ax = plt.subplots(figsize=(11, 5)) x_values = list(range(len(labels))) ax.plot(x_values, yes_counts, marker='o') for x, y in zip(x_values, yes_counts): if y >= 7: color = 'green' elif y >= 4: color = 'orange' else: color = 'red' ax.scatter([x], [y], color=color, s=120) ax.set_xticks(x_values) ax.set_xticklabels(labels, rotation=20, ha='right') ax.set_ylim(0, 8) ax.set_ylabel('Anzahl JA-Antworten') ax.set_xlabel('Themen') ax.set_title('Assessment-Ergebnis') ax.grid(True, axis='y', alpha=0.3) fig.tight_layout() fig.savefig(buffer, format='png', dpi=150) plt.close(fig) buffer.seek(0) return buffer