TiBillet-Ticket-Nonfree/DjangoFiles/BaseBillet/tasks.py

170 lines
5.3 KiB
Python

import os
from io import BytesIO
import base64
import segno
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string, get_template
from django.utils import timezone
from BaseBillet.models import Configuration, Reservation, Ticket
from TiBillet.celery import app
import logging
logger = logging.getLogger(__name__)
class CeleryMailerClass():
def __init__(self,
email: str,
title: str,
text=None,
html=None,
template=None,
context=None,
attached_files=None,
):
self.title = title
self.email = email
self.text = text
self.html = html
self.config = Configuration.get_solo()
self.context = context
self.attached_files = attached_files
if template and context:
self.html = render_to_string(template, context=context)
def config_valid(self):
EMAIL_HOST = os.environ.get('EMAIL_HOST')
EMAIL_PORT = os.environ.get('EMAIL_PORT')
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
if EMAIL_HOST and EMAIL_PORT and EMAIL_HOST_USER and EMAIL_HOST_PASSWORD and self.config.email:
return True
else:
return False
def send(self):
if self.html and self.config_valid():
logger.info(f' send_mail')
mail = EmailMultiAlternatives(
self.title,
self.text,
self.config.email,
[self.email, ],
)
mail.attach_alternative(self.html, "text/html")
if self.attached_files:
for filename, file in self.attached_files.items():
mail.attach(filename, file, 'application/pdf')
mail_return = mail.send(fail_silently=False)
if mail_return == 1:
logger.info(f' mail envoyé : {mail_return} - {self.email}')
else:
logger.error(f' mail non envoyé : {mail_return} - {self.email}')
return mail_return
else:
logger.error(f'Pas de contenu HTML ou de configuration email valide')
raise ValueError('Pas de contenu HTML ou de configuration email valide')
def create_ticket_pdf(ticket: Ticket):
qr = segno.make(f'{ticket.uuid}')
buffer_png = BytesIO()
qr.save(buffer_png, kind='PNG', scale=15)
img_str = base64.b64encode(buffer_png.getvalue()).decode('utf-8')
buffer_svg = BytesIO()
qr.save(buffer_svg, kind='svg', scale=10)
context = {
'ticket': ticket,
'config': Configuration.get_solo(),
'img_str': base64.b64encode(buffer_png.getvalue()).decode('utf-8'),
'img_svg': buffer_svg.getvalue().decode('utf-8'),
'img_svg64': base64.b64encode(buffer_svg.getvalue()).decode('utf-8'),
}
template_name = 'ticket/ticket.html'
# template_name = 'ticket/qrtest.html'
font_config = FontConfiguration()
template = get_template(template_name)
html = template.render(context)
css = CSS(string=
'''
@font-face {
font-family: Libre Barcode;
src: url(file:///DjangoFiles/ApiBillet/templates/ticket/librebarcode128-regular.ttf);
}
@font-face {
font-family: Barlow Condensed;
src: url(file:///DjangoFiles/ApiBillet/templates/ticket/barlowcondensed-regular.otf)
}
@font-face {
font-family: Barlow Condensed;
font-weight: 300;
src: url(file:///DjangoFiles/ApiBillet/templates/ticket/barlowcondensed-light.otf);
}
@font-face {
font-family: Barlow Condensed;
font-weight: 700;
src: url(file:///DjangoFiles/ApiBillet/templates/ticket/barlowcondensed-bold.otf);
}
''',
font_config=font_config)
pdf_binary = HTML(string=html).write_pdf(
stylesheets=[css],
font_config=font_config
)
return pdf_binary
@app.task
def ticket_celery_mailer(reservation_uuid: str):
'''
for ticket in reservation.tickets.filter(status=Ticket.NOT_SCANNED):
response = requests.get(ticket.pdf_url())
print(response.status_code)
'''
config = Configuration.get_solo()
reservation = Reservation.objects.get(pk=reservation_uuid)
attached_files = {}
for ticket in reservation.tickets.filter(status=Ticket.NOT_SCANNED):
attached_files[ticket.pdf_filename()] = create_ticket_pdf(ticket)
try:
mail = CeleryMailerClass(
reservation.user_commande.email,
f"Votre reservation pour {config.organisation}",
template='mails/buy_confirmation.html',
context={
'config': config,
'reservation': reservation,
},
attached_files=attached_files,
)
mail.send()
return True
except Exception as e:
logger.error(f"{timezone.now()} Erreur envoie de mail pour reservation {reservation} : {e}")
raise Exception