from django.contrib.staticfiles import finders from django.contrib import messages from django.core.mail import EmailMultiAlternatives, get_connection from django.http import HttpRequest from django.db.models.query import QuerySet from django.utils.safestring import SafeText from django.template.loader import render_to_string from ..models.students import Student from smtplib import SMTPException from email.mime.image import MIMEImage from typing import List def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> None: img: MIMEImage | None = None filename: str candidates = finders.find("cantorair.png") if not candidates: messages.error(request=request, message="Cannot Load CantorAir Logo") return elif isinstance(candidates, list): filename = candidates.pop() else: filename = candidates with open(filename, "rb") as f: img = MIMEImage(f.read()) img.add_header("Content-ID", "logo_image") img.add_header("Content-Disposition", "inline", filename="cantorair.png") # build mail list filling template queryset = queryset.filter(mail_sent=False) mails: List[EmailMultiAlternatives] = [] for student in queryset: if not student.user or not student.email: # skip student if has not an associated user continue try: username: str = student.user.username password: str = student.default_password() address: str = student.email text_message: str = f"Cantor Air Flight Scheduler\nUsername:{username}\nPassword:{password}\n" html_message: SafeText = render_to_string( template_name="email/mail.html", context={"username": username, "password": password} ) mail: EmailMultiAlternatives = EmailMultiAlternatives( subject="CantorAir Flight Scheduler 🛫", from_email="ema.trabattoni@gmail.com", body=text_message, to = [ address ] ) mail.attach(filename=img) mail.attach_alternative(content=html_message, mimetype="text/html") mails.append(mail) student.mail_sent = True student.save() except Exception as e: messages.error(request=request, message=f"General Error: {e}") if len(mails) == 0: messages.warning(request=request, message="No email will be sent") return # Open only one conenction and send mass email try: sent: int = 0 with get_connection() as conn: sent = conn.send_messages(mails) except SMTPException as e: messages.error(request=request, message=f"Send Mail SMTP error: {e.strerror}") except Exception as e: messages.error(request=request, message=f"Send Mail General error: {e}") else: messages.success(request=request, message=f"Successfully sent {sent} messages") return