diff --git a/elections/forms.py b/elections/forms.py index a570c41..cc29e64 100644 --- a/elections/forms.py +++ b/elections/forms.py @@ -4,6 +4,7 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from .models import Election, Option, Question +from .utils import check_csv class ElectionForm(forms.ModelForm): @@ -29,6 +30,14 @@ class UploadVotersForm(forms.Form): def clean_csv_file(self): csv_file = self.cleaned_data["csv_file"] + if csv_file.name.lower().endswith(".csv"): + for error in check_csv(csv_file): + self.add_error(None, error) + else: + self.add_error( + None, + _("Extension de fichier invalide, il faut un fichier au format CSV."), + ) return csv_file diff --git a/elections/templates/elections/upload_voters.html b/elections/templates/elections/upload_voters.html index c8b4e97..ac4aaa7 100644 --- a/elections/templates/elections/upload_voters.html +++ b/elections/templates/elections/upload_voters.html @@ -11,7 +11,7 @@ const fileName = document.querySelector('#import-voters .file-name'); fileName.textContent = fileInput.files[0].name; } - } + }; }); @@ -30,6 +30,14 @@
+ {% if form.non_field_errors %} +
+ + {% for error in form.non_field_errors %} + {{ error }}
+ {% endfor %} +
+ {% endif %}
{% csrf_token %} diff --git a/elections/utils.py b/elections/utils.py index 3572dca..bbcddd8 100644 --- a/elections/utils.py +++ b/elections/utils.py @@ -1,6 +1,10 @@ import csv import io +from django.core.exceptions import ValidationError +from django.core.validators import validate_email +from django.utils.translation import gettext_lazy as _ + def create_users(election, csv_file): """Crée les votant·e·s pour l'élection donnée, en remplissant les champs @@ -13,3 +17,53 @@ def create_users(election, csv_file): election.registered_voters.create( username=f"{election.id}__{username}", email=email ) + + +def check_csv(csv_file): + """Vérifie que le fichier donnant la liste de votant·e·s est bien formé""" + try: + dialect = csv.Sniffer().sniff(csv_file.read(1024).decode("utf-8")) + except csv.Error: + return [ + _( + "Format invalide. Vérifiez que le fichier est bien formé (i.e. " + "chaque ligne de la forme 'login,nom,email')." + ) + ] + csv_file.seek(0) + reader = csv.reader(io.StringIO(csv_file.read().decode("utf-8")), dialect) + + columns = [_("login"), _("nom"), _("email")] + + errors = [] + line_nb = 0 + for line in reader: + line_nb += 1 + if len(line) != 3: + errors.append( + _("La ligne {} n'a pas le bon nombre d'éléments.").format(line_nb) + ) + else: + if line[0] == "" or line[1] == "": + errors.append( + _("Valeur manquante dans la ligne {} : '{}'.").format( + line_nb, columns[line.index("")] + ) + ) + try: + validate_email(line[2]) + except ValidationError: + errors.append( + _("Adresse mail invalide à la ligne {} : '{}'.").format( + line_nb, line[2] + ) + ) + + return errors + + +def send_mail(election): + """Envoie le mail d'annonce de l'élection avec identifiants et mot de passe + aux votant·e·s, le mdp est généré en même temps que le mail est envoyé. + """ + pass