def send_publish_notifications(courses, template=None): from evap.evaluation.models import EmailTemplate publish_notifications = defaultdict(set) if not template: template = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE) for course in courses: # for published courses all contributors and participants get a notification if course.can_publish_grades: for participant in course.participants.all(): publish_notifications[participant].add(course) for contribution in course.contributions.all(): if contribution.contributor: publish_notifications[contribution.contributor].add(course) # if a course was not published notifications are only sent for contributors who can see comments elif len(course.textanswer_set) > 0: for textanswer in course.textanswer_set: if textanswer.contribution.contributor: publish_notifications[textanswer.contribution.contributor].add(course) for contributor in course.responsible_contributors: publish_notifications[contributor].add(course) for user, course_set in publish_notifications.items(): body_params = {'user': user, 'courses': list(course_set)} EmailTemplate.send_to_user(user, template, {}, body_params, use_cc=True)
def send(self, request, courses): recipient = self.cleaned_data.get('to') self.template.subject = self.cleaned_data.get('subject') self.template.body = self.cleaned_data.get('body') subject_params = {} body_params = {'user': recipient, 'courses': courses} EmailTemplate.send_to_user(recipient, self.template, subject_params, body_params, use_cc=True, request=request)
def send(self, request, courses): recipient = self.cleaned_data.get('to') self.template.subject = self.cleaned_data.get('subject') self.template.body = self.cleaned_data.get('body') subject_params = {} body_params = {'user': recipient, 'courses': courses} EmailTemplate.send_to_user(recipient, self.template, subject_params, body_params, use_cc=True, request=request)
def send_publish_notifications(courses, template=None): from evap.evaluation.models import EmailTemplate publish_notifications = defaultdict(set) if not template: template = EmailTemplate.objects.get( name=EmailTemplate.PUBLISHING_NOTICE) for course in courses: # for courses with published averaged grade, all contributors and participants get a notification # we don't send a notification if the significance threshold isn't met if course.can_publish_average_grade: for participant in course.participants.all(): publish_notifications[participant].add(course) for contribution in course.contributions.all(): if contribution.contributor: publish_notifications[contribution.contributor].add(course) # if the average grade was not published, notifications are only sent for contributors who can see text answers elif course.textanswer_set: for textanswer in course.textanswer_set: if textanswer.contribution.contributor: publish_notifications[ textanswer.contribution.contributor].add(course) for contributor in course.responsible_contributors: publish_notifications[contributor].add(course) for user, course_set in publish_notifications.items(): body_params = {'user': user, 'courses': list(course_set)} EmailTemplate.send_to_user(user, template, {}, body_params, use_cc=True)
def send_publish_notifications(courses, template=None): from evap.evaluation.models import EmailTemplate publish_notifications = defaultdict(set) if not template: template = EmailTemplate.objects.get( name=EmailTemplate.PUBLISHING_NOTICE) for course in courses: # for published courses all contributors and participants get a notification if course.can_publish_grades: for participant in course.participants.all(): publish_notifications[participant].add(course) for contribution in course.contributions.all(): if contribution.contributor: publish_notifications[contribution.contributor].add(course) # if a course was not published notifications are only sent for contributors who can see comments elif len(course.textanswer_set) > 0: for textanswer in course.textanswer_set: if textanswer.contribution.contributor: publish_notifications[ textanswer.contribution.contributor].add(course) for contributor in course.responsible_contributors: publish_notifications[contributor].add(course) for user, course_set in publish_notifications.items(): body_params = {'user': user, 'courses': list(course_set)} EmailTemplate.send_to_user(user, template, {}, body_params, use_cc=True)
def send_publish_notifications(courses, template=None): from evap.evaluation.models import EmailTemplate publish_notifications = defaultdict(set) if not template: template = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE) for course in courses: # for courses with published averaged grade, all contributors and participants get a notification # we don't send a notification if the significance threshold isn't met if course.can_publish_average_grade: for participant in course.participants.all(): publish_notifications[participant].add(course) for contribution in course.contributions.all(): if contribution.contributor: publish_notifications[contribution.contributor].add(course) # if the average grade was not published, notifications are only sent for contributors who can see text answers elif course.textanswer_set: for textanswer in course.textanswer_set: if textanswer.contribution.contributor: publish_notifications[textanswer.contribution.contributor].add(course) for contributor in course.responsible_contributors: publish_notifications[contributor].add(course) for user, course_set in publish_notifications.items(): body_params = {'user': user, 'courses': list(course_set)} EmailTemplate.send_to_user(user, template, {}, body_params, use_cc=True)
def evaluation_direct_delegation(request, evaluation_id): delegate_user_id = request.POST.get("delegate_to") evaluation = get_object_or_404(Evaluation, id=evaluation_id) delegate_user = get_object_or_404(UserProfile, id=delegate_user_id) Contribution.objects.update_or_create(evaluation=evaluation, contributor=delegate_user, defaults={'can_edit': True}) template = EmailTemplate.objects.get(name=EmailTemplate.DIRECT_DELEGATION) subject_params = { "evaluation": evaluation, "user": request.user, "delegate_user": delegate_user } body_params = subject_params # we don't provide the request here since send_to_user only uses it to display a warning message in case the user does not have # an email address. In this special case, we don't want that warning. Instead, we want a mail to the admins. EmailTemplate.send_to_user(delegate_user, template, subject_params, body_params, use_cc=True, additional_cc_user=request.user) messages.add_message( request, messages.SUCCESS, _('{} was added as a contributor for evaluation "{}" and was sent an email with further information.' ).format(str(delegate_user), str(evaluation))) return redirect('contributor:index')
def evaluation_direct_delegation(request, evaluation_id): delegate_user_id = request.POST.get("delegate_to") evaluation = get_object_or_404(Evaluation, id=evaluation_id) delegate_user = get_object_or_404(UserProfile, id=delegate_user_id) contribution, created = Contribution.objects.update_or_create(evaluation=evaluation, contributor=delegate_user, defaults={'can_edit': True}) if created: contribution.order = evaluation.contributions.all().aggregate(Max('order'))['order__max'] + 1 contribution.save() template = EmailTemplate.objects.get(name=EmailTemplate.DIRECT_DELEGATION) subject_params = {"evaluation": evaluation, "user": request.user, "delegate_user": delegate_user} body_params = subject_params # we don't provide the request here since send_to_user only uses it to display a warning message in case the user does not have # an email address. In this special case, we don't want that warning. Instead, we want a mail to the admins. EmailTemplate.send_to_user(delegate_user, template, subject_params, body_params, use_cc=True, additional_cc_user=request.user) messages.add_message( request, messages.SUCCESS, _('{} was added as a contributor for evaluation "{}" and was sent an email with further information.').format(str(delegate_user), str(evaluation)) ) return redirect('contributor:index')
def test_copy_plain_content_on_empty_html_content(self): template = EmailTemplate( subject="Example", plain_content="Example plain content\nWith newline", html_content="" ) template.send_to_user(self.user, {}, {}, False) self.assertEqual(mail.outbox[0].body, "Example plain content\nWith newline") self.assertIn("Example plain content<br />With newline", mail.outbox[0].alternatives[0][0])
def test_missing_email_address(self): """ Tests that __send_to_user behaves when the user has no email address. Regression test to https://github.com/fsr-itse/EvaP/issues/825 """ user = mommy.make(UserProfile, email=None) template = EmailTemplate.objects.get(name=EmailTemplate.STUDENT_REMINDER) EmailTemplate.send_to_user(user, template, {}, {}, False, None)
def test_escape_special_characters_in_html_email(self): template = EmailTemplate( subject="<h1>Special Email</h1>", plain_content="Example plain content", html_content="Special Content: {{special_content}}", ) template.send_to_user(self.user, {}, {"special_content": "0 < 1"}, False) self.assertIn("<h1>Special Email</h1>", mail.outbox[0].alternatives[0][0]) self.assertIn("Special Content: 0 < 1", mail.outbox[0].alternatives[0][0])
def test_send_multi_alternatives_email(self): template = EmailTemplate( subject="Example", plain_content="Example plain content", html_content="<p>Example html content</p>" ) template.send_to_user(self.user, {}, {}, False) self.assertEqual(len(mail.outbox), 1) self.assertTrue(isinstance(mail.outbox[0], mail.message.EmailMultiAlternatives)) self.assertEqual(mail.outbox[0].body, "Example plain content") self.assertEqual(len(mail.outbox[0].alternatives), 1) self.assertEqual(mail.outbox[0].alternatives[0][1], "text/html") self.assertIn("<p>Example html content</p>", mail.outbox[0].alternatives[0][0])
def test_plain_content_escaped_and_copied_on_empty_html_content(self): template = EmailTemplate(subject="Subject <>&", plain_content="A\nB <>& {{ some_var }}", html_content="") template.send_to_user(self.user, {}, {"some_var": "0 < 1"}, False) self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0] self.assertEqual(message.alternatives[0][1], "text/html") html_content = message.alternatives[0][0] self.assertEqual("Subject <>&", message.subject) self.assertEqual("A\nB <>& 0 < 1", message.body) self.assertIn("A<br>B <>& 0 < 1\n", html_content) self.assertNotIn("<>&", html_content)
def test_escaping_with_html_content(self): template = EmailTemplate( subject="Subject <>&", plain_content="A\nB <>& {{ some_var }}", html_content="Html content &<br/> {{ some_var }}", ) template.send_to_user(self.user, {}, {"some_var": "0 < 1"}, False) self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0] self.assertEqual(message.alternatives[0][1], "text/html") html_content = message.alternatives[0][0] self.assertEqual("Subject <>&", message.subject) self.assertEqual("A\nB <>& 0 < 1", message.body) self.assertIn("Html content &<br/> 0 < 1", html_content) self.assertNotIn("<>&", html_content)
def send_publish_notifications(evaluations, template_contributor=USE_DEFAULT, template_participant=USE_DEFAULT): from evap.evaluation.models import EmailTemplate if template_contributor == USE_DEFAULT: template_contributor = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE_CONTRIBUTOR) if template_participant == USE_DEFAULT: template_participant = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE_PARTICIPANT) evaluations_for_contributors = defaultdict(set) evaluations_for_participants = defaultdict(set) for evaluation in evaluations: # for evaluations with published averaged grade, all contributors and participants get a notification # we don't send a notification if the significance threshold isn't met if evaluation.can_publish_average_grade: if template_contributor: for contribution in evaluation.contributions.all(): if contribution.contributor: evaluations_for_contributors[contribution.contributor].add(evaluation) if template_participant: for participant in evaluation.participants.all(): evaluations_for_participants[participant].add(evaluation) # if the average grade was not published, notifications are only sent for contributors who can see text answers elif evaluation.textanswer_set and template_contributor: for textanswer in evaluation.textanswer_set: if textanswer.contribution.contributor: evaluations_for_contributors[textanswer.contribution.contributor].add(evaluation) for contributor in evaluation.course.responsibles.all(): evaluations_for_contributors[contributor].add(evaluation) assert(not evaluations_for_contributors or template_contributor) assert(not evaluations_for_participants or template_participant) for contributor, evaluation_set in evaluations_for_contributors.items(): body_params = {'user': contributor, 'evaluations': list(evaluation_set)} EmailTemplate.send_to_user(contributor, template_contributor, {}, body_params, use_cc=True) for participant, evaluation_set in evaluations_for_participants.items(): body_params = {'user': participant, 'evaluations': list(evaluation_set)} EmailTemplate.send_to_user(participant, template_participant, {}, body_params, use_cc=True)
def send_publish_notifications(evaluations, template_contributor=USE_DEFAULT, template_participant=USE_DEFAULT): from evap.evaluation.models import EmailTemplate if template_contributor == USE_DEFAULT: template_contributor = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE_CONTRIBUTOR) if template_participant == USE_DEFAULT: template_participant = EmailTemplate.objects.get(name=EmailTemplate.PUBLISHING_NOTICE_PARTICIPANT) evaluations_for_contributors = defaultdict(set) evaluations_for_participants = defaultdict(set) for evaluation in evaluations: # for evaluations with published averaged grade, all contributors and participants get a notification # we don't send a notification if the significance threshold isn't met if evaluation.can_publish_average_grade: if template_contributor: for contribution in evaluation.contributions.all(): if contribution.contributor: evaluations_for_contributors[contribution.contributor].add(evaluation) if template_participant: for participant in evaluation.participants.all(): evaluations_for_participants[participant].add(evaluation) # if the average grade was not published, notifications are only sent for contributors who can see text answers elif evaluation.textanswer_set and template_contributor: for textanswer in evaluation.textanswer_set: if textanswer.contribution.contributor: evaluations_for_contributors[textanswer.contribution.contributor].add(evaluation) for contributor in evaluation.course.responsibles.all(): evaluations_for_contributors[contributor].add(evaluation) assert(not evaluations_for_contributors or template_contributor) assert(not evaluations_for_participants or template_participant) for contributor, evaluation_set in evaluations_for_contributors.items(): body_params = {'user': contributor, 'evaluations': list(evaluation_set)} EmailTemplate.send_to_user(contributor, template_contributor, {}, body_params, use_cc=True) for participant, evaluation_set in evaluations_for_participants.items(): body_params = {'user': participant, 'evaluations': list(evaluation_set)} EmailTemplate.send_to_user(participant, template_participant, {}, body_params, use_cc=True)