From 813cbe7b13d19ac578fcbc60784f42e5bad449e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 26 Aug 2016 22:18:22 +0200 Subject: [PATCH 01/26] Meilleure gestion des permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il n'est plus possible de modifier l'attribut `is_superuser` dans l'interface admin. les membres du burô ne doivent plus être super- utilisateurs en prévision de l'arrivée de l'appli K-Fêt. Pour donner les permissions adéquates au burô, il faut créer un groupe COF avec tous les droits sur les applis `gestioncof` et `bda` ainsi que les droits sur les d'utilisateurs et ajouter les membres du burô à ce groupe. --- gestioncof/admin.py | 13 +++++++++++++ gestioncof/shared.py | 3 +-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 342317f3..db70946b 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -5,6 +5,7 @@ from __future__ import print_function from __future__ import unicode_literals from django.contrib import admin +from django.utils.translation import ugettext_lazy as _ from gestioncof.models import SurveyQuestionAnswer, SurveyQuestion, \ CofProfile, EventOption, EventOptionChoice, Event, Club, CustomMail, \ Survey, EventCommentField, EventRegistration @@ -162,6 +163,13 @@ class UserProfileAdmin(UserAdmin): return False is_cof.short_description = 'Membre du COF' is_cof.boolean = True + + fieldsets = [ + (None, {'fields': ['username', 'password']}), + (_('Personal info'), {'fields': ['first_name', 'last_name', 'email']}), + (_('Groups'), {'fields': ['groups']}) + ] + list_display = ('profile_num',) + UserAdmin.list_display \ + ('profile_login_clipper', 'profile_phone', 'profile_occupation', 'profile_mailing_cof', 'profile_mailing_bda', @@ -175,6 +183,11 @@ class UserProfileAdmin(UserAdmin): CofProfileInline, ] + def save_model(self, request, user, form, change): + if user.profile.is_buro: + user.is_staff = True + user.save() + # FIXME: This is absolutely horrible. def user_unicode(self): diff --git a/gestioncof/shared.py b/gestioncof/shared.py index fc901d50..87021a00 100644 --- a/gestioncof/shared.py +++ b/gestioncof/shared.py @@ -58,8 +58,7 @@ class COFCASBackend(CASBackend): if not user.email: user.email = settings.CAS_EMAIL_FORMAT % profile.login_clipper user.save() - if profile.is_buro and not user.is_superuser: - user.is_superuser = True + if profile.is_buro and not user.is_staff: user.is_staff = True user.save() return user From 9d5931fd6f73802d269bbd00c9b31b2dce41b5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Tue, 30 Aug 2016 22:31:55 +0200 Subject: [PATCH 02/26] Meilleure gestion des permissions dans l'admin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seul les superusers ont le contrôle sur les groupes et permissions. Un membre du burô est automatiquement ajouté au groupe COF, lui même créé automatiquement s'il n'existe pas. --- gestioncof/admin.py | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/gestioncof/admin.py b/gestioncof/admin.py index db70946b..09965785 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -12,10 +12,11 @@ from gestioncof.models import SurveyQuestionAnswer, SurveyQuestion, \ from gestioncof.petits_cours_models import PetitCoursDemande, \ PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \ PetitCoursAttributionCounter -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Group, Permission from django.contrib.auth.admin import UserAdmin from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe +from django.db.models import Q import django.utils.six as six import autocomplete_light @@ -164,12 +165,6 @@ class UserProfileAdmin(UserAdmin): is_cof.short_description = 'Membre du COF' is_cof.boolean = True - fieldsets = [ - (None, {'fields': ['username', 'password']}), - (_('Personal info'), {'fields': ['first_name', 'last_name', 'email']}), - (_('Groups'), {'fields': ['groups']}) - ] - list_display = ('profile_num',) + UserAdmin.list_display \ + ('profile_login_clipper', 'profile_phone', 'profile_occupation', 'profile_mailing_cof', 'profile_mailing_bda', @@ -183,9 +178,38 @@ class UserProfileAdmin(UserAdmin): CofProfileInline, ] + staff_fieldsets = [ + (None, {'fields': ['username', 'password']}), + (_('Personal info'), {'fields': ['first_name', 'last_name', 'email']}), + ] + + def get_fieldsets(self, request, user=None): + if not request.user.is_superuser: + return self.staff_fieldsets + return super(UserProfileAdmin, self).get_fieldsets(request, user) + def save_model(self, request, user, form, change): + cof_group, created = Group.objects.get_or_create(name='COF') + if created: + # Si le groupe COF n'était pas déjà dans la bdd + # On lui assigne les bonnes permissions + perms = Permission.objects.filter( + Q(content_type__app_label='gestioncof') + | Q(content_type__app_label='bda') + | (Q(content_type__app_label='auth') + & Q(content_type__model='user'))) + cof_group.permissions = perms + # On y associe les membres du Burô + cof_group.user_set = User.objects.filter(profile__is_buro=True) + # Sauvegarde + cof_group.save() + # le Burô est staff et appartient au groupe COF if user.profile.is_buro: user.is_staff = True + user.groups.add(cof_group) + else: + user.is_staff = False + user.groups.remove(cof_group) user.save() From 799f2317f74049fd90aab6231f80d6f4b17a84e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 4 Sep 2016 13:14:26 +0200 Subject: [PATCH 03/26] Champ commentaires MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit le champ `comments` du modèle `CofProfile` est maintenant visible par l'urilisateur via la vue “profil”. --- bda/migrations/0008_py3.py | 103 ++++++++++++ gestioncof/migrations/0008_py3.py | 253 ++++++++++++++++++++++++++++++ gestioncof/models.py | 2 +- gestioncof/templates/profile.html | 10 +- 4 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 bda/migrations/0008_py3.py create mode 100644 gestioncof/migrations/0008_py3.py diff --git a/bda/migrations/0008_py3.py b/bda/migrations/0008_py3.py new file mode 100644 index 00000000..fe6a8eaf --- /dev/null +++ b/bda/migrations/0008_py3.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('bda', '0007_extends_spectacle'), + ] + + operations = [ + migrations.AlterField( + model_name='choixspectacle', + name='double_choice', + field=models.CharField( + verbose_name='Nombre de places', + choices=[('1', '1 place'), + ('autoquit', '2 places si possible, 1 sinon'), + ('double', '2 places sinon rien')], + max_length=10, default='1'), + ), + migrations.AlterField( + model_name='participant', + name='paymenttype', + field=models.CharField( + blank=True, + choices=[('cash', 'Cash'), ('cb', 'CB'), + ('cheque', 'Chèque'), ('autre', 'Autre')], + max_length=6, verbose_name='Moyen de paiement'), + ), + migrations.AlterField( + model_name='salle', + name='address', + field=models.TextField(verbose_name='Adresse'), + ), + migrations.AlterField( + model_name='salle', + name='name', + field=models.CharField(verbose_name='Nom', max_length=300), + ), + migrations.AlterField( + model_name='spectacle', + name='date', + field=models.DateTimeField(verbose_name='Date & heure'), + ), + migrations.AlterField( + model_name='spectacle', + name='description', + field=models.TextField(verbose_name='Description', blank=True), + ), + migrations.AlterField( + model_name='spectacle', + name='listing', + field=models.BooleanField( + verbose_name='Les places sont sur listing'), + ), + migrations.AlterField( + model_name='spectacle', + name='price', + field=models.FloatField(verbose_name="Prix d'une place"), + ), + migrations.AlterField( + model_name='spectacle', + name='slots', + field=models.IntegerField(verbose_name='Places'), + ), + migrations.AlterField( + model_name='spectacle', + name='slots_description', + field=models.TextField(verbose_name='Description des places', + blank=True), + ), + migrations.AlterField( + model_name='spectacle', + name='title', + field=models.CharField(verbose_name='Titre', max_length=300), + ), + migrations.AlterField( + model_name='tirage', + name='active', + field=models.BooleanField(verbose_name='Tirage actif', + default=False), + ), + migrations.AlterField( + model_name='tirage', + name='fermeture', + field=models.DateTimeField( + verbose_name='Date et heure de fermerture du tirage'), + ), + migrations.AlterField( + model_name='tirage', + name='ouverture', + field=models.DateTimeField( + verbose_name="Date et heure d'ouverture du tirage"), + ), + migrations.AlterField( + model_name='tirage', + name='title', + field=models.CharField(verbose_name='Titre', max_length=300), + ), + ] diff --git a/gestioncof/migrations/0008_py3.py b/gestioncof/migrations/0008_py3.py new file mode 100644 index 00000000..7d94d7ce --- /dev/null +++ b/gestioncof/migrations/0008_py3.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +def forwards(apps, schema_editor): + Profile = apps.get_model("gestioncof", "CofProfile") + Profile.objects.update(comments="") + + +class Migration(migrations.Migration): + + dependencies = [ + ('gestioncof', '0007_alter_club'), + ] + + operations = [ + migrations.AlterField( + model_name='clipper', + name='fullname', + field=models.CharField(verbose_name='Nom complet', max_length=200), + ), + migrations.AlterField( + model_name='clipper', + name='username', + field=models.CharField(verbose_name='Identifiant', max_length=20), + ), + migrations.AlterField( + model_name='cofprofile', + name='comments', + field=models.TextField( + verbose_name="Commentaires visibles par l'utilisateur", + blank=True), + ), + migrations.AlterField( + model_name='cofprofile', + name='is_cof', + field=models.BooleanField(verbose_name='Membre du COF', + default=False), + ), + migrations.AlterField( + model_name='cofprofile', + name='login_clipper', + field=models.CharField(verbose_name='Login clipper', max_length=8, + blank=True), + ), + migrations.AlterField( + model_name='cofprofile', + name='mailing_bda', + field=models.BooleanField(verbose_name='Recevoir les mails BdA', + default=False), + ), + migrations.AlterField( + model_name='cofprofile', + name='mailing_bda_revente', + field=models.BooleanField( + verbose_name='Recevoir les mails de revente de places BdA', + default=False), + ), + migrations.AlterField( + model_name='cofprofile', + name='mailing_cof', + field=models.BooleanField(verbose_name='Recevoir les mails COF', + default=False), + ), + migrations.AlterField( + model_name='cofprofile', + name='occupation', + field=models.CharField(verbose_name='Occupation', + choices=[('exterieur', 'Extérieur'), + ('1A', '1A'), + ('2A', '2A'), + ('3A', '3A'), + ('4A', '4A'), + ('archicube', 'Archicube'), + ('doctorant', 'Doctorant'), + ('CST', 'CST')], + max_length=9, default='1A'), + ), + migrations.AlterField( + model_name='cofprofile', + name='petits_cours_accept', + field=models.BooleanField(verbose_name='Recevoir des petits cours', + default=False), + ), + migrations.AlterField( + model_name='cofprofile', + name='petits_cours_remarques', + field=models.TextField( + blank=True, + verbose_name='Remarques et précisions pour les petits cours', + default=''), + ), + migrations.AlterField( + model_name='cofprofile', + name='type_cotiz', + field=models.CharField( + verbose_name='Type de cotisation', + choices=[('etudiant', 'Normalien étudiant'), + ('normalien', 'Normalien élève'), + ('exterieur', 'Extérieur')], + max_length=9, default='normalien'), + ), + migrations.AlterField( + model_name='custommail', + name='comments', + field=models.TextField( + verbose_name='Informations contextuelles sur le mail', + blank=True), + ), + migrations.AlterField( + model_name='custommail', + name='content', + field=models.TextField(verbose_name='Contenu'), + ), + migrations.AlterField( + model_name='custommail', + name='title', + field=models.CharField(verbose_name='Titre', max_length=200), + ), + migrations.AlterField( + model_name='event', + name='description', + field=models.TextField(verbose_name='Description', blank=True), + ), + migrations.AlterField( + model_name='event', + name='end_date', + field=models.DateTimeField(null=True, verbose_name='Date de fin', + blank=True), + ), + migrations.AlterField( + model_name='event', + name='image', + field=models.ImageField(upload_to='imgs/events/', null=True, + verbose_name='Image', blank=True), + ), + migrations.AlterField( + model_name='event', + name='location', + field=models.CharField(verbose_name='Lieu', max_length=200), + ), + migrations.AlterField( + model_name='event', + name='registration_open', + field=models.BooleanField(verbose_name='Inscriptions ouvertes', + default=True), + ), + migrations.AlterField( + model_name='event', + name='title', + field=models.CharField(verbose_name='Titre', max_length=200), + ), + migrations.AlterField( + model_name='eventcommentfield', + name='fieldtype', + field=models.CharField(verbose_name='Type', + choices=[('text', 'Texte long'), + ('char', 'Texte court')], + max_length=10, default='text'), + ), + migrations.AlterField( + model_name='eventcommentfield', + name='name', + field=models.CharField(verbose_name='Champ', max_length=200), + ), + migrations.AlterField( + model_name='eventcommentvalue', + name='content', + field=models.TextField(null=True, verbose_name='Contenu', + blank=True), + ), + migrations.AlterField( + model_name='eventoption', + name='multi_choices', + field=models.BooleanField(verbose_name='Choix multiples', + default=False), + ), + migrations.AlterField( + model_name='eventoption', + name='name', + field=models.CharField(verbose_name='Option', max_length=200), + ), + migrations.AlterField( + model_name='eventoptionchoice', + name='value', + field=models.CharField(verbose_name='Valeur', max_length=200), + ), + migrations.AlterField( + model_name='petitcoursability', + name='niveau', + field=models.CharField( + choices=[('college', 'Collège'), ('lycee', 'Lycée'), + ('prepa1styear', 'Prépa 1ère année / L1'), + ('prepa2ndyear', 'Prépa 2ème année / L2'), + ('licence3', 'Licence 3'), + ('other', 'Autre (préciser dans les commentaires)')], + max_length=12, verbose_name='Niveau'), + ), + migrations.AlterField( + model_name='petitcoursattribution', + name='rank', + field=models.IntegerField(verbose_name="Rang dans l'email"), + ), + migrations.AlterField( + model_name='petitcoursattributioncounter', + name='count', + field=models.IntegerField(verbose_name="Nombre d'envois", + default=0), + ), + migrations.AlterField( + model_name='petitcoursdemande', + name='niveau', + field=models.CharField( + verbose_name='Niveau', + choices=[('college', 'Collège'), ('lycee', 'Lycée'), + ('prepa1styear', 'Prépa 1ère année / L1'), + ('prepa2ndyear', 'Prépa 2ème année / L2'), + ('licence3', 'Licence 3'), + ('other', 'Autre (préciser dans les commentaires)')], + max_length=12, default=''), + ), + migrations.AlterField( + model_name='survey', + name='old', + field=models.BooleanField(verbose_name='Archiver (sondage fini)', + default=False), + ), + migrations.AlterField( + model_name='survey', + name='survey_open', + field=models.BooleanField(verbose_name='Sondage ouvert', + default=True), + ), + migrations.AlterField( + model_name='survey', + name='title', + field=models.CharField(verbose_name='Titre', max_length=200), + ), + migrations.AlterField( + model_name='surveyquestion', + name='multi_answers', + field=models.BooleanField(verbose_name='Choix multiples', + default=False), + ), + migrations.AlterField( + model_name='surveyquestion', + name='question', + field=models.CharField(verbose_name='Question', max_length=200), + ), + migrations.RunPython(forwards, migrations.RunPython.noop), + ] diff --git a/gestioncof/models.py b/gestioncof/models.py index 382a5750..19590aff 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -62,7 +62,7 @@ class CofProfile(models.Model): mailing_bda_revente = models.BooleanField( "Recevoir les mails de revente de places BdA", default=False) comments = models.TextField( - "Commentaires visibles uniquement par le Buro", blank=True) + "Commentaires visibles par l'utilisateur", blank=True) is_buro = models.BooleanField("Membre du Burô", default=False) petits_cours_accept = models.BooleanField( "Recevoir des petits cours", default=False) diff --git a/gestioncof/templates/profile.html b/gestioncof/templates/profile.html index 6ba101e9..7b185150 100644 --- a/gestioncof/templates/profile.html +++ b/gestioncof/templates/profile.html @@ -13,10 +13,18 @@ {% csrf_token %} {% for field in form %} - {{ field | bootstrap}} + {{ field | bootstrap }} {% endfor %} + {% if user.profile.comments %} +
+

Commentaires

+

+ {{ user.profile.comments }} +

+
+ {% endif %}
From 2151bf0dd82147de976f786f501c4fa91f60031c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 4 Sep 2016 14:34:20 +0200 Subject: [PATCH 04/26] =?UTF-8?q?Corrections/am=C3=A9liorations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sur le template des descriptions des spectacles --- bda/templates/descriptions.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index 3ab514f2..44fe16ae 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -46,7 +46,7 @@

{{ show.location }}

{{ show.category }}

-

{{ show.date }}

{{ show.slots }} place{{ show.slots|pluralize}} {% if show.slots_description != "" %}({{ show.slots_description }}){% endif %}- {{ show.price }}

+

{{ show.date|date:"l j F Y - H\hi" }}

{{ show.slots }} place{{ show.slots|pluralize}} {% if show.slots_description != "" %}({{ show.slots_description }}){% endif %} - {{ show.price }}€

{{ show.category }}

From 9efe209689f5b08c74ad164c050d353af54152ff Mon Sep 17 00:00:00 2001 From: Hugo Roussille Date: Mon, 5 Sep 2016 20:08:43 +0200 Subject: [PATCH 05/26] Modifications graphiques --- bda/templates/descriptions.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index 44fe16ae..404bf89c 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -20,6 +20,7 @@ .descTable{ width: auto; margin: 0 auto 1em; + border-bottom: 2px solid; border-collapse: collapse; border-spacing: 0; font-size: 14px; @@ -46,10 +47,7 @@

{{ show.location }}

{{ show.category }}

-

{{ show.date|date:"l j F Y - H\hi" }}

{{ show.slots }} place{{ show.slots|pluralize}} {% if show.slots_description != "" %}({{ show.slots_description }}){% endif %} - {{ show.price }}€

- - -

{{ show.category }}

+

{{ show.date|date:"l j F Y - H\hi" }}

{{ show.slots }} place{{ show.slots|pluralize}} {% if show.slots_description != "" %}({{ show.slots_description }}){% endif %} - {{ show.price }} euro{{ show.price|pluralize}}

@@ -61,7 +59,7 @@ {% if show.image %} -

{{ show.title }}

+

{{ show.title }}

{% endif %} From 4237b842b401b5adc940d3a61c4a225e3f9b23b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 5 Sep 2016 23:47:16 +0200 Subject: [PATCH 06/26] Compat IE et mobiles --- gestioncof/templates/base.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gestioncof/templates/base.html b/gestioncof/templates/base.html index 185ebd44..2a718951 100644 --- a/gestioncof/templates/base.html +++ b/gestioncof/templates/base.html @@ -4,10 +4,12 @@ {{ site.name }} - - + + + + {% block extra_head %}{% endblock %} From 7d02f29e488c4576369ab6fa83b29622a4ced623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Tue, 6 Sep 2016 01:26:44 +0200 Subject: [PATCH 07/26] =?UTF-8?q?Pr=C3=A9paration=20pour=20daphne?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apache/__init__.py | 0 apache/asgi.py | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 apache/__init__.py create mode 100644 apache/asgi.py diff --git a/apache/__init__.py b/apache/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apache/asgi.py b/apache/asgi.py new file mode 100644 index 00000000..eb18c7b2 --- /dev/null +++ b/apache/asgi.py @@ -0,0 +1,6 @@ +import os +from channels.asgi import get_channel_layer + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") + +channel_layer = get_channel_layer() From 5b2c3e3caece39c1fb53612664f434ef72412a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 8 Sep 2016 12:52:07 +0200 Subject: [PATCH 08/26] Fix tabs --- bda/templates/descriptions.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index 404bf89c..7eb8b93b 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -20,7 +20,7 @@ .descTable{ width: auto; margin: 0 auto 1em; - border-bottom: 2px solid; + border-bottom: 2px solid; border-collapse: collapse; border-spacing: 0; font-size: 14px; From ae3ef21a2f9dbfbc55857f8db8ea2f5df61c58f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 10 Sep 2016 19:15:43 +0200 Subject: [PATCH 09/26] =?UTF-8?q?Corrections=20sur=20les=20dates=20affich?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bda/models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bda/models.py b/bda/models.py index 8a7d0814..270921be 100644 --- a/bda/models.py +++ b/bda/models.py @@ -32,7 +32,8 @@ class Tirage(models.Model): default=False) def date_no_seconds(self): - return self.fermeture.strftime('%d %b %Y %H:%M') + return self.fermeture.astimezone(timezone.get_current_timezone()) \ + .strftime('%d %b %Y %H:%M') def __str__(self): return "%s - %s" % (self.title, self.date_no_seconds()) @@ -89,7 +90,8 @@ class Spectacle(models.Model): return "%d" % calendar.timegm(self.date.utctimetuple()) def date_no_seconds(self): - return self.date.strftime('%d %b %Y %H:%M') + return self.date.astimezone(timezone.get_current_timezone()) \ + .strftime('%d %b %Y %H:%M') def __str__(self): return "%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), From 2153a64f584d719d91e0a1198ae1f3125f8e02b4 Mon Sep 17 00:00:00 2001 From: Hugo Roussille Date: Sun, 11 Sep 2016 01:32:32 +0200 Subject: [PATCH 10/26] Correction de la taille des images --- bda/templates/descriptions.html | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index 404bf89c..3ed67e87 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -34,6 +34,7 @@ + {% for show in shows %} @@ -59,11 +60,40 @@ {% if show.image %} - + {% endif %}

{{ show.title }}

{{ show.title }}

{% endfor %} + From 9979072c1301f526bec68d921c336fdb283f55c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 11 Sep 2016 13:49:10 +0200 Subject: [PATCH 11/26] Config redis Le provisionning ajoute un mot de passe sur le serveur redis --- cof/settings_dev.py | 3 ++- provisioning/bootstrap.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index 54797fc5..c63437a5 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -175,12 +175,13 @@ CHANNEL_LAYERS = { "default": { "BACKEND": "asgi_redis.RedisChannelLayer", "CONFIG": { - "hosts": [("redis://:password_redis@127.0.0.1:6379/0")], + "hosts": [("redis://:redis_password@127.0.0.1:6379/0")], }, "ROUTING": "cof.routing.channel_routing", } } + def show_toolbar(request): """ On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index 304d8cd0..b6df6caa 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -23,6 +23,7 @@ mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON $D # Installation de redis-server. Todo: lui mettre un mot de passe apt-get install -y redis-server +redis-cli config set requirepass redis_password # Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh` cat > ~vagrant/.bash_profile < Date: Mon, 12 Sep 2016 16:48:15 +0200 Subject: [PATCH 12/26] =?UTF-8?q?Correction=20de=202153a64=20pour=20g?= =?UTF-8?q?=C3=A9rer=20les=20tableaux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bda/templates/descriptions.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index 3ed67e87..a993848a 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -18,7 +18,7 @@ } .descTable{ - width: auto; + width: 100%; margin: 0 auto 1em; border-bottom: 2px solid; border-collapse: collapse; @@ -70,6 +70,10 @@ // Correction de la taille des images $(document).ready(function() { + $(".descTable").each(function() { + $(this).width($("body").width()); + }); + $(".imgDesc").on("load", function() { // Dimensions @@ -78,7 +82,7 @@ w = $(this).width(); h = $(this).height(); r = w/h; // Ratio de l'image - maxWidth = $(this).parent().width(); + maxWidth = $("body").width(); if (r * origHeight > maxWidth) { From f37bdd90b701bcbaa454737e097d0704827794fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 12 Sep 2016 16:49:37 +0200 Subject: [PATCH 13/26] =?UTF-8?q?Cr=C3=A9e=20un=20setup=20proche=20de=20ce?= =?UTF-8?q?lui=20en=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On fait tourner GestioCOF avec daphne derrière un reverse-proxy Apache sur la VM Vagrant tout comme sur le serveur de production. On peut tester en local GestioCOF en “conditions réelles”. Le serveur lancé avec `python manage.py runserver 0.0.0.0:8000` est toujours accessible à la même url `localhost:8000`. Le (nouveau) serveur apache est accessible à `localhost:8080`. Pour appliquer les changements dans le code au serveur type prod, il faut relancer le worker : `sudo supervisorctl restart worker`. Alors que le serveur de dev se relance tout seul. NB important : ce patch supprime le mot de passe sur le serveur redis en dev, pour faire marcher ce nouveau setup avec un version précédente de la VM, il faut lancer `sudo redis-cli config set requirepass ""` --- README.md | 43 +++++++++++++++++++++++++++------- {apache => cof}/asgi.py | 2 +- cof/settings_dev.py | 5 ++-- provisioning/apache.conf | 29 +++++++++++++++++++++++ provisioning/bootstrap.sh | 20 ++++++++++++---- provisioning/prepare_django.sh | 1 + provisioning/supervisor.conf | 20 ++++++++++++++++ 7 files changed, 104 insertions(+), 16 deletions(-) rename {apache => cof}/asgi.py (57%) create mode 100644 provisioning/apache.conf create mode 100644 provisioning/supervisor.conf diff --git a/README.md b/README.md index 15f0ec0d..80d87e87 100644 --- a/README.md +++ b/README.md @@ -47,28 +47,47 @@ gérer la machine virtuelle : - `vagrant ssh` vous connecte en SSH à la machine virtuelle, dans le dossier où est installé GestioCOF. Vous pouvez utiliser les commandes Django - habituelles (`manage.py runserver` etc.); toutefois pour lancer le serveur il faut faire - - python manage.py runserver 0.0.0.0:8000 - - car par défaut Django n'écoute que sur l'adresse locale de la machine - virtuelle - or vous voudrez accéder à GestioCOF depuis votre machine - physique. + habituelles (`manage.py runserver` etc.) **Le dossier avec le code de GestioCOF est partagé entre la machine virtuelle et votre machine physique : vous pouvez donc utiliser votre éditeur favori pour coder depuis l'extérieur de la machine virtuelle, et les changements seront répercutés dans la machine virtuelle.** +#### Lancer le serveur de développement standard + +Pour lancer le serveur de développement, il faut faire + + python manage.py runserver 0.0.0.0:8000 + +car par défaut Django n'écoute que sur l'adresse locale de la machine virtuelle +or vous voudrez accéder à GestioCOF depuis votre machine physique. L'url à +entrer dans le navigateur est `localhost:8000`. + +#### Serveur de développement type production + +Sur la VM Vagrant, un serveur apache est configuré pour servir GestioCOF de +façon similaire à la version en production : on utilise +[Daphne](https://github.com/django/daphne/) et `python manage.py runworker` +derrière un reverse-proxy apache. Le tout est monitoré par +[supervisor](http://supervisord.org/). + +Ce serveur se lance tout seul et est accessible en dehors de la VM à l'url +`localhost:8080`. Toutefois il ne se recharge pas tout seul lorsque le code +change, il faut relancer le worker avec `sudo supervisorctl restart worker` pour +visualiser la dernière version du code. + ### Installation manuelle Si vous optez pour une installation manuelle plutôt que d'utiliser Vagrant, il est fortement conseillé d'utiliser un environnement virtuel pour Python. Il vous faudra installer mercurial, pip, les librairies de développement de -python, ainsi qu'un client et un serveur MySQL ; sous Debian et dérivées (Ubuntu, ...) : +python, un client et un serveur MySQL ainsi qu'un serveur redis ; sous Debian et +dérivées (Ubuntu, ...) : sudo apt-get install mercurial python-pip python-dev libmysqlclient-dev + redis-server Si vous décidez d'utiliser un environnement virtuel Python (virtualenv; fortement conseillé), déplacez-vous dans le dossier où est installé GestioCOF @@ -87,7 +106,13 @@ Vous pouvez maintenant installer les dépendances Python depuis les fichiers pip install -r requirements.txt -r requirements-devel.txt -Enfin, copiez le fichier `cof/settings_dev.py` dans `cof/settings.py`. +Copiez le fichier `cof/settings_dev.py` dans `cof/settings.py`. + +Enfin, configurez le mot de passe redis le plus simple et de ne pas en utiliser +(pas de risque en local) en remplaçant la ligne `hosts` dans +`settings.CHANNEL_LAYER` par + + "hosts": [("localhost", 6379)] #### Installation avec MySQL diff --git a/apache/asgi.py b/cof/asgi.py similarity index 57% rename from apache/asgi.py rename to cof/asgi.py index eb18c7b2..bb1b3b83 100644 --- a/apache/asgi.py +++ b/cof/asgi.py @@ -1,6 +1,6 @@ import os from channels.asgi import get_channel_layer -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings_dev") channel_layer = get_channel_layer() diff --git a/cof/settings_dev.py b/cof/settings_dev.py index c63437a5..f9adb2cf 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -29,7 +29,7 @@ SECRET_KEY = 'q()(zn4m63i%5cp4)f+ww4-28_w+ly3q9=6imw2ciu&_(5_4ah' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['127.0.0.1'] # Application definition @@ -123,6 +123,7 @@ USE_TZ = True # https://docs.djangoproject.com/en/1.8/howto/static-files/ STATIC_URL = '/static/' +STATIC_ROOT = '/var/www/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static/'), @@ -175,7 +176,7 @@ CHANNEL_LAYERS = { "default": { "BACKEND": "asgi_redis.RedisChannelLayer", "CONFIG": { - "hosts": [("redis://:redis_password@127.0.0.1:6379/0")], + "hosts": [("localhost", 6379)], }, "ROUTING": "cof.routing.channel_routing", } diff --git a/provisioning/apache.conf b/provisioning/apache.conf new file mode 100644 index 00000000..6bc1cd28 --- /dev/null +++ b/provisioning/apache.conf @@ -0,0 +1,29 @@ + + ServerName default + DocumentRoot /var/www/html + + ProxyPreserveHost On + ProxyRequests Off + ProxyPass /static/ ! + ProxyPass /media/ ! + ProxyPass /ws/ ws://127.0.0.1:8000/ws/ + ProxyPass / http://127.0.0.1:8000/ + ProxyPassReverse / http://127.0.0.1:8000/ + + Alias /media /vagrant/media + Alias /static /var/www/static + + Order deny,allow + Allow from all + + + Order deny,allow + Allow from all + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index b6df6caa..d3d0f4cb 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 mercurial python-pip python-dev \ - libmysqlclient-dev libjpeg-dev git + libmysqlclient-dev libjpeg-dev git redis-server # Configuration et installation de mysql. Le mot de passe root est le même que # le mot de passe pour l'utilisateur local - pour rappel, ceci est une instance @@ -21,9 +21,15 @@ apt-get install -y mysql-server mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON $DBNAME.* TO '$DBUSER'@'localhost' IDENTIFIED BY '$DBPASSWD'" -# Installation de redis-server. Todo: lui mettre un mot de passe -apt-get install -y redis-server -redis-cli config set requirepass redis_password +# Installation et configuration d'Apache +apt-get install -y apache2 +a2enmod proxy proxy_http +cp /vagrant/provisioning/apache.conf /etc/apache2/sites-available/gestiocof.conf +a2ensite gestiocof +a2dissite 000-default +service apache2 restart +mkdir /var/www/static +chown -R vagrant:www-data /var/www/static # Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh` cat > ~vagrant/.bash_profile < Date: Mon, 12 Sep 2016 17:04:50 +0200 Subject: [PATCH 14/26] Correction de port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le port 8000 est réservé au serveur de dev --- provisioning/apache.conf | 6 +++--- provisioning/supervisor.conf | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/provisioning/apache.conf b/provisioning/apache.conf index 6bc1cd28..001c6ec9 100644 --- a/provisioning/apache.conf +++ b/provisioning/apache.conf @@ -6,9 +6,9 @@ ProxyRequests Off ProxyPass /static/ ! ProxyPass /media/ ! - ProxyPass /ws/ ws://127.0.0.1:8000/ws/ - ProxyPass / http://127.0.0.1:8000/ - ProxyPassReverse / http://127.0.0.1:8000/ + ProxyPass /ws/ ws://127.0.0.1:8001/ws/ + ProxyPass / http://127.0.0.1:8001/ + ProxyPassReverse / http://127.0.0.1:8001/ Alias /media /vagrant/media Alias /static /var/www/static diff --git a/provisioning/supervisor.conf b/provisioning/supervisor.conf index 814b8c35..487defe3 100644 --- a/provisioning/supervisor.conf +++ b/provisioning/supervisor.conf @@ -10,7 +10,7 @@ stopasgroup=true redirect_stderr=true [program:interface] -command=/usr/local/bin/daphne -b 127.0.0.1 -p 8000 cof.asgi:channel_layer +command=/usr/local/bin/daphne -b 127.0.0.1 -p 8001 cof.asgi:channel_layer environment=DBUSER="cof_gestion",DBNAME="cof_gestion",DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4" directory=/vagrant/ redirect_stderr=true From 14733c07a0b4356f15380e5e6df60c5a60586b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 12 Sep 2016 19:33:39 +0200 Subject: [PATCH 15/26] Petits changements Clarification du README Utilisation de sed pour construire les fichiers de config --- README.md | 10 +++------- provisioning/bootstrap.sh | 3 +++ provisioning/supervisor.conf | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 80d87e87..db2cc93b 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,9 @@ gérer la machine virtuelle : - `vagrant ssh` vous connecte en SSH à la machine virtuelle, dans le dossier où est installé GestioCOF. Vous pouvez utiliser les commandes Django - habituelles (`manage.py runserver` etc.) + habituelles (`manage.py runserver` etc.) pour lancer + [le serveur en dev](#lancer-le-serveur-de-développement-standard) par + exemple **Le dossier avec le code de GestioCOF est partagé entre la machine virtuelle et votre machine physique : vous pouvez donc utiliser votre éditeur favori pour @@ -108,12 +110,6 @@ Vous pouvez maintenant installer les dépendances Python depuis les fichiers Copiez le fichier `cof/settings_dev.py` dans `cof/settings.py`. -Enfin, configurez le mot de passe redis le plus simple et de ne pas en utiliser -(pas de risque en local) en remplaçant la ligne `hosts` dans -`settings.CHANNEL_LAYER` par - - "hosts": [("localhost", 6379)] - #### Installation avec MySQL Il faut maintenant installer MySQL. Si vous n'avez pas déjà MySQL installé sur diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index d3d0f4cb..f072e6fc 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -65,4 +65,7 @@ sudo -H -u vagrant crontab provisioning/cron.dev pip install daphne apt-get install -y supervisor cp /vagrant/provisioning/supervisor.conf /etc/supervisor/conf.d/gestiocof.conf +sed "s/{DBUSER}/$DBUSER/" -i /etc/supervisor/conf.d/gestiocof.conf +sed "s/{DBNAME}/$DBNAME/" -i /etc/supervisor/conf.d/gestiocof.conf +sed "s/{DBPASSWD}/$DBPASSWD/" -i /etc/supervisor/conf.d/gestiocof.conf service supervisor restart diff --git a/provisioning/supervisor.conf b/provisioning/supervisor.conf index 487defe3..4c46b952 100644 --- a/provisioning/supervisor.conf +++ b/provisioning/supervisor.conf @@ -2,7 +2,7 @@ command=/usr/bin/python /vagrant/manage.py runworker directory=/vagrant/ user=vagrant -environment=DBUSER="cof_gestion",DBNAME="cof_gestion",DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4",DJANGO_SETTINGS_MODULE="cof.settings_dev" +environment=DBUSER={DBUSER},DBNAME={DBNAME},DBPASSWD={DBPASSWD},DJANGO_SETTINGS_MODULE="cof.settings_dev" autostart=true autorestart=true redirect_stderr=true @@ -11,7 +11,7 @@ redirect_stderr=true [program:interface] command=/usr/local/bin/daphne -b 127.0.0.1 -p 8001 cof.asgi:channel_layer -environment=DBUSER="cof_gestion",DBNAME="cof_gestion",DBPASSWD="4KZt3nGPLVeWSvtBZPSM3fSzXpzEU4" +environment=DBUSER={DBUSER},DBNAME={DBNAME},DBPASSWD={DBPASSWD},DJANGO_SETTINGS_MODULE="cof.settings_dev" directory=/vagrant/ redirect_stderr=true autostart=true From 2bae32a10558d761f1c1e5ff291441d4942a9a86 Mon Sep 17 00:00:00 2001 From: Hugo Roussille Date: Wed, 14 Sep 2016 16:22:30 +0200 Subject: [PATCH 16/26] Ajouts et corrections --- bda/templates/descriptions.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bda/templates/descriptions.html b/bda/templates/descriptions.html index a993848a..a229757b 100644 --- a/bda/templates/descriptions.html +++ b/bda/templates/descriptions.html @@ -3,6 +3,7 @@ + @@ -75,7 +79,7 @@ From ac3c79daca1937ec4cc642d3763bf952f8023d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 22 Sep 2016 14:01:01 +0200 Subject: [PATCH 19/26] Fix petits cours --- gestioncof/petits_cours_views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index b7b9cd36..1a31115d 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -135,7 +135,7 @@ def _finalize_traitement(request, demande, proposals, proposed_for, unsatisfied, attribdata, redo=False, errors=None): proposals = proposals.items() proposed_for = proposed_for.items() - # attribdata = attribdata.items() + attribdata = list(attribdata.items()) proposed_mails = _generate_eleve_email(demande, proposed_for) mainmail = render_template("petits-cours-mail-demandeur.txt", {"proposals": proposals, @@ -153,7 +153,8 @@ def _finalize_traitement(request, demande, proposals, proposed_for, "proposed_mails": proposed_mails, "mainmail": mainmail, "attribdata": - base64.b64encode(simplejson.dumps(attribdata).encode('utf_8')), + base64.b64encode(simplejson.dumps(attribdata) + .encode('utf_8')), "redo": redo, "errors": errors, }) From d89493856f5457e424349a68de39bf71c760d807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 24 Sep 2016 17:34:15 +0200 Subject: [PATCH 20/26] Fix: inscriptions bda MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problèmes d'encodage sur la fonction `_hash_queryset` --- bda/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bda/views.py b/bda/views.py index 4ea0df32..4cf3dd03 100644 --- a/bda/views.py +++ b/bda/views.py @@ -66,7 +66,7 @@ def etat_places(request, tirage_id): def _hash_queryset(queryset): - data = serializers.serialize("json", queryset).encode() + data = serializers.serialize("json", queryset).encode('utf-8') hasher = hashlib.sha256() hasher.update(data) return hasher.hexdigest() From 05e48386a1f53ea10bf088af54f8a24d793f30e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 24 Sep 2016 18:44:35 +0200 Subject: [PATCH 21/26] Ajustements, fix --- gestioncof/views.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gestioncof/views.py b/gestioncof/views.py index 3148308a..80f528f7 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -346,7 +346,7 @@ def registration_form2(request, login_clipper=None, username=None): registration_set_ro_fields(user_form, profile_form) # events & clubs event_formset = EventFormset(events=events, prefix='events') - clubs_form = ClubsForm(initial={'clubs': member.clubs.all()}) + clubs_form = ClubsForm() if username: member = get_object_or_404(User, username=username) (profile, _) = CofProfile.objects.get_or_create(user=member) diff --git a/requirements.txt b/requirements.txt index d7cada42..2d1109eb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ configparser==3.5.0 Django==1.8 django-autocomplete-light==2.3.3 django-autoslug==1.9.3 -django-cas-ng==3.5.4 +git+https://github.com/xapantu/django-cas-ng.git#egg=django-cas-ng django-grappelli==2.8.1 django-recaptcha==1.0.5 mysqlclient==1.3.7 From 38bb59b004c51298386e554b908718d1f97c880b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 12 Sep 2016 22:08:39 +0200 Subject: [PATCH 22/26] =?UTF-8?q?Permet=20l'ajout=20d'un=20pr=C3=A9fixe=20?= =?UTF-8?q?dans=20les=20urls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cof/urls.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cof/urls.py b/cof/urls.py index ca7ea247..263fc3a0 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -24,7 +24,7 @@ from gestioncof.autocomplete import autocomplete autocomplete_light.autodiscover() admin.autodiscover() -urlpatterns = [ +my_urlpatterns = [ # Page d'accueil url(r'^$', gestioncof_views.home, name='home'), # Le BdA @@ -88,3 +88,7 @@ urlpatterns = [ else []) # Si on est en production, MEDIA_ROOT est servi par Apache. # Il faut dire à Django de servir MEDIA_ROOT lui-même en développement. + +urlpatterns = [ + url(r'^gestion/', include(my_urlpatterns)) +] From 54409fb85f458c9220554c51305a99c9521a712e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 24 Sep 2016 19:34:36 +0200 Subject: [PATCH 23/26] Modif pour la production --- apache/__init__.py | 0 apache/django.wsgi | 7 ------- apache/wsgi.py | 18 ------------------ cof/asgi.py | 3 ++- 4 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 apache/__init__.py delete mode 100644 apache/django.wsgi delete mode 100644 apache/wsgi.py diff --git a/apache/__init__.py b/apache/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/apache/django.wsgi b/apache/django.wsgi deleted file mode 100644 index 7b9c271d..00000000 --- a/apache/django.wsgi +++ /dev/null @@ -1,7 +0,0 @@ -import os, sys -sys.path.append (os.path.expanduser ('~gestion/www')) -os.environ['DJANGO_SETTINGS_MODULE'] = 'cof.settings' - -import django.core.handlers.wsgi - -application = django.core.handlers.wsgi.WSGIHandler() diff --git a/apache/wsgi.py b/apache/wsgi.py deleted file mode 100644 index 177542a8..00000000 --- a/apache/wsgi.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -WSGI config for myproject project. -It exposes the WSGI callable as a module-level variable named ``application``. -For more information on this file, see -https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ -""" - -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -import os -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") -application = get_wsgi_application() diff --git a/cof/asgi.py b/cof/asgi.py index bb1b3b83..a34621c7 100644 --- a/cof/asgi.py +++ b/cof/asgi.py @@ -1,6 +1,7 @@ import os from channels.asgi import get_channel_layer -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings_dev") +if "DJANGO_SETTINGS_MODULE" not in os.environ: + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") channel_layer = get_channel_layer() From 68153652d03988fa07fa2dc88604a74106ff2dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 24 Sep 2016 19:40:16 +0200 Subject: [PATCH 24/26] Protection de la vue autocomplete --- gestioncof/autocomplete.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gestioncof/autocomplete.py b/gestioncof/autocomplete.py index 5b4616be..ed0a1e5a 100644 --- a/gestioncof/autocomplete.py +++ b/gestioncof/autocomplete.py @@ -10,8 +10,10 @@ from django.db.models import Q from django.contrib.auth.models import User from gestioncof.models import CofProfile, Clipper +from gestioncof.decorators import buro_required +@buro_required def autocomplete(request): if "q" not in request.GET: raise Http404 From 3bf4e6ae06caf9a352f0d0dfd99d4539fff22f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 24 Sep 2016 19:34:36 +0200 Subject: [PATCH 25/26] Modif pour la production MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Suppression du dossier `apache` devenu inutile. - On utilise `cof.settings` dans le fichier `asgi.py` par défaut - Correction dans les urls du fichier de settings en lien avec les nouvelles urls en `/gestion/...` --- apache/__init__.py | 0 apache/django.wsgi | 7 ------- apache/wsgi.py | 18 ------------------ cof/asgi.py | 3 ++- cof/settings_dev.py | 6 +++--- 5 files changed, 5 insertions(+), 29 deletions(-) delete mode 100644 apache/__init__.py delete mode 100644 apache/django.wsgi delete mode 100644 apache/wsgi.py diff --git a/apache/__init__.py b/apache/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/apache/django.wsgi b/apache/django.wsgi deleted file mode 100644 index 7b9c271d..00000000 --- a/apache/django.wsgi +++ /dev/null @@ -1,7 +0,0 @@ -import os, sys -sys.path.append (os.path.expanduser ('~gestion/www')) -os.environ['DJANGO_SETTINGS_MODULE'] = 'cof.settings' - -import django.core.handlers.wsgi - -application = django.core.handlers.wsgi.WSGIHandler() diff --git a/apache/wsgi.py b/apache/wsgi.py deleted file mode 100644 index 177542a8..00000000 --- a/apache/wsgi.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -WSGI config for myproject project. -It exposes the WSGI callable as a module-level variable named ``application``. -For more information on this file, see -https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ -""" - -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -import os -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") -application = get_wsgi_application() diff --git a/cof/asgi.py b/cof/asgi.py index bb1b3b83..a34621c7 100644 --- a/cof/asgi.py +++ b/cof/asgi.py @@ -1,6 +1,7 @@ import os from channels.asgi import get_channel_layer -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings_dev") +if "DJANGO_SETTINGS_MODULE" not in os.environ: + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") channel_layer = get_channel_layer() diff --git a/cof/settings_dev.py b/cof/settings_dev.py index f9adb2cf..38d36390 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -152,12 +152,12 @@ PETITS_COURS_REPLYTO = "cof@ens.fr" RAPPEL_FROM = 'Le BdA ' RAPPEL_REPLY_TO = RAPPEL_FROM -LOGIN_URL = "/login" -LOGIN_REDIRECT_URL = "/" +LOGIN_URL = "/gestion/login" +LOGIN_REDIRECT_URL = "/gestion/" CAS_SERVER_URL = 'https://cas.eleves.ens.fr/' CAS_IGNORE_REFERER = True -CAS_REDIRECT_URL = '/' +CAS_REDIRECT_URL = '/gestion/' CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', From 5d05b220fd865d0bad483c2ae7ca5bca5bebf3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Sun, 25 Sep 2016 23:35:29 +0200 Subject: [PATCH 26/26] Fix touche H sur K-Psul --- kfet/templates/kfet/kpsul.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index ca401ccb..0eceebd2 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -1240,9 +1240,10 @@ $(document).ready(function() { case 72: if (e.ctrlKey) { // Ctrl+H - Display help + e.preventDefault(); $('.help').show('fast'); } - return false; + return true; case 112: // F1 - Cool reset coolReset();