Affiche les erreurs quand le fichier CSV est mal formé
This commit is contained in:
parent
e53cd7587f
commit
7bd9e5bfed
3 changed files with 72 additions and 1 deletions
|
@ -4,6 +4,7 @@ from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Election, Option, Question
|
from .models import Election, Option, Question
|
||||||
|
from .utils import check_csv
|
||||||
|
|
||||||
|
|
||||||
class ElectionForm(forms.ModelForm):
|
class ElectionForm(forms.ModelForm):
|
||||||
|
@ -29,6 +30,14 @@ class UploadVotersForm(forms.Form):
|
||||||
|
|
||||||
def clean_csv_file(self):
|
def clean_csv_file(self):
|
||||||
csv_file = self.cleaned_data["csv_file"]
|
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
|
return csv_file
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
const fileName = document.querySelector('#import-voters .file-name');
|
const fileName = document.querySelector('#import-voters .file-name');
|
||||||
fileName.textContent = fileInput.files[0].name;
|
fileName.textContent = fileInput.files[0].name;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -30,6 +30,14 @@
|
||||||
|
|
||||||
<div class="columns is-centered">
|
<div class="columns is-centered">
|
||||||
<div class="column is-two-thirds">
|
<div class="column is-two-thirds">
|
||||||
|
{% if form.non_field_errors %}
|
||||||
|
<div class="notification is-danger">
|
||||||
|
<button class="delete"></button>
|
||||||
|
{% for error in form.non_field_errors %}
|
||||||
|
{{ error }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<form action="" method="post" enctype="multipart/form-data" id="import-voters">
|
<form action="" method="post" enctype="multipart/form-data" id="import-voters">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import csv
|
import csv
|
||||||
import io
|
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):
|
def create_users(election, csv_file):
|
||||||
"""Crée les votant·e·s pour l'élection donnée, en remplissant les champs
|
"""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(
|
election.registered_voters.create(
|
||||||
username=f"{election.id}__{username}", email=email
|
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
|
||||||
|
|
Loading…
Reference in a new issue