unified mailing

This commit is contained in:
Oliver Zander 2025-10-17 14:51:18 +02:00
parent 1e075fda68
commit 5a5962b619
25 changed files with 54 additions and 94 deletions

View File

@ -2,13 +2,13 @@ from datetime import date, timedelta
from django.core.management import CommandError from django.core.management import CommandError
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.template.loader import get_template
from django.core.mail import BadHeaderError from django.core.mail import BadHeaderError
from django.core.mail import EmailMultiAlternatives
from django.conf import settings from django.conf import settings
from input.models import Project, Library, HonoraryCertificate, Travel, Email,\ from input.models import Project, Library, HonoraryCertificate, Travel, Email,\
BusinessCard, List, IFG, Literature BusinessCard, List, IFG, Literature
from input.utils.mail import send_email
class Command(BaseCommand): class Command(BaseCommand):
''' mails will be sent here: ''' mails will be sent here:
@ -34,15 +34,11 @@ class Command(BaseCommand):
'name': name, 'name': name,
'pid': pid, 'pid': pid,
'SURVEY_PREFIX': settings.SURVEY_PREFIX, } 'SURVEY_PREFIX': settings.SURVEY_PREFIX, }
txt_mail_template = get_template('input/survey_mail.txt')
html_mail_template = get_template('input/survey_mail.html') subject = 'Dein Feedback zur Förderung durch Wikimedia Deutschland'
try: try:
subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', settings.IF_EMAIL, email send_email('survey_mail', context, subject, email, bcc=[settings.SURVEY_EMAIL])
text_content = txt_mail_template.render(context)
html_content = html_mail_template.render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[settings.SURVEY_EMAIL])
msg.attach_alternative(html_content, "text/html")
msg.send()
#print('survey mail would have been send') #print('survey mail would have been send')
#survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland', #survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland',
@ -70,21 +66,14 @@ class Command(BaseCommand):
.exclude(end_mail_send = True)\ .exclude(end_mail_send = True)\
.filter(mail_state = 'NONE') .filter(mail_state = 'NONE')
txt_mail_template = get_template('input/if_end_of_project.txt') subject = 'Projektende erreicht'
html_mail_template = get_template('input/if_end_of_project.html') recipient = settings.IF_EMAIL
for project in old: for project in old:
context = {'project': project} context = {'project': project, 'URL_PREFIX': settings.EMAIL_URL_PREFIX}
context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX
try: try:
subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, settings.IF_EMAIL send_email('if_end_of_project', context, subject, recipient)
text_content = txt_mail_template.render(context)
html_content = html_mail_template.render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
#print('end of project mail would have been sent') #print('end of project mail would have been sent')
#send_mail('Projektende erreicht', #send_mail('Projektende erreicht',
@ -110,33 +99,19 @@ class Command(BaseCommand):
approved_end = Project.objects.filter(status = 'END')\ approved_end = Project.objects.filter(status = 'END')\
.exclude(end_mail_send = True)\ .exclude(end_mail_send = True)\
.filter(mail_state = 'INF') .filter(mail_state = 'INF')
txt_mail_template = get_template('input/if_end_of_project_approved.txt')
html_mail_template = get_template('input/if_end_of_project_approved.html')
txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt')
html_informMail_template = get_template('input/if_end_of_project_orginformed.html')
# send the mail to project.email, which would be the mail of the volunteer filling out the form # send the mail to project.email, which would be the mail of the volunteer filling out the form
for project in approved_end: for project in approved_end:
context = {'project': project} context = {'project': project, 'URL_PREFIX': settings.EMAIL_URL_PREFIX}
context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX
try: try:
subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, project.email send_email('if_end_of_project_approved', context, 'Projektende erreicht', project.email)
text_content = txt_mail_template.render(context)
html_content = html_mail_template.render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
#print('if and of project approved mail would have been sent') #print('if and of project approved mail would have been sent')
inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', settings.IF_EMAIL, settings.IF_EMAIL send_email('if_end_of_project_orginformed', context, 'Projektorganisator*in wurde informiert', settings.IF_EMAIL)
inform_text_content = txt_informMail_template.render(context)
inform_html_content = html_informMail_template.render(context)
inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to])
inform_msg.attach_alternative(html_content, "text/html")
inform_msg.send()
#print('if end of project orginformed mail would have been sent') #print('if end of project orginformed mail would have been sent')
#send_mail('Projektende erreicht', #send_mail('Projektende erreicht',
@ -168,25 +143,15 @@ class Command(BaseCommand):
.exclude(end_mail_send = True)\ .exclude(end_mail_send = True)\
.filter(mail_state = 'INF') .filter(mail_state = 'INF')
html_mail_template = get_template('input/if_not_of_project_approved.html')
txt_mail_template = get_template('input/if_not_of_project_approved.txt')
txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt')
html_informMail_template = get_template('input/if_end_of_project_orginformed.html')
# send the mail to project.email, which would be the mail of the volunteer that filled out the form # send the mail to project.email, which would be the mail of the volunteer that filled out the form
for project in approved_notHappened: for project in approved_notHappened:
context = {'project': project} context = {'project': project, 'URL_PREFIX': settings.EMAIL_URL_PREFIX}
context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX
try:
subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, project.email
text_content = txt_mail_template.render(context)
html_content = html_mail_template.render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
#print('if not of project approved end mail would have been sent')
try:
send_email('if_not_of_project_approved', context, 'Projektende erreicht', project.email)
#print('if not of project approved end mail would have been sent')
#send_mail('Projektende erreicht', #send_mail('Projektende erreicht',
# mail_template.render(context), # mail_template.render(context),
@ -194,12 +159,8 @@ class Command(BaseCommand):
# [project.email], # [project.email],
# fail_silently=False) # fail_silently=False)
inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', settings.IF_EMAIL, settings.IF_EMAIL send_email('if_end_of_project_orginformed', context, 'Projektorganisator*in wurde informiert', settings.IF_EMAIL)
inform_text_content = txt_informMail_template.render(context)
inform_html_content = html_informMail_template.render(context)
inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to])
inform_msg.attach_alternative(html_content, "text/html")
inform_msg.send()
#print('if not of project approved end mail orginformed would have been sent') #print('if not of project approved end mail orginformed would have been sent')
#send_mail('Projektorganisator*in wurde informiert', #send_mail('Projektorganisator*in wurde informiert',

View File

@ -8,6 +8,8 @@ from input.models import TYPE_CHOICES
from .attachments import collect_attachment_paths, attach_files from .attachments import collect_attachment_paths, attach_files
__all__ = [ __all__ = [
'build_email',
'send_email',
'collect_attachment_paths', 'collect_attachment_paths',
'attach_files', 'attach_files',
'send_decision_mail', 'send_decision_mail',
@ -15,6 +17,27 @@ __all__ = [
] ]
def build_email(template_name: str, context: dict, subject: str, *recipients: str, **kwargs):
body = get_template(f'mails/{template_name}.txt').render(context)
html = get_template(f'mails/{template_name}.html').render(context)
kwargs.setdefault('from_email', settings.IF_EMAIL)
kwargs['subject'] = subject
kwargs['body'] = body
kwargs['to'] = recipients
email = EmailMultiAlternatives(**kwargs)
email.attach_alternative(html, 'text/html')
return email
def send_email(template_name: str, context: dict, subject: str, *recipients: str, fail_silently=False, **kwargs):
return build_email(template_name, context, subject, *recipients, **kwargs).send(fail_silently)
def _type_labels(choice: str): def _type_labels(choice: str):
""" """
Resolve the human-readable type label. Resolve the human-readable type label.
@ -53,23 +76,13 @@ def send_decision_mail(obj, choice_code: str, granted: bool) -> None:
return # no recipient -> skip return # no recipient -> skip
ctx = _decision_context(obj, choice_code) ctx = _decision_context(obj, choice_code)
base = 'input/approval_granted' if granted else 'input/approval_denied' template_suffix = 'granted' if granted else 'denied'
project_name = getattr(obj, 'name', None) or '(ohne Projektnamen)' project_name = getattr(obj, 'name', None) or '(ohne Projektnamen)'
decision_word = 'bewilligt' if granted else 'abgelehnt' decision_word = 'bewilligt' if granted else 'abgelehnt'
subject = f'Deine Förderanfrage „{project_name} {decision_word}' subject = f'Deine Förderanfrage „{project_name} {decision_word}'
txt = get_template(f'{base}.txt').render(ctx) return send_email(f'approval_{template_suffix}', ctx, subject, recipient)
html = get_template(f'{base}.html').render(ctx)
msg = EmailMultiAlternatives(
subject,
txt,
settings.IF_EMAIL,
[recipient],
)
msg.attach_alternative(html, 'text/html')
msg.send()
def send_staff_decision_mail(obj, choice_code: str, granted: bool) -> None: def send_staff_decision_mail(obj, choice_code: str, granted: bool) -> None:
@ -78,20 +91,10 @@ def send_staff_decision_mail(obj, choice_code: str, granted: bool) -> None:
Uses: input/approval_granted_staff.(txt|html) or input/approval_denied_staff.(txt|html) Uses: input/approval_granted_staff.(txt|html) or input/approval_denied_staff.(txt|html)
""" """
ctx = _decision_context(obj, choice_code) ctx = _decision_context(obj, choice_code)
base = 'input/approval_granted_staff' if granted else 'input/approval_denied_staff' template_suffix = 'granted' if granted else 'denied'
project_name = getattr(obj, 'name', None) or '(ohne Projektnamen)' project_name = getattr(obj, 'name', None) or '(ohne Projektnamen)'
decision_word = 'bewilligt' if granted else 'abgelehnt' decision_word = 'bewilligt' if granted else 'abgelehnt'
subject = f'Entscheidung: {project_name} ({decision_word})' subject = f'Entscheidung: {project_name} ({decision_word})'
txt = get_template(f'{base}.txt').render(ctx) return send_email(f'approval_{template_suffix}_staff', ctx, subject, settings.IF_EMAIL)
html = get_template(f'{base}.html').render(ctx)
msg = EmailMultiAlternatives(
subject,
txt,
settings.IF_EMAIL,
[settings.IF_EMAIL],
)
msg.attach_alternative(html, 'text/html')
msg.send()

View File

@ -5,15 +5,14 @@ from django.shortcuts import render
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.core.mail import BadHeaderError, EmailMultiAlternatives from django.core.mail import BadHeaderError
from django.template.loader import get_template
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.utils.html import strip_tags from django.utils.html import strip_tags
from input.utils.mail import collect_attachment_paths, attach_files from input.utils.mail import collect_attachment_paths, attach_files, build_email
from .forms import ( from .forms import (
BaseApplicationForm, BaseApplicationForm,
@ -288,16 +287,13 @@ class ApplicationView(FormView):
obj.delete() obj.delete()
return HttpResponse('Error in sending mails (probably wrong address?). Data not saved!') return HttpResponse('Error in sending mails (probably wrong address?). Data not saved!')
def send_email(self, kind, template_name, subject, recipient, context): def send_email(self, kind, template_name, subject, recipient, context, *, fail_silently=False):
plain = get_template(f'input/{template_name}.txt').render(context) email = build_email(template_name, context, subject, recipient)
html = get_template(f'input/{template_name}.html').render(context)
email = EmailMultiAlternatives(subject, plain, settings.IF_EMAIL, [recipient])
applicant_files = collect_attachment_paths(kind=kind, choice=self.type_code) applicant_files = collect_attachment_paths(kind=kind, choice=self.type_code)
email.attach_alternative(html, 'text/html')
attach_files(email, applicant_files) attach_files(email, applicant_files)
return email.send() return email.send(fail_silently)
@staticmethod @staticmethod
def get_recipient_name(obj, data): def get_recipient_name(obj, data):