Split in 2 commands

This commit is contained in:
Ludovic Stephan 2020-11-13 17:23:17 +01:00
parent df10e754a5
commit 1d24478c1d
3 changed files with 91 additions and 41 deletions

View file

@ -121,14 +121,14 @@ class AnnuaireLDAP(LDAP):
search_base = "ou=people,dc=ens,dc=fr"
attr_list = ["uid", "sn", "givenName", "ou"]
def try_match(self, clipper):
"""Essaie de trouver une entrée correspondant au compte clipper donné dans
def try_match(self, profile):
"""Essaie de trouver une entrée correspondant au profile donné dans
l'annuaire de l'ENS. L'heuristique est la suivante : il est très probable
que le prénom de la personne commence par le premier mot de `clipper.fullname`,
que le prénom de la personne commence par le premier mot de `profile.full_name`,
et que son nom de famille finisse par le dernier mot.
"""
given_name = clipper.name.split(" ")[0]
last_name = clipper.name.split(" ")[-1]
given_name = profile.full_name.split(" ")[0]
last_name = profile.full_name.split(" ")[-1]
search_name = self.search(
"(&(givenName={}*)(sn=*{}))".format(given_name, last_name)
@ -136,7 +136,11 @@ class AnnuaireLDAP(LDAP):
if len(search_name) > 0:
if len(search_name) > 2:
print("Erreur : deux résultats trouvés pour {}".format(clipper.uid))
print(
"Erreur : deux résultats trouvés pour {}".format(
profile.user.username
)
)
return None
return self.extract_ldap_info(search_name[0], "uid")

View file

@ -1,22 +1,15 @@
from datetime import date
from io import BytesIO
from urllib.error import HTTPError
from urllib.request import urlopen
from django.conf import settings
from django.contrib.auth.models import User
from django.core.files import File
from django.core.management.base import BaseCommand
from fiches.models import Department, Profile
from ._ldap import AnnuaireLDAP, ClipperLDAP
from ._ldap import ClipperLDAP
class Command(BaseCommand):
help = (
"Importe les noms et (si possible) les photos des conscrit·e·s dans l'annuaire."
)
help = "Crée les fiches annuaire des conscrit·e·s automatiquement"
def add_arguments(self, parser):
group = parser.add_mutually_exclusive_group()
@ -25,12 +18,6 @@ class Command(BaseCommand):
)
group.add_argument("--promo", help="Spécifie la promotion à importer")
parser.add_argument(
"--without-photos",
action="store_true",
help="N'essaie pas d'importer les photos associées",
)
def get_current_promo(self):
today = date.today()
year = today.year
@ -83,27 +70,13 @@ class Command(BaseCommand):
User.objects.bulk_create(users_to_create)
for profile in profiles_to_create:
profile.user_id = profile.user.id
profiles = Profile.objects.bulk_create(profiles_to_create)
Profile.objects.bulk_create(profiles_to_create)
for dept_m2m in dept_m2m_to_create:
dept_m2m.profile_id = dept_m2m.profile.id
Profile.department.through.objects.bulk_create(dept_m2m_to_create)
# Gestion des images
if not options["without_photos"]:
cri_ldap = AnnuaireLDAP()
base_annuaire = "{PROTOCOL}://{URL}:{PORT}".format(**settings.ANNUAIRE)
for clipper, profile in zip(clippers, profiles):
cri_login = cri_ldap.try_match(clipper)
if cri_login is not None:
img_url = "{}/photos/{}.jpg".format(base_annuaire, cri_login)
try:
istream = urlopen(img_url)
profile.picture.save(
name="{}.jpg".format(profile.user.username),
content=File(BytesIO(istream.read())),
)
except HTTPError:
# Parfois il y a une erreur 404 : dans ce cas, pas de photo
pass
print(
"Création de {} utilisateur·ices et de {} profils effectuée avec succès".format(
len(users_to_create), len(profiles_to_create)
)
)

View file

@ -0,0 +1,73 @@
from datetime import date
from io import BytesIO
from urllib.error import HTTPError
from urllib.request import urlopen
from django.conf import settings
from django.core.files import File
from django.core.management.base import BaseCommand
from fiches.models import Profile
from ._ldap import AnnuaireLDAP
class Command(BaseCommand):
help = "Si possible, import les photos des conscrit·e·s dans l'annuaire."
def add_arguments(self, parser):
group = parser.add_mutually_exclusive_group()
group.add_argument(
"--all", action="store_true", help="Importe l'intégralité des promotions"
)
group.add_argument("--promo", help="Spécifie la promotion à importer")
def get_current_promo(self):
today = date.today()
year = today.year
if today.month < 9:
year -= 1
return year
def handle(self, *args, **options):
if options["all"]:
promo = None
elif options["promo"] is not None:
promo = options["promo"]
if len(promo) == 2:
promo = "20" + promo
else:
promo = self.get_current_promo()
no_images = Profile.objects.select_related("user").filter(picture="")
if promo is not None:
no_images = no_images.filter(promotion=promo)
cri_ldap = AnnuaireLDAP()
base_annuaire = "{PROTOCOL}://{URL}:{PORT}".format(**settings.ANNUAIRE)
success = 0
for profile in no_images:
cri_login = cri_ldap.try_match(profile)
if cri_login is not None:
img_url = "{}/photos/{}.jpg".format(base_annuaire, cri_login)
try:
istream = urlopen(img_url)
profile.picture.save(
name="{}.jpg".format(profile.user.username),
content=File(BytesIO(istream.read())),
)
success += 1
except HTTPError:
# Parfois, même si on trouve un login CRI, il y a une erreur 404.
# Dans ce cas, pas de photo : on échoue gracieusement.
pass
print(
"{} profils traités ; {} images importées.".format(
no_images.count(), success
)
)