From df06c5d2a49abe74766eeedfdaa4c3dd7a9fa8e1 Mon Sep 17 00:00:00 2001 From: Ju Luiselli Date: Sat, 8 Feb 2020 11:32:47 +0100 Subject: [PATCH 1/4] added dep and promotion to results --- fiches/templates/fiches/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fiches/templates/fiches/home.html b/fiches/templates/fiches/home.html index 3d47ff0..28a9b20 100644 --- a/fiches/templates/fiches/home.html +++ b/fiches/templates/fiches/home.html @@ -12,7 +12,7 @@
From 0a3e9b28dfcf5dfc7ca09cae45de929c010ffc8c Mon Sep 17 00:00:00 2001 From: Ju Luiselli Date: Sat, 8 Feb 2020 14:10:14 +0100 Subject: [PATCH 2/4] Added birthday page --- annuaire/urls.py | 5 +++-- fiches/models.py | 3 +++ fiches/templates/fiches/base.html | 2 +- fiches/templates/fiches/birthday.html | 17 +++++++++++++++++ fiches/templates/fiches/home.html | 2 +- fiches/templates/fiches/search.html | 21 --------------------- fiches/views.py | 13 +++++++++++++ 7 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 fiches/templates/fiches/birthday.html delete mode 100644 fiches/templates/fiches/search.html diff --git a/annuaire/urls.py b/annuaire/urls.py index 17f0e1d..b8febf5 100644 --- a/annuaire/urls.py +++ b/annuaire/urls.py @@ -17,12 +17,13 @@ from django.conf import settings from django.contrib import admin from django.urls import path, include from django.conf.urls.static import static -from fiches.views import home +from fiches.views import home, birthday urlpatterns = [ path('admin/', admin.site.urls), path('fiche/', include('fiches.urls')), - path('', home, name='home') + path('', home, name='home'), + path('birthday', birthday, name='birthday') ] if settings.DEBUG: diff --git a/fiches/models.py b/fiches/models.py index 7793fdb..02ff5ab 100644 --- a/fiches/models.py +++ b/fiches/models.py @@ -33,6 +33,9 @@ class Profile(models.Model): def __str__(self): return self.full_name + def birthday(): + return self.birth_date.strftime("%d%m") + class Department(models.Model): name = models.CharField(max_length=255, verbose_name=_("nom du département")) diff --git a/fiches/templates/fiches/base.html b/fiches/templates/fiches/base.html index 9c076eb..0e4fa7b 100644 --- a/fiches/templates/fiches/base.html +++ b/fiches/templates/fiches/base.html @@ -28,7 +28,7 @@ Accueil Modifier sa fiche d'annuaire Consulter sa fiche d'annuaire - Anniversaires à venir + Anniversaires à venir
diff --git a/fiches/templates/fiches/birthday.html b/fiches/templates/fiches/birthday.html new file mode 100644 index 0000000..0b30ca5 --- /dev/null +++ b/fiches/templates/fiches/birthday.html @@ -0,0 +1,17 @@ +{% extends "fiches/base.html" %} +{% block content %} + +

Anniversaires

+ + +
+ +
+ + +{% endblock %} \ No newline at end of file diff --git a/fiches/templates/fiches/home.html b/fiches/templates/fiches/home.html index 28a9b20..c2d2f52 100644 --- a/fiches/templates/fiches/home.html +++ b/fiches/templates/fiches/home.html @@ -1,7 +1,7 @@ {% extends "fiches/base.html" %} {% block content %} -

Chercher quelqu'un.e dans l'annuaire

+

Chercher quelqu'un·e dans l'annuaire

{% csrf_token %} {{ form.as_p }} diff --git a/fiches/templates/fiches/search.html b/fiches/templates/fiches/search.html deleted file mode 100644 index 15eb066..0000000 --- a/fiches/templates/fiches/search.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "fiches/base.html" %} -{% block content %} - -

Chercher quelqu'un.e dans l'annuaire

- - {% csrf_token %} - {{ form.as_p }} - -
- -
- -
- - -{% endblock %} diff --git a/fiches/views.py b/fiches/views.py index 5b50a4b..649060e 100644 --- a/fiches/views.py +++ b/fiches/views.py @@ -5,6 +5,8 @@ from fiches.models import Profile from fiches.forms import ProfileForm, SearchForm from django.urls import reverse from django.db.models import Q +from django.utils import timezone +from datetime import timedelta @login_required @@ -39,3 +41,14 @@ def home(request): else: form = SearchForm() return render(request,'fiches/home.html',{"form":form}) + + +@login_required +def birthday(request): + today = timezone.now() + result = list(Profile.objects.filter(birth_date__day=today.day, birth_date__month=today.month)) + for i in range(1,7): + today = today + timedelta(days=1) + result += list(Profile.objects.filter(birth_date__day=today.day, birth_date__month=today.month)) + return render(request,'fiches/birthday.html',{"result":result}) + From 14bc4927ed27208e87c703f24e7ba6815821e529 Mon Sep 17 00:00:00 2001 From: Ju Luiselli Date: Wed, 12 Feb 2020 23:21:24 +0100 Subject: [PATCH 3/4] added CAS authentification --- annuaire/settings.py | 11 +++++++++++ annuaire/urls.py | 5 ++++- fiches/forms.py | 4 +++- fiches/migrations/0004_auto_20200212_2130.py | 20 ++++++++++++++++++++ fiches/templates/fiches/base.html | 5 +++++ requirements.txt | 3 ++- 6 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 fiches/migrations/0004_auto_20200212_2130.py diff --git a/annuaire/settings.py b/annuaire/settings.py index 657cae3..0501811 100644 --- a/annuaire/settings.py +++ b/annuaire/settings.py @@ -36,6 +36,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django_cas_ng', 'fiches' ] @@ -67,6 +68,11 @@ TEMPLATES = [ }, ] +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'django_cas_ng.backends.CASBackend', +) + WSGI_APPLICATION = 'annuaire.wsgi.application' @@ -123,3 +129,8 @@ STATIC_URL = '/static/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' + +CAS_SERVER_URL = 'https://cas.eleves.ens.fr/' + +CAS_VERSION = "2" + diff --git a/annuaire/urls.py b/annuaire/urls.py index b8febf5..85e272c 100644 --- a/annuaire/urls.py +++ b/annuaire/urls.py @@ -18,12 +18,15 @@ from django.contrib import admin from django.urls import path, include from django.conf.urls.static import static from fiches.views import home, birthday +import django_cas_ng.views as cas_views urlpatterns = [ path('admin/', admin.site.urls), path('fiche/', include('fiches.urls')), path('', home, name='home'), - path('birthday', birthday, name='birthday') + path('birthday', birthday, name='birthday'), + path('login', cas_views.LoginView.as_view(), name='cas_ng_login'), + path('logout', cas_views.LogoutView.as_view(), name='cas_ng_logout'), ] if settings.DEBUG: diff --git a/fiches/forms.py b/fiches/forms.py index 83c20c0..28a72ea 100644 --- a/fiches/forms.py +++ b/fiches/forms.py @@ -22,7 +22,9 @@ class ProfileForm(forms.ModelForm): class SearchForm(forms.Form): name = forms.CharField(label='Nom/Surnom', max_length=1023, required=False) year = forms.IntegerField(label='Promotion', required=False) - department = forms.ModelMultipleChoiceField(queryset=Department.objects.all(), required=False) + department = forms.ModelMultipleChoiceField( + queryset=Department.objects.all(), required=False + ) def clean(self): cleaned_data = super().clean() diff --git a/fiches/migrations/0004_auto_20200212_2130.py b/fiches/migrations/0004_auto_20200212_2130.py new file mode 100644 index 0000000..672d23f --- /dev/null +++ b/fiches/migrations/0004_auto_20200212_2130.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.9 on 2020-02-12 21:30 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('fiches', '0003_auto_20200108_2306'), + ] + + operations = [ + migrations.AlterField( + model_name='profile', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL, verbose_name='utilisateur'), + ), + ] diff --git a/fiches/templates/fiches/base.html b/fiches/templates/fiches/base.html index 0e4fa7b..dd66119 100644 --- a/fiches/templates/fiches/base.html +++ b/fiches/templates/fiches/base.html @@ -29,6 +29,11 @@ Modifier sa fiche d'annuaire Consulter sa fiche d'annuaire Anniversaires à venir + {% if user.is_authenticated %} + Se déconnecter + {% else %} + Se connecter + {% endif %} diff --git a/requirements.txt b/requirements.txt index 1b3a0c4..4e4fcaf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ django==2.2.* -Pillow \ No newline at end of file +Pillow +django_cas_ng From 6d6be7ddf2fd925ab25909e5a5c66131cbfd6b9b Mon Sep 17 00:00:00 2001 From: Ju Luiselli Date: Thu, 13 Feb 2020 00:11:28 +0100 Subject: [PATCH 4/4] send mail upon modification --- annuaire/settings.py | 1 + fiches/apps.py | 2 +- fiches/forms.py | 14 ++++--- fiches/templates/fiches/mail/mail_modif.txt | 6 +++ fiches/urls.py | 6 +-- fiches/views.py | 45 ++++++++++++++------- 6 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 fiches/templates/fiches/mail/mail_modif.txt diff --git a/annuaire/settings.py b/annuaire/settings.py index 0501811..b102e1c 100644 --- a/annuaire/settings.py +++ b/annuaire/settings.py @@ -134,3 +134,4 @@ CAS_SERVER_URL = 'https://cas.eleves.ens.fr/' CAS_VERSION = "2" +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' diff --git a/fiches/apps.py b/fiches/apps.py index 929f294..45d45ef 100644 --- a/fiches/apps.py +++ b/fiches/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class FichesConfig(AppConfig): - name = 'fiches' + name = "fiches" diff --git a/fiches/forms.py b/fiches/forms.py index 28a72ea..934f624 100644 --- a/fiches/forms.py +++ b/fiches/forms.py @@ -15,18 +15,22 @@ class ProfileForm(forms.ModelForm): "thurne", "text_field", "printing", - "keep_me" + "keep_me", ] class SearchForm(forms.Form): - name = forms.CharField(label='Nom/Surnom', max_length=1023, required=False) - year = forms.IntegerField(label='Promotion', required=False) + name = forms.CharField(label="Nom/Surnom", max_length=1023, required=False) + year = forms.IntegerField(label="Promotion", required=False) department = forms.ModelMultipleChoiceField( queryset=Department.objects.all(), required=False ) def clean(self): cleaned_data = super().clean() - if (not cleaned_data['name'] and not cleaned_data['year'] and not cleaned_data['department']): - raise forms.ValidationError(('Tous les champs sont vides'), code='invalid') \ No newline at end of file + if ( + not cleaned_data["name"] + and not cleaned_data["year"] + and not cleaned_data["department"] + ): + raise forms.ValidationError(("Tous les champs sont vides"), code="invalid") diff --git a/fiches/templates/fiches/mail/mail_modif.txt b/fiches/templates/fiches/mail/mail_modif.txt new file mode 100644 index 0000000..0d16f2f --- /dev/null +++ b/fiches/templates/fiches/mail/mail_modif.txt @@ -0,0 +1,6 @@ +Bonjour {{profile.full_name}}, + +Ta fiche annuaire a été modifiée ! + +Cordialement, +le Klub Dev \ No newline at end of file diff --git a/fiches/urls.py b/fiches/urls.py index 918c628..d9a7510 100644 --- a/fiches/urls.py +++ b/fiches/urls.py @@ -2,6 +2,6 @@ from django.urls import path from . import views urlpatterns = [ - path('',views.fiche, name='fiche'), - path('edit',views.fiche_modif, name='fiche_modif') - ] + path("", views.fiche, name="fiche"), + path("edit", views.fiche_modif, name="fiche_modif"), +] diff --git a/fiches/views.py b/fiches/views.py index 649060e..77aac83 100644 --- a/fiches/views.py +++ b/fiches/views.py @@ -7,48 +7,65 @@ from django.urls import reverse from django.db.models import Q from django.utils import timezone from datetime import timedelta +from django.core.mail import send_mail +from django.template.loader import render_to_string @login_required def fiche(request, id): profile = get_object_or_404(Profile, id=id) - return render(request, 'fiches/fiche.html', {"profile": profile}) + return render(request, "fiches/fiche.html", {"profile": profile}) @login_required def fiche_modif(request): profile = request.user.profile - if request.method == 'POST': + if request.method == "POST": form = ProfileForm(request.POST, instance=profile) if form.is_valid(): form.save() - return redirect(reverse('fiche', args=(profile.id,))) + send_mail( + "Fiche annuaire modifée", + render_to_string("fiches/mail/mail_modif.txt", {"profile": profile}), + "klub-dev@ens.psl.eu", + ["{}@clipper.ens.psl.eu".format(request.user.username)], + fail_silently=False, + ) + return redirect(reverse("fiche", args=(profile.id,))) + else: form = ProfileForm(instance=profile) - return render(request, 'fiches/fiches_modif.html', {"form": form}) - + return render(request, "fiches/fiches_modif.html", {"form": form}) @login_required def home(request): - if request.method == 'POST': + if request.method == "POST": form = SearchForm(request.POST) if form.is_valid(): - result = Profile.objects.filter(Q(full_name__icontains=form.cleaned_data['name']) | Q(nickname__icontains=form.cleaned_data['name'])) - return render(request,'fiches/home.html',{"form":form, "result":result}) + result = Profile.objects.filter( + Q(full_name__icontains=form.cleaned_data["name"]) + | Q(nickname__icontains=form.cleaned_data["name"]) + ) + return render(request, "fiches/home.html", {"form": form, "result": result}) else: form = SearchForm() - return render(request,'fiches/home.html',{"form":form}) + return render(request, "fiches/home.html", {"form": form}) @login_required def birthday(request): today = timezone.now() - result = list(Profile.objects.filter(birth_date__day=today.day, birth_date__month=today.month)) - for i in range(1,7): + result = list( + Profile.objects.filter(birth_date__day=today.day, birth_date__month=today.month) + ) + for i in range(1, 7): today = today + timedelta(days=1) - result += list(Profile.objects.filter(birth_date__day=today.day, birth_date__month=today.month)) - return render(request,'fiches/birthday.html',{"result":result}) - + result += list( + Profile.objects.filter( + birth_date__day=today.day, birth_date__month=today.month + ) + ) + return render(request, "fiches/birthday.html", {"result": result})