segno qr code
This commit is contained in:
parent
40eb9c3ad2
commit
f0ec02c295
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div>
|
||||||
|
{{ img_svg | safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ img_svg64 }}">
|
||||||
|
fallback
|
||||||
|
</object>
|
||||||
|
|
@ -3,21 +3,202 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="{% static 'ticket/ticket.css' %}"/>
|
|
||||||
|
|
||||||
<title>Boarding ticket</title>
|
<title>Boarding ticket</title>
|
||||||
<meta name="description" content="Boarding ticket">
|
<meta name="description" content="Boarding ticket">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: Libre Barcode;
|
||||||
|
src: url(librebarcode128-regular.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
src: url(barlowcondensed-regular.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(barlowcondensed-light.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(barlowcondensed-bold.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
margin: 0;
|
||||||
|
size: landscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
font-family: Barlow Condensed, sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #eef1f5;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
columns: 4;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-size: 9pt;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations h1 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 25pt;
|
||||||
|
font-weight: 300;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #name {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #destination {
|
||||||
|
position: absolute;
|
||||||
|
right: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dl {
|
||||||
|
background: #2A3239;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1cm 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd {
|
||||||
|
border-left: 1pt solid #fff;
|
||||||
|
font-size: 35pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations ul {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li {
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0.15cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:first-of-type {
|
||||||
|
background: #2A3239;
|
||||||
|
border-radius: 4pt;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:last-of-type {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
color: black;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: 1cm;
|
||||||
|
padding-top: 0.5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket {
|
||||||
|
border-left: 1pt dashed #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket h2 {
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket p {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket dl {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket li {
|
||||||
|
margin: 0 0.25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div>
|
||||||
|
{{ img_svg | safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<section id="informations">
|
<section id="informations">
|
||||||
<h1 id="name">{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
<h1 id="name">{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
||||||
<h1 id="destination">{{ ticket.reservation.event.name }}</h1>
|
<h1 id="destination">{{ ticket.reservation.event.name }}</h1>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Flight</dt>
|
<dt>IMG</dt>
|
||||||
<dd>DL31</dd>
|
<dd>Prout</dd>
|
||||||
<dt>Gate</dt>
|
<dt>Gate</dt>
|
||||||
<dd>29</dd>
|
<dd>img_svg</dd>
|
||||||
<dt>Seat</dt>
|
<dt>Seat</dt>
|
||||||
<dd>26E</dd>
|
<dd>26E</dd>
|
||||||
<dt>Zone</dt>
|
<dt>Zone</dt>
|
||||||
|
|
@ -32,7 +213,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="ticket">
|
<section id="ticket">
|
||||||
<p>1257797706706</p>
|
<p>proutproutprout</p>
|
||||||
<h2>{{ ticket.first_name }} {{ ticket.last_name }}</h2>
|
<h2>{{ ticket.first_name }} {{ ticket.last_name }}</h2>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Flight</dt>
|
<dt>Flight</dt>
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,13 @@ class TicketPdf(WeasyTemplateView):
|
||||||
kwargs['ticket'] = ticket
|
kwargs['ticket'] = ticket
|
||||||
kwargs['config'] = self.config
|
kwargs['config'] = self.config
|
||||||
|
|
||||||
|
'''
|
||||||
|
context = {
|
||||||
|
'ticket': ticket,
|
||||||
|
'config': config,
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
self.pdf_filename = ticket.pdf_filename()
|
self.pdf_filename = ticket.pdf_filename()
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# Create your tasks here
|
|
||||||
|
|
||||||
|
|
@ -7,6 +7,7 @@ from django.utils import timezone
|
||||||
|
|
||||||
from ApiBillet.thread_mailer import ThreadMaileur
|
from ApiBillet.thread_mailer import ThreadMaileur
|
||||||
from BaseBillet.models import Reservation, LigneArticle, Ticket, Product, Configuration, Paiement_stripe
|
from BaseBillet.models import Reservation, LigneArticle, Ticket, Product, Configuration, Paiement_stripe
|
||||||
|
from BaseBillet.tasks import ticket_celery_mailer
|
||||||
|
|
||||||
from TiBillet import settings
|
from TiBillet import settings
|
||||||
|
|
||||||
|
|
@ -127,7 +128,6 @@ def check_paid(old_instance, new_instance):
|
||||||
# def send_billet_to_mail(sender, instance: Reservation, **kwargs):
|
# def send_billet_to_mail(sender, instance: Reservation, **kwargs):
|
||||||
def send_billet_to_mail(old_instance, new_instance):
|
def send_billet_to_mail(old_instance, new_instance):
|
||||||
# On active les tickets
|
# On active les tickets
|
||||||
urls_for_attached_files = {}
|
|
||||||
if new_instance.tickets:
|
if new_instance.tickets:
|
||||||
# On prend aussi ceux qui sont déja activé ( avec les Q() )
|
# On prend aussi ceux qui sont déja activé ( avec les Q() )
|
||||||
# pour pouvoir les envoyer par mail en cas de nouvelle demande
|
# pour pouvoir les envoyer par mail en cas de nouvelle demande
|
||||||
|
|
@ -136,33 +136,16 @@ def send_billet_to_mail(old_instance, new_instance):
|
||||||
ticket.status = Ticket.NOT_SCANNED
|
ticket.status = Ticket.NOT_SCANNED
|
||||||
ticket.save()
|
ticket.save()
|
||||||
|
|
||||||
# on rajoute les urls du pdf pour le thread async
|
|
||||||
urls_for_attached_files[ticket.pdf_filename()] = ticket.pdf_url()
|
|
||||||
|
|
||||||
# import ipdb; ipdb.set_trace()
|
# import ipdb; ipdb.set_trace()
|
||||||
# On vérifie qu'on a pas déja envoyé le mail
|
# On vérifie qu'on a pas déja envoyé le mail
|
||||||
if not new_instance.mail_send :
|
if not new_instance.mail_send :
|
||||||
logger.info(f" TRIGGER RESERVATION send_billet_to_mail {new_instance.status}")
|
logger.info(f" TRIGGER RESERVATION send_billet_to_mail {new_instance.status}")
|
||||||
new_instance : Reservation
|
new_instance : Reservation
|
||||||
config = Configuration.get_solo()
|
|
||||||
|
|
||||||
if new_instance.user_commande.email:
|
if new_instance.user_commande.email:
|
||||||
try:
|
|
||||||
mail = ThreadMaileur(
|
|
||||||
new_instance.user_commande.email,
|
|
||||||
f"Votre reservation pour {config.organisation}",
|
|
||||||
template='mails/buy_confirmation.html',
|
|
||||||
context={
|
|
||||||
'config': config,
|
|
||||||
'reservation': new_instance,
|
|
||||||
},
|
|
||||||
urls_for_attached_files = urls_for_attached_files,
|
|
||||||
)
|
|
||||||
# import ipdb; ipdb.set_trace()
|
# import ipdb; ipdb.set_trace()
|
||||||
mail.send_with_tread()
|
task = ticket_celery_mailer.delay(new_instance.pk)
|
||||||
except Exception as e :
|
# https://github.com/psf/requests/issues/5832
|
||||||
logger.error(f"{timezone.now()} Erreur envoie de mail pour reservation {new_instance} : {e}")
|
|
||||||
|
|
||||||
else :
|
else :
|
||||||
logger.info(f" TRIGGER RESERVATION mail déja envoyé {new_instance} : {new_instance.mail_send} - status : {new_instance.status}")
|
logger.info(f" TRIGGER RESERVATION mail déja envoyé {new_instance} : {new_instance.mail_send} - status : {new_instance.status}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
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
|
||||||
|
|
@ -8,6 +8,14 @@ from rest_framework.permissions import AllowAny
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from BaseBillet.models import Configuration, Event, Ticket
|
from BaseBillet.models import Configuration, Event, Ticket
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import segno
|
||||||
|
from io import StringIO, BytesIO
|
||||||
|
|
||||||
|
from django.template import engines
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
class index(APIView):
|
class index(APIView):
|
||||||
permission_classes = [AllowAny]
|
permission_classes = [AllowAny]
|
||||||
|
|
@ -36,10 +44,24 @@ class Ticket_html_view(APIView):
|
||||||
permission_classes = [AllowAny]
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
def get(self, request, pk_uuid):
|
def get(self, request, pk_uuid):
|
||||||
|
|
||||||
ticket = get_object_or_404(Ticket, uuid=pk_uuid)
|
ticket = get_object_or_404(Ticket, uuid=pk_uuid)
|
||||||
|
|
||||||
|
qr = segno.make(f'{ticket.uuid}')
|
||||||
|
|
||||||
|
buffer_png = BytesIO()
|
||||||
|
qr.save(buffer_png, kind='PNG', scale=3)
|
||||||
|
|
||||||
|
buffer_svg = BytesIO()
|
||||||
|
qr.save(buffer_svg, kind='svg', scale=10)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'ticket': ticket,
|
'ticket': ticket,
|
||||||
'config': Configuration.get_solo(),
|
'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'),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'ticket/ticket.html', context=context)
|
return render(request, 'ticket/ticket.html', context=context)
|
||||||
|
# return render(request, 'ticket/qrtest.html', context=context)
|
||||||
|
|
@ -34,10 +34,10 @@ app.config_from_object('django.conf:settings')
|
||||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||||
|
|
||||||
|
|
||||||
@app.task(bind=True)
|
@app.task
|
||||||
def add(x, y):
|
def add(x, y):
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def add2(x, y):
|
def schema_name():
|
||||||
return x + y
|
return connection.schema_name
|
||||||
|
|
|
||||||
|
|
@ -216,11 +216,10 @@ EMAIL_USE_SSL = os.environ.get('EMAIL_USE_SSL', True)
|
||||||
CELERY_TIMEZONE=os.environ.get('TIME_ZONE', 'UTC')
|
CELERY_TIMEZONE=os.environ.get('TIME_ZONE', 'UTC')
|
||||||
CELERY_TASK_TRACK_STARTED=True
|
CELERY_TASK_TRACK_STARTED=True
|
||||||
CELERY_TASK_TIME_LIMIT=30 * 60
|
CELERY_TASK_TIME_LIMIT=30 * 60
|
||||||
BROKER_URL=os.environ.get('CELERY_BROKER')
|
BROKER_URL=os.environ.get('CELERY_BROKER', 'redis://redis:6379/0')
|
||||||
RESULT_BACKEND=os.environ.get('CELERY_BROKER')
|
CELERY_RESULT_BACKEND=os.environ.get('CELERY_BACKEND', 'redis://redis:6379/0')
|
||||||
CELERY_RESULT_BACKEND=os.environ.get('CELERY_BACKEND')
|
|
||||||
# DJANGO_CELERY_BEAT_TZ_AWARE=False
|
# DJANGO_CELERY_BEAT_TZ_AWARE=False
|
||||||
# celery -A TiBillet worker -l INFO
|
|
||||||
|
|
||||||
# Jet Menu
|
# Jet Menu
|
||||||
# -------------------------------------/
|
# -------------------------------------/
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ RUN pip install celery
|
||||||
RUN pip install redis
|
RUN pip install redis
|
||||||
RUN pip install tenant-schemas-celery
|
RUN pip install tenant-schemas-celery
|
||||||
|
|
||||||
|
RUN pip install segno
|
||||||
|
|
||||||
RUN apt-get -y clean
|
RUN apt-get -y clean
|
||||||
|
|
||||||
RUN python --version
|
RUN python --version
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue