From 2c408389389a701f9e2e15ae1c23f65108d4a942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Mon, 10 Apr 2017 18:58:52 +0200 Subject: [PATCH 01/15] Add real cache support - Fix cache per process issue with a real cache system - Configuration seems too easy... but it seems to work --- provisioning/bootstrap.sh | 2 +- requirements.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index 269e4f25..e94d3ac4 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -9,7 +9,7 @@ DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4" # Installation de paquets utiles apt-get update && apt-get install -y python3-pip python3-dev python3-venv \ - libmysqlclient-dev libjpeg-dev git redis-server + libmysqlclient-dev libjpeg-dev git redis-server memcached pip install -U pip # Configuration et installation de mysql. Le mot de passe root est le même que diff --git a/requirements.txt b/requirements.txt index ce081588..202f5dda 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,3 +21,4 @@ git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_customma ldap3 git+https://github.com/Aureplop/channels.git#egg=channels python-dateutil +python-memcached From ab31c20649601514a24411328021daf6a636a46b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Mon, 10 Apr 2017 19:07:19 +0200 Subject: [PATCH 02/15] missing CACHES value... --- cof/settings_dev.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index 18aadaad..3bc4b807 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -115,6 +115,15 @@ USE_L10N = True USE_TZ = True +# Cache system +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '127.0.0.1:11211', + } +} + + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.8/howto/static-files/ From 36771c2c4f6a3c31c0d71e26ce5f2adda8445017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Mon, 10 Apr 2017 21:36:00 +0200 Subject: [PATCH 03/15] Use redis for cache. - Cache use db #1 of redis. - Channel layer (of channels) use db #0 of redis. - `settings` try getting redis connection variables from environment. - Drop memcached system --- cof/settings_dev.py | 39 ++++++++++++++++++++++++++++----------- provisioning/bootstrap.sh | 2 +- requirements.txt | 2 +- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index 3bc4b807..97b4bf7c 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -115,15 +115,6 @@ USE_L10N = True USE_TZ = True -# Cache system -CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': '127.0.0.1:11211', - } -} - - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.8/howto/static-files/ @@ -176,13 +167,39 @@ RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" RECAPTCHA_USE_SSL = True -# Channels settings + +# Redis settings (for cache and channel layers) + +REDIS_HOST = os.environ.get("REDIS_HOST", "localhost") +REDIS_USER = os.environ.get("REDIS_USER", "") +REDIS_PASS = os.environ.get("REDIS_PASS", "") +REDIS_PORT = os.environ.get("REDIS_PORT", "6379") + +REDIS_AUTH = REDIS_USER+":"+REDIS_PASS+"@" if REDIS_USER or REDIS_PASS else '' +REDIS_BASE_URL = "redis://" + REDIS_AUTH + REDIS_HOST + ":" + REDIS_PORT + + +# Cache settings (use db #1 of redis) + +CACHE_REDIS_URL = REDIS_BASE_URL + "/1" + +CACHES = { + 'default': { + 'BACKEND': 'redis_cache.RedisCache', + 'LOCATION': CACHE_REDIS_URL, + } +} + + +# Channels settings (use db #0 of redis) + +CHANNEL_REDIS_URL = REDIS_BASE_URL + "/0" CHANNEL_LAYERS = { "default": { "BACKEND": "asgi_redis.RedisChannelLayer", "CONFIG": { - "hosts": [(os.environ.get("REDIS_HOST", "localhost"), 6379)], + "hosts": [CHANNEL_REDIS_URL], }, "ROUTING": "cof.routing.channel_routing", } diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index e94d3ac4..269e4f25 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -9,7 +9,7 @@ DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4" # Installation de paquets utiles apt-get update && apt-get install -y python3-pip python3-dev python3-venv \ - libmysqlclient-dev libjpeg-dev git redis-server memcached + libmysqlclient-dev libjpeg-dev git redis-server pip install -U pip # Configuration et installation de mysql. Le mot de passe root est le même que diff --git a/requirements.txt b/requirements.txt index 202f5dda..2012351a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ django-autoslug==1.9.3 django-cas-ng==3.5.5 django-grappelli==2.8.1 django-recaptcha==1.0.5 +django-redis-cache==1.7.1 mysqlclient==1.3.7 Pillow==3.3.0 six==1.10.0 @@ -21,4 +22,3 @@ git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_customma ldap3 git+https://github.com/Aureplop/channels.git#egg=channels python-dateutil -python-memcached From dbf5844f6a996399b2227f57a136a39897002673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Sat, 15 Apr 2017 14:41:55 +0200 Subject: [PATCH 04/15] Clean settings redis --- cof/settings/common.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/cof/settings/common.py b/cof/settings/common.py index 98f4f713..a3b7527f 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -19,6 +19,26 @@ except ImportError: except KeyError: raise RuntimeError("Secrets missing") + +# Redis settings (for cache and channel layers) +try: + from .secret import REDIS_USER, REDIS_PASS +except ImportError: + REDIS_USER = os.environ.get("REDIS_USER", "") + REDIS_PASS = os.environ.get("REDIS_PASS", "") + +if REDIS_USER or REDIS_PASS: + REDIS_AUTH = REDIS_USER+":"+REDIS_PASS+"@" +else: + REDIS_AUTH = '' + +REDIS_HOST = os.environ.get("REDIS_HOST", "localhost") +REDIS_PORT = os.environ.get("REDIS_PORT", "6379") + +REDIS_BASE_URL = "redis://" + REDIS_AUTH + REDIS_HOST + ":" + REDIS_PORT +# To select a specific redis database, do: REDIS_BASE_URL + '/' + + # Other secrets try: from .secret import ( @@ -153,18 +173,6 @@ AUTHENTICATION_BACKENDS = ( RECAPTCHA_USE_SSL = True - -# Redis settings (for cache and channel layers) - -REDIS_HOST = os.environ.get("REDIS_HOST", "localhost") -REDIS_USER = os.environ.get("REDIS_USER", "") -REDIS_PASS = os.environ.get("REDIS_PASS", "") -REDIS_PORT = os.environ.get("REDIS_PORT", "6379") - -REDIS_AUTH = REDIS_USER+":"+REDIS_PASS+"@" if REDIS_USER or REDIS_PASS else '' -REDIS_BASE_URL = "redis://" + REDIS_AUTH + REDIS_HOST + ":" + REDIS_PORT - - # Cache settings (use db #1 of redis) CACHE_REDIS_URL = REDIS_BASE_URL + "/1" From e7266e7a9d834b2372c38c5339ad6412beae39a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Wed, 26 Apr 2017 11:28:18 +0200 Subject: [PATCH 05/15] use new settings for redis --- cof/settings/common.py | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/cof/settings/common.py b/cof/settings/common.py index 14f672e0..372d7d81 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -20,25 +20,6 @@ except KeyError: raise RuntimeError("Secrets missing") -# Redis settings (for cache and channel layers) -try: - from .secret import REDIS_USER, REDIS_PASS -except ImportError: - REDIS_USER = os.environ.get("REDIS_USER", "") - REDIS_PASS = os.environ.get("REDIS_PASS", "") - -if REDIS_USER or REDIS_PASS: - REDIS_AUTH = REDIS_USER+":"+REDIS_PASS+"@" -else: - REDIS_AUTH = '' - -REDIS_HOST = os.environ.get("REDIS_HOST", "localhost") -REDIS_PORT = os.environ.get("REDIS_PORT", "6379") - -REDIS_BASE_URL = "redis://" + REDIS_AUTH + REDIS_HOST + ":" + REDIS_PORT -# To select a specific redis database, do: REDIS_BASE_URL + '/' - - # Other secrets try: from .secret import ( @@ -174,19 +155,19 @@ AUTHENTICATION_BACKENDS = ( RECAPTCHA_USE_SSL = True -# Cache settings (use db #1 of redis) - -CACHE_REDIS_URL = REDIS_BASE_URL + "/1" +# Cache settings CACHES = { 'default': { 'BACKEND': 'redis_cache.RedisCache', - 'LOCATION': CACHE_REDIS_URL, + 'LOCATION': 'redis://:{passwd}@{host}:{port}/db' + .format(passwd=REDIS_PASSWD, host=REDIS_HOST, + port=REDIS_PORT, db=REDIS_DB), } } -# Channels settings (use db #0 of redis) +# Channels settings CHANNEL_LAYERS = { "default": { From 0e03fc85ee2528d67957c6fa298f232ee2391410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 2 Jun 2017 17:25:04 +0100 Subject: [PATCH 06/15] The BdA receives the reminder emails --- bda/__init__.py | 10 ++++++++++ bda/models.py | 10 +++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/bda/__init__.py b/bda/__init__.py index e69de29b..a5eecc65 100644 --- a/bda/__init__.py +++ b/bda/__init__.py @@ -0,0 +1,10 @@ +from django.contrib.auth.models import User + + +def get_generic_user(): + generic, created = User.objects.get_or_create(username="bda_generic") + if created: + generic.email = "bda@ens.fr" + generic.first_name = "Bureau des Arts" + generic.save() + return generic diff --git a/bda/models.py b/bda/models.py index 0228b4c0..42090374 100644 --- a/bda/models.py +++ b/bda/models.py @@ -11,6 +11,8 @@ from django.contrib.auth.models import User from django.conf import settings from django.utils import timezone, formats +from . import get_generic_user + class Tirage(models.Model): title = models.CharField("Titre", max_length=300) @@ -104,11 +106,9 @@ class Spectacle(models.Model): members[member.id][1] = 2 else: members[member.id] = [member, 1] - # FIXME : faire quelque chose de ça, un utilisateur bda_generic ? - # # Pour le BdA - # members[0] = ['BdA', 1, 'bda@ens.fr'] - # members[-1] = ['BdA', 2, 'bda@ens.fr'] # On écrit un mail personnalisé à chaque participant + bda_generic = get_generic_user() + members[-1] = [bda_generic, 1] datatuple = [( 'bda-rappel', {'member': member[0], 'nb_attr': member[1], 'show': self}, @@ -121,7 +121,7 @@ class Spectacle(models.Model): self.rappel_sent = timezone.now() self.save() # On renvoie la liste des destinataires - return members.values() + return map(lambda t: t[0], members.values()) @property def is_past(self): From 2a3614540fc143e7e62f091991c4bd9106692724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 2 Jun 2017 17:32:23 +0100 Subject: [PATCH 07/15] minor PEP8 changes --- bda/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bda/views.py b/bda/views.py index 00a1b300..406ca81c 100644 --- a/bda/views.py +++ b/bda/views.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from collections import defaultdict -from functools import partial import random import hashlib import time @@ -27,7 +26,7 @@ from django.views.generic.list import ListView from gestioncof.decorators import cof_required, buro_required from bda.models import ( Spectacle, Participant, ChoixSpectacle, Attribution, Tirage, - SpectacleRevente, Salle, Quote, CategorieSpectacle + SpectacleRevente, Salle, CategorieSpectacle ) from bda.algorithm import Algorithm from bda.forms import ( @@ -305,7 +304,8 @@ def do_tirage(tirage_elt, token): # On inscrit à BdA-Revente ceux qui n'ont pas eu les places voulues ChoixRevente = Participant.choicesrevente.through - # Suppression des reventes demandées/enregistrées (si le tirage est relancé) + # Suppression des reventes demandées/enregistrées + # (si le tirage est relancé) ( ChoixRevente.objects .filter(spectacle__tirage=tirage_elt) From 31c034a96ae2cf4072d6607df45038ce98657d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 2 Jun 2017 18:01:27 +0100 Subject: [PATCH 08/15] send_rappel: use django messages + css tweaks --- bda/templates/bda/mails-rappel.html | 47 +++++++++++++---------------- bda/views.py | 8 +++++ gestioncof/static/css/cof.css | 7 +++-- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/bda/templates/bda/mails-rappel.html b/bda/templates/bda/mails-rappel.html index 73625d1c..21fcc407 100644 --- a/bda/templates/bda/mails-rappel.html +++ b/bda/templates/bda/mails-rappel.html @@ -3,41 +3,36 @@ {% block realcontent %}

Mails de rappels

{% if sent %} -

Les mails de rappel pour le spectacle {{ show.title }} ont bien été envoyés aux personnes suivantes

-
    - {% for member in members %} -
  • {{ member.get_full_name }} ({{ member.email }})
  • - {% endfor %} -
+

Les mails de rappel pour le spectacle {{ show.title }} ont bien été envoyés aux personnes suivantes

+
    + {% for member in members %} +
  • {{ member.get_full_name }} ({{ member.email }})
  • + {% endfor %} +
{% else %} -

Voulez vous envoyer les mails de rappel pour le spectacle - {{ show.title }} ?

- {% if show.rappel_sent %} -

Attention, les mails ont déjà été envoyés le - {{ show.rappel_sent }}

- {% endif %} +

Voulez vous envoyer les mails de rappel pour le spectacle {{ show.title }} ?

{% endif %} - {% if not sent %} -
- {% csrf_token %} -
- -
-
- {% endif %} +
+ {% if not sent %} +
+ {% csrf_token %} +
+ +
+
+ {% endif %} +
-
-

Forme des mails

Une seule place

- {% for part in exemple_mail_1place %} -
{{ part }}
- {% endfor %} + {% for part in exemple_mail_1place %} +
{{ part }}
+ {% endfor %}

Deux places

{% for part in exemple_mail_2places %} -
{{ part }}
+
{{ part }}
{% endfor %} {% endblock %} diff --git a/bda/views.py b/bda/views.py index 406ca81c..602e5025 100644 --- a/bda/views.py +++ b/bda/views.py @@ -673,6 +673,14 @@ def send_rappel(request, spectacle_id): # Demande de confirmation else: ctxt['sent'] = False + if show.rappel_sent: + messages.warning( + request, + "Attention, un mail de rappel pour ce spectale a déjà été " + "envoyé le {}".format(formats.localize( + timezone.template_localtime(show.rappel_sent) + )) + ) return render(request, "bda/mails-rappel.html", ctxt) diff --git a/gestioncof/static/css/cof.css b/gestioncof/static/css/cof.css index e1cdd763..91cf726a 100644 --- a/gestioncof/static/css/cof.css +++ b/gestioncof/static/css/cof.css @@ -40,8 +40,9 @@ a { background: transparent; } - - +div.empty-form { + padding-bottom: 2em; +} a:hover { color: #444; @@ -341,10 +342,12 @@ fieldset legend { font-weight: 700; font-size: large; color:#DE826B; + padding-bottom: .5em; } #main-content h4 { color:#DE826B; + padding-bottom: .5em; } #main-content h2, From fbdfdeef46f725e49ee73f88643ad5fe70a57c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 2 Jun 2017 18:30:02 +0100 Subject: [PATCH 09/15] Add a link to the reminder emails sending page --- bda/templates/bda-participants.html | 27 ++++++++++++++++++--------- bda/urls.py | 5 ++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/bda/templates/bda-participants.html b/bda/templates/bda-participants.html index 289d1761..85af4a2e 100644 --- a/bda/templates/bda-participants.html +++ b/bda/templates/bda-participants.html @@ -36,17 +36,26 @@

Ajouter une attribution

-
- - -
- - + + + +