Split in 2 commands
This commit is contained in:
parent
df10e754a5
commit
1d24478c1d
3 changed files with 91 additions and 41 deletions
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
)
|
||||
|
|
73
fiches/management/commands/get_photos.py
Normal file
73
fiches/management/commands/get_photos.py
Normal 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
|
||||
)
|
||||
)
|
Loading…
Add table
Reference in a new issue