Files
PyRIGS/RIGS/signals.py
Arona Jones 8568c591a9 Update Python Dependencies (#404)
* [requires.io] dependency update

* Server starts...

Various things are broken, but it runs!

* [requires.io] dependency update

* [requires.io] dependency update

* [requires.io] dependency update

* FIX: Broken migrations

* FIX: Update auth framework

* FIX: Correct static use in templates

* FIX: Fix supplier sort

* FIX: Remaining tests

* Revert "Disable password reset as temporary fix to vulnerability (#396)"

This reverts commit e0c6a56263.

# Conflicts:
#	RIGS/urls.py

* FIX: Fix broken newlining in PDFs

Introduced by a change in Django 2.1 'HTML rendered by form widgets no longer includes a closing slash on void elements, e.g. <br>. This is incompatible within XHTML, although some widgets already used aspects of HTML5 such as boolean attributes.'

* FIX: Fix some Django4 deprecation warnings

Why not...

* Refactor dependency file

Should now only include dependencies we actually use, not dependencies of dependencies and unused things

* Add newlines to the paperwork print test event

This will catch the error encountered in 79ec9214f9

* Swap to pycodestyle rather than pep8 in Travis

And eliminate W605 errors

* Bit too heavy handed with the dep purge there...

* Whoops, helps if one installs pycodestyle...

* FIX: Re-add overridden login view

* Better fix for previous commit

* FIX: Bloody smartquotes

Co-authored-by: requires.io <support@requires.io>
2020-03-07 16:21:48 +00:00

141 lines
4.8 KiB
Python

import datetime
import re
import urllib.request
import urllib.error
import urllib.parse
from io import BytesIO
from django.db.models.signals import post_save
from PyPDF2 import PdfFileReader, PdfFileMerger
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.template.loader import get_template
from django.urls import reverse
from django.utils import timezone
from registration.signals import user_activated
from premailer import Premailer
from z3c.rml import rml2pdf
from RIGS import models
def send_eventauthorisation_success_email(instance):
# Generate PDF first to prevent context conflicts
context = {
'object': instance.event,
'fonts': {
'opensans': {
'regular': 'RIGS/static/fonts/OPENSANS-REGULAR.TTF',
'bold': 'RIGS/static/fonts/OPENSANS-BOLD.TTF',
}
},
'receipt': True,
'current_user': False,
}
template = get_template('RIGS/event_print.xml')
merger = PdfFileMerger()
rml = template.render(context)
buffer = rml2pdf.parseString(rml)
merger.append(PdfFileReader(buffer))
buffer.close()
terms = urllib.request.urlopen(settings.TERMS_OF_HIRE_URL)
merger.append(BytesIO(terms.read()))
merged = BytesIO()
merger.write(merged)
# Produce email content
context = {
'object': instance,
}
if instance.event.person is not None and instance.email == instance.event.person.email:
context['to_name'] = instance.event.person.name
elif instance.event.organisation is not None and instance.email == instance.event.organisation.email:
context['to_name'] = instance.event.organisation.name
subject = "N%05d | %s - Event Authorised" % (instance.event.pk, instance.event.name)
client_email = EmailMultiAlternatives(
subject,
get_template("RIGS/eventauthorisation_client_success.txt").render(context),
to=[instance.email],
reply_to=[settings.AUTHORISATION_NOTIFICATION_ADDRESS],
)
css = staticfiles_storage.path('css/email.css')
html = Premailer(get_template("RIGS/eventauthorisation_client_success.html").render(context),
external_styles=css).transform()
client_email.attach_alternative(html, 'text/html')
escapedEventName = re.sub(r'[^a-zA-Z0-9 \n\.]', '', instance.event.name)
client_email.attach('N%05d - %s - CONFIRMATION.pdf' % (instance.event.pk, escapedEventName),
merged.getvalue(),
'application/pdf'
)
if instance.event.mic:
mic_email_address = instance.event.mic.email
else:
mic_email_address = settings.AUTHORISATION_NOTIFICATION_ADDRESS
mic_email = EmailMessage(
subject,
get_template("RIGS/eventauthorisation_mic_success.txt").render(context),
to=[mic_email_address]
)
# Now we have both emails successfully generated, send them out
client_email.send(fail_silently=True)
mic_email.send(fail_silently=True)
# Set event to booked now that it's authorised
instance.event.status = models.Event.BOOKED
instance.event.save()
def on_revision_commit(sender, instance, created, **kwargs):
if created:
send_eventauthorisation_success_email(instance)
post_save.connect(on_revision_commit, sender=models.EventAuthorisation)
def send_admin_awaiting_approval_email(user, request, **kwargs):
# Bit more controlled than just emailing all superusers
for admin in models.Profile.admins():
# Check we've ever emailed them before and if so, if cooldown has passed.
if admin.last_emailed is None or admin.last_emailed + settings.EMAIL_COOLDOWN <= timezone.now():
context = {
'request': request,
'link_suffix': reverse("admin:RIGS_profile_changelist") + '?is_approved__exact=0',
'number_of_users': models.Profile.users_awaiting_approval_count(),
'to_name': admin.first_name
}
email = EmailMultiAlternatives(
"%s new users awaiting approval on RIGS" % (context['number_of_users']),
get_template("RIGS/admin_awaiting_approval.txt").render(context),
to=[admin.email],
reply_to=[user.email],
)
css = staticfiles_storage.path('css/email.css')
html = Premailer(get_template("RIGS/admin_awaiting_approval.html").render(context),
external_styles=css).transform()
email.attach_alternative(html, 'text/html')
email.send()
# Update last sent
admin.last_emailed = timezone.now()
admin.save()
user_activated.connect(send_admin_awaiting_approval_email)