from itertools import groupby from django.core import mail from django.core.mail.message import sanitize_address from django.contrib.auth import get_user_model from django.template import loader from markdownify import markdownify import mdformat def make_multipart_email(subject, html_body, to): plain_body = mdformat.text(markdownify(html_body), extensions={"tables"}) email = mail.EmailMultiAlternatives( subject, plain_body, "Claremont MakerSpace Member Certification System ", to, reply_to=["Claremont MakerSpace "], ) email.attach_alternative(html_body, "text/html") return email def make_department_email(department, certifications): template = loader.get_template("paperwork/email/department_certifications.dj.html") shop_leads = department.shop_lead_flag.members.values_list( "first_name", "account_name", "email", named=True ) html_body = template.render( { "shop_lead_names": [shop_lead.first_name for shop_lead in shop_leads], "department": department, "certifications": certifications, } ) return make_multipart_email( f"{len(certifications)} new CMS Certifications issued for {department}", html_body, to=[ sanitize_address((shop_lead.account_name, shop_lead.email), "ascii") for shop_lead in shop_leads ], ) def department_emails(ordered_queryset): certifications_by_department = groupby( ordered_queryset, lambda c: c.certification_version.definition.department ) for department, certifications in certifications_by_department: if department.shop_lead_flag is not None: yield make_department_email(department, list(certifications)) def make_member_email(member, certifications): template = loader.get_template("paperwork/email/member_certifications.dj.html") html_body = template.render({"member": member, "certifications": certifications}) return make_multipart_email( f"You have been issued {len(certifications)} new CMS Certifications", html_body, to=[sanitize_address((member.account_name, member.email), "ascii")], ) def member_emails(ordered_queryset): certifications_by_member = groupby( ordered_queryset.filter(member__isnull=False), lambda c: c.member ) for member, certifications in certifications_by_member: yield make_member_email(member, list(certifications)) def admin_email(ordered_queryset): template = loader.get_template("paperwork/email/admin_certifications.dj.html") html_body = template.render({"certifications": ordered_queryset}) return make_multipart_email( f"{len(ordered_queryset)} new CMS Certifications issued", html_body, to=( get_user_model() .objects.with_perm( "paperwork.receive_certification_emails", include_superusers=False, # TODO: backend should not be hardcoded # TODO: LDAPBackend does not support with_perm() directly backend="django.contrib.auth.backends.ModelBackend", ) .values_list("email", flat=True) ), ) def all_certification_emails(queryset): ordered_queryset = queryset.select_related( "certification_version__definition" ).order_by("certification_version__definition__department") yield from department_emails(ordered_queryset) yield from member_emails(ordered_queryset) yield admin_email(ordered_queryset)