From 8769aefeb79b1e948f26f7aedbd95bb345e616e8 Mon Sep 17 00:00:00 2001 From: ThomasBidot <77505438+ThomasBidot@users.noreply.github.com> Date: Sat, 17 Apr 2021 15:08:35 +0200 Subject: [PATCH] Notifications for Sec-Gen (#36) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Password reset feature (#8) * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * test * Added utf-8 support to exported csv and switched delimiter from , to ; in admin interface * Disabled emails while in dev * Added multi selection filter in admin * Fixed mail settings * Added year field to Tutor serializer * Fixed year updated before registration form filled * commit for automatic deploy * Testing CI * Added filtering in admin for registration validation * Added filter to student admin * Added school info * Fixed typo in filters * Sorties (#30) * Custom participation_inline css * Ordered student profiles by last modification date in admin * Ajouté infos sorties * Sortie thomas (#32) * Updated student admin filters (#28) * Password reset feature (#8) * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * test * Added utf-8 support to exported csv and switched delimiter from , to ; in admin interface * Disabled emails while in dev * Added multi selection filter in admin * Fixed mail settings * Added year field to Tutor serializer * Fixed year updated before registration form filled * commit for automatic deploy * Testing CI * Added filtering in admin for registration validation * Added filter to student admin Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> * Ajout filtre sur register * Ajout filtre participation * Ajout de 3 filtres par etablissements * Ajout 3 filtres pour etablissement V2 Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Witeden <58004019+Witeden@users.noreply.github.com> * Sortie thomas (export CSV sorties) (#33) * Updated student admin filters (#28) * Password reset feature (#8) * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * test * Added utf-8 support to exported csv and switched delimiter from , to ; in admin interface * Disabled emails while in dev * Added multi selection filter in admin * Fixed mail settings * Added year field to Tutor serializer * Fixed year updated before registration form filled * commit for automatic deploy * Testing CI * Added filtering in admin for registration validation * Added filter to student admin Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> * Ajout filtre sur register * Ajout filtre participation * Ajout de 3 filtres par etablissements * Ajout 3 filtres pour etablissement V2 * Ajout export CSV sorties Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Dylan Sechet <dylan.sechet82@gmail.com> Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Witeden <58004019+Witeden@users.noreply.github.com> * Update runtime.txt Changement version python * Ordering students by updated_date * Notifications for Sec-Gen (#35) * Custom participation_inline css * Ajout filtre sur register * Ajout filtre participation * Ordered student profiles by last modification date in admin * Ajouté infos sorties * Ajout de 3 filtres par etablissements * Ajout 3 filtres pour etablissement V2 * Sortie thomas (#32) * Updated student admin filters (#28) * Password reset feature (#8) * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * test * Added utf-8 support to exported csv and switched delimiter from , to ; in admin interface * Disabled emails while in dev * Added multi selection filter in admin * Fixed mail settings * Added year field to Tutor serializer * Fixed year updated before registration form filled * commit for automatic deploy * Testing CI * Added filtering in admin for registration validation * Added filter to student admin Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> * Ajout filtre sur register * Ajout filtre participation * Ajout de 3 filtres par etablissements * Ajout 3 filtres pour etablissement V2 Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Witeden <58004019+Witeden@users.noreply.github.com> * Ajout export CSV sorties * Sortie thomas (export CSV sorties) (#33) * Updated student admin filters (#28) * Password reset feature (#8) * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * Add Django Rest auth module * Try to make the send reset password email work * Modified template mail for reset * test * Added utf-8 support to exported csv and switched delimiter from , to ; in admin interface * Disabled emails while in dev * Added multi selection filter in admin * Fixed mail settings * Added year field to Tutor serializer * Fixed year updated before registration form filled * commit for automatic deploy * Testing CI * Added filtering in admin for registration validation * Added filter to student admin Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> * Ajout filtre sur register * Ajout filtre participation * Ajout de 3 filtres par etablissements * Ajout 3 filtres pour etablissement V2 * Ajout export CSV sorties Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> * Erreurs dans visits/admin résolus * Notifications for Sec-Gen Co-authored-by: Dylan Sechet <dylan.sechet82@gmail.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Witeden <58004019+Witeden@users.noreply.github.com> Co-authored-by: chiahetcho <44137047+chiahetcho@users.noreply.github.com> Co-authored-by: florimondmanca <florimond.manca@gmail.com> Co-authored-by: Dylan Sechet <dylan.sechet82@gmail.com> Co-authored-by: Arthur Guédon <arthur.guedon@student-cs.fr> Co-authored-by: Arthur Guédon <60623551+arthurgdn@users.noreply.github.com> Co-authored-by: Seon82 <46298009+Seon82@users.noreply.github.com> Co-authored-by: Bidot-Naude Thomas <thomas.bidotnaude@student-cs.fr> Co-authored-by: Witeden <58004019+Witeden@users.noreply.github.com> --- oser_backend/settings/common.py | 9 ++ profiles/admin.py | 19 ++-- profiles/models.py | 165 ++++++++++++++++---------------- register/admin.py | 19 ---- requirements.txt | 4 + visits/admin.py | 13 +-- 6 files changed, 115 insertions(+), 114 deletions(-) diff --git a/oser_backend/settings/common.py b/oser_backend/settings/common.py index 84ccf82..478aa5e 100644 --- a/oser_backend/settings/common.py +++ b/oser_backend/settings/common.py @@ -288,3 +288,12 @@ STATICFILES_DIRS = [ MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Telegram bot +TELEGRAM_BOT_TOKEN = os.getenv( + "TELEGRAM_BOT_TOKEN") +TELEGRAM = { + 'bot_token': TELEGRAM_BOT_TOKEN, + 'channel_name': 'oserSECGEN', + 'production': False, +} diff --git a/profiles/admin.py b/profiles/admin.py index 9c8efa2..b107212 100644 --- a/profiles/admin.py +++ b/profiles/admin.py @@ -7,6 +7,8 @@ import codecs import csv from django.http import HttpResponse + + class ExportCsvMixin: def export_as_csv(self, request, queryset): @@ -14,13 +16,15 @@ class ExportCsvMixin: field_names = [field.name for field in meta.fields] response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta) - response.write(codecs.BOM_UTF8) #force response to be UTF-8 + response['Content-Disposition'] = 'attachment; filename={}.csv'.format( + meta) + response.write(codecs.BOM_UTF8) # force response to be UTF-8 writer = csv.writer(response, delimiter=';') writer.writerow(field_names) for obj in queryset: - row = writer.writerow([getattr(obj, field) for field in field_names]) + row = writer.writerow([getattr(obj, field) + for field in field_names]) return response @@ -33,8 +37,9 @@ class ProfileAdminMixin: search_fields = ('user__email', 'user__first_name', 'user__last_name',) actions = ["export_as_csv"] + @admin.register(Tutor) -class TutorAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin): +class TutorAdmin(ProfileAdminMixin, admin.ModelAdmin, ExportCsvMixin): """Tutor admin panel.""" autocomplete_fields = ('address',) @@ -45,9 +50,11 @@ class TutorAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin): @admin.register(Student) -class StudentAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin): +class StudentAdmin(ProfileAdminMixin, admin.ModelAdmin, ExportCsvMixin): """Student admin panel.""" - list_filter = (('school',MultiSelectFieldListFilter), 'year', 'registration__validated') + list_filter = (('school', MultiSelectFieldListFilter), + 'year', 'registration__validated') + class Meta: # noqa model = Student ordering = ['-updated_date'] diff --git a/profiles/models.py b/profiles/models.py index 4c9d912..39f3925 100644 --- a/profiles/models.py +++ b/profiles/models.py @@ -7,6 +7,10 @@ from .utils import get_promotion_range from datetime import datetime from .notifications import SendDocs +import telegram +from django.conf import settings +from django.template.loader import render_to_string + class ProfileMixin: """Mixin with common functionnality for profiles.""" @@ -57,35 +61,34 @@ class Student(ProfileMixin, models.Model): ) classType = models.CharField(max_length=50, - null=True, - blank=True, - verbose_name="général/techno", - ) + null=True, + blank=True, + verbose_name="général/techno", + ) nationality = models.CharField(max_length=50, - null=True, - blank=True, - verbose_name="nationalité", - ) + null=True, + blank=True, + verbose_name="nationalité", + ) specialTeaching = models.CharField(max_length=50, - null=True, - blank=True, - verbose_name="enseignement de spécialité", - ) + null=True, + blank=True, + verbose_name="enseignement de spécialité", + ) zipCode = models.CharField(max_length=10, - null=True, - blank=True, - verbose_name="code postal", - ) - + null=True, + blank=True, + verbose_name="code postal", + ) gender = models.CharField(max_length=20, - null=True, - blank=True, - verbose_name="genre", - ) + null=True, + blank=True, + verbose_name="genre", + ) addressNumber = models.IntegerField( null=True, @@ -94,77 +97,70 @@ class Student(ProfileMixin, models.Model): ) street = models.CharField(max_length=70, - null=True, - blank=True, - verbose_name="nom de rue" - ) + null=True, + blank=True, + verbose_name="nom de rue" + ) city = models.CharField(max_length=50, - null=True, - blank=True, - verbose_name="nom de ville" - ) + null=True, + blank=True, + verbose_name="nom de ville" + ) personalPhone = models.CharField(max_length=12, - null=True, - blank=True, - verbose_name="numéro de téléphone personnel" - ) + null=True, + blank=True, + verbose_name="numéro de téléphone personnel" + ) parentsPhone = models.CharField(max_length=12, - null=True, - blank=True, - verbose_name="numéro de téléphone parental" - ) + null=True, + blank=True, + verbose_name="numéro de téléphone parental" + ) parentsEmail = models.EmailField(max_length=70, - null=True, - blank=True, - verbose_name="adresse mail parentale" - ) - + null=True, + blank=True, + verbose_name="adresse mail parentale" + ) school = models.CharField(max_length=70, - null=True, - blank=True, - verbose_name="établissement" - ) - + null=True, + blank=True, + verbose_name="établissement" + ) grade = models.CharField(max_length=20, - null=True, - blank=True, - verbose_name="niveau de la classe" - ) - + null=True, + blank=True, + verbose_name="niveau de la classe" + ) scholarship = models.CharField(max_length=50, - null=True, - blank=True, - verbose_name="boursier" - ) - + null=True, + blank=True, + verbose_name="boursier" + ) fatherActivity = models.CharField(max_length=70, - null=True, - blank=True, - verbose_name="métier du père" - ) - + null=True, + blank=True, + verbose_name="métier du père" + ) motherActivity = models.CharField(max_length=70, - null=True, - blank=True, - verbose_name="métier de la mère" - ) - + null=True, + blank=True, + verbose_name="métier de la mère" + ) parentsStatus = models.CharField(max_length=70, - null=True, - blank=True, - verbose_name="statut des parents" - ) - + null=True, + blank=True, + verbose_name="statut des parents" + ) dependantsNumber = models.IntegerField( null=True, @@ -173,10 +169,10 @@ class Student(ProfileMixin, models.Model): ) year = models.CharField(max_length=10, - null=True, - blank=True, - verbose_name="année" - ) + null=True, + blank=True, + verbose_name="année" + ) @staticmethod def has_write_permission(request): @@ -187,16 +183,25 @@ class Student(ProfileMixin, models.Model): def save(self, *args, **kwargs): """Updates the year field based on the last modified date""" - if self.city != None: # Ne mettre à jour que quand les données personnelles sont remplies + if self.city != None: # Ne mettre à jour que quand les données personnelles sont remplies date_now = datetime.now() - if date_now.month>=9: + if date_now.month >= 9: self.year = f"{date_now.year}/{date_now.year+1}" else: self.year = f"{date_now.year-1}/{date_now.year}" - SendDocs(user=self.user).send() # send email with link to registration docs + # send email with link to registration docs + SendDocs(user=self.user).send() + + # send a telegram message to oserSECGEN + telegram_settings = settings.TELEGRAM + if telegram_settings['bot_token'] != None: + message_telegram = "Un tutoré a renseigné ses données personnelles, il attend ta validation !" + bot = telegram.Bot(token=telegram_settings['bot_token']) + bot.send_message( + chat_id="@%s" % telegram_settings['channel_name'], text=message_telegram, parse_mode=telegram.ParseMode.HTML) - return super(Student,self).save(*args, **kwargs) + return super(Student, self).save(*args, **kwargs) class Meta: # noqa verbose_name = 'lycéen' diff --git a/register/admin.py b/register/admin.py index 482cba4..95a4138 100644 --- a/register/admin.py +++ b/register/admin.py @@ -5,25 +5,6 @@ from .models import Registration from profiles.models import Student -class SchoolFilter(admin.SimpleListFilter): - title = 'établissement' - parameter_name = 'profiles__school' - - def lookups(self, request, model_admin): - list_of_school = [] - query = Student.objects.values_list( - "school", flat=True).distinct() - for school in query: - list_of_school.append((school, school)) - return list_of_school - - def queryset(self, request, queryset): - if self.value(): - emails = Student.objects.filter( - school=self.value()).values_list("user__email", flat=True) - return queryset.filter(email__in=emails) - - class SchoolFilter(admin.SimpleListFilter): title = 'établissement' parameter_name = 'profiles__school' diff --git a/requirements.txt b/requirements.txt index 85baa93..e1b2a84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,10 @@ django-sendgrid-v5 django-filter django-rest-auth +# Telegram messages via python-telegram-bot +tornado==5.1.1 +python-telegram-bot==12.2.0 + # Storage of files in AWS S3 django-storages boto3 diff --git a/visits/admin.py b/visits/admin.py index 7d49e11..6ca578e 100644 --- a/visits/admin.py +++ b/visits/admin.py @@ -110,13 +110,11 @@ class ParticipationInline(admin.TabularInline): school = Student.objects.get(user = participation.user).school return school school.short_description = "Établissement" - def name(self, participation: Participation): """Returns the participation's user's name""" return participation.user.first_name + " " + participation.user.last_name name.short_description = "Nom" - class Media: css = { "all" : ("css/hide_admin_original.css",) } @@ -171,11 +169,10 @@ class ParticipationAdmin(admin.ModelAdmin): def school(self, participation: Participation): """Return a link to the participation's user's school.""" - school = Student.objects.get(user = participation.user).school + school = Student.objects.get(user=participation.user).school return school school.short_description = "Établissement" - def export_as_csv(self, request, queryset): meta = self.model._meta field_names = [field.name for field in meta.fields] @@ -205,8 +202,7 @@ class ParticipationAdmin(admin.ModelAdmin): export_as_csv.short_description = "Exporter sélection (en .csv)" - -@admin.register(Visit.organizers.through) +@ admin.register(Visit.organizers.through) class VisitOrganizersAdmin(admin.ModelAdmin): """Admin panel for visit organizers.""" @@ -220,7 +216,7 @@ class OrganizersInline(admin.TabularInline): extra = 0 -@admin.register(Visit) +@ admin.register(Visit) class VisitAdmin(admin.ModelAdmin): """Admin panel for visits.""" @@ -239,8 +235,7 @@ class VisitAdmin(admin.ModelAdmin): return obj.participants.count() num_participants.short_description = 'Participants' - -@admin.register(Place) +@ admin.register(Place) class PlaceAdmin(admin.ModelAdmin): """Admin panel for places.""" -- GitLab