121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
import csv
|
|
import io
|
|
import random
|
|
|
|
from django.contrib.auth.hashers import make_password
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.mail import EmailMessage, get_connection
|
|
from django.core.validators import validate_email
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
def choices_length(choices):
|
|
"""Renvoie la longueur maximale des choix de choices"""
|
|
m = 0
|
|
for c in choices:
|
|
m = max(m, len(c[0]))
|
|
return m
|
|
|
|
|
|
def create_users(election, csv_file):
|
|
"""Crée les votant·e·s pour l'élection donnée, en remplissant les champs
|
|
`username`, `election` et `full_name`.
|
|
"""
|
|
dialect = csv.Sniffer().sniff(csv_file.readline().decode("utf-8"))
|
|
csv_file.seek(0)
|
|
reader = csv.reader(io.StringIO(csv_file.read().decode("utf-8")), dialect)
|
|
for (username, full_name, email) in reader:
|
|
election.registered_voters.create(
|
|
username=f"{election.id}__{username}", email=email, full_name=full_name
|
|
)
|
|
|
|
|
|
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.readline().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)
|
|
|
|
errors = []
|
|
users = {}
|
|
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] == "":
|
|
errors.append(
|
|
_("Valeur manquante dans la ligne {} : 'login'.").format(line_nb)
|
|
)
|
|
else:
|
|
if line[0] in users:
|
|
errors.append(
|
|
_("Doublon dans les logins : lignes {} et {}.").format(
|
|
line_nb, users[line[0]]
|
|
)
|
|
)
|
|
else:
|
|
users[line[0]] = line_nb
|
|
if line[1] == "":
|
|
errors.append(
|
|
_("Valeur manquante dans la ligne {} : 'nom'.").format(line_nb)
|
|
)
|
|
try:
|
|
validate_email(line[2])
|
|
except ValidationError:
|
|
errors.append(
|
|
_("Adresse mail invalide à la ligne {} : '{}'.").format(
|
|
line_nb, line[2]
|
|
)
|
|
)
|
|
|
|
return errors
|
|
|
|
|
|
def generate_password():
|
|
random.seed()
|
|
alphabet = "abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
|
password = ""
|
|
for i in range(15):
|
|
password += random.choice(alphabet)
|
|
|
|
return password
|
|
|
|
|
|
def send_mail(election, mail_form):
|
|
"""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é.
|
|
"""
|
|
from .models import User
|
|
|
|
voters = list(election.registered_voters.all())
|
|
url = f"https://kadenios.eleves.ens.fr/elections/view/{election.id}"
|
|
messages = []
|
|
for v in voters:
|
|
password = generate_password()
|
|
v.password = make_password(password)
|
|
messages.append(
|
|
EmailMessage(
|
|
subject=mail_form.cleaned_data["objet"],
|
|
body=mail_form.cleaned_data["message"].format(
|
|
full_name=v.full_name,
|
|
election_url=url,
|
|
username=v.get_username,
|
|
password=password,
|
|
),
|
|
to=[v.email],
|
|
)
|
|
)
|
|
get_connection(fail_silently=False).send_messages(messages)
|
|
User.objects.bulk_update(voters, ["password"])
|