Revisión 47
Añadido por Francisco Mora hace más de 14 años
update-fotos-ldap/trunk/actualizafotosldap.py | ||
---|---|---|
#!/usr/bin/python -tt
|
||
# -*- coding: utf-8 -*-
|
||
|
||
""" Programa para actualizar las fotos de los alumnos
|
||
en el servidor ldap a partir del fichero de alumnos generado por
|
||
Rayuela. Tambien depura las entradas del grupo students, eliminando
|
||
aquellas membresias cuyos uids no están en la rama People, si lo queremos.
|
||
|
||
Necesita paquetes instalados python python-ldap python-imaging
|
||
|
||
En los servidores de terminales está todo instalado excepto python-ldap
|
||
que se carga ejecutando la orden como superusuario:
|
||
|
||
apt-get install python-ldap
|
||
|
||
Uso: crearemos una carpeta donde copiaremos este programa y además
|
||
pondremos el ZIP generado por Rayuela, denominado
|
||
ExportacionDatosAlumnado.zip, ejecutaremos el script pasando como
|
||
parámetros como mínimo la contraseña del administrador ldap, por defecto
|
||
el programa establece el URI ldap de nuesto servidor ldap y la ruta a la
|
||
carpeta con el ZIP de rayuela en la propia carpeta.
|
||
|
||
Existe un parámetro, denominado --depurastudents {on|off} el cual si lo
|
||
establecemos a on, eliminará del grupos students de ldap aquellas entradas
|
||
que no tienen un uid en el grupo People, normalmente son residuos de
|
||
uids de alumnos que ya no están en el centro.
|
||
|
||
OJO: Realizar copias de seguridad de ldap antes de ejecutar el script...
|
||
|
||
|
||
Francisco Mora Sánchez
|
||
IES Maestro Juan Calero
|
||
adminies.maestrojuancalero@edu.juntaextremadura.net
|
||
|
||
|
||
"""
|
||
|
||
import sys,os,shutil,zipfile,ldap,Image,glob,time,copy
|
||
import ldap.modlist as modlist
|
||
|
||
# Set debugging level
|
||
#ldap.set_option(ldap.OPT_DEBUG_LEVEL,255)
|
||
#ldap.set_option(ldap.OPT_DEBUG_LEVEL,0)
|
||
#ldapmodule_trace_level = 1
|
||
#ldapmodule_trace_level = 0
|
||
#ldapmodule_trace_file = sys.stderr
|
||
|
||
def descomprime_zip_en_directorio(fichero, carpeta):
|
||
"""Funcion que dado un fichero zip lo descomprime en la
|
||
carpeta indicada."""
|
||
if os.path.exists(carpeta):
|
||
shutil.rmtree(carpeta)
|
||
os.mkdir(carpeta, 0777)
|
||
zfobj = zipfile.ZipFile(fichero)
|
||
for name in zfobj.namelist():
|
||
if name.endswith('/'):
|
||
os.mkdir(os.path.join(carpeta, name))
|
||
else:
|
||
outfile = open(os.path.join(carpeta, name), 'wb')
|
||
outfile.write(zfobj.read(name))
|
||
outfile.close()
|
||
|
||
def lee_parametros(lista,params):
|
||
"""Funcion que crea un diccionario para leer el valor de los
|
||
parametros que se pasan en la linea de comandos."""
|
||
for i in range(1,len(lista)):
|
||
if lista[i][:2] == "--":
|
||
#veamos si tiene valor
|
||
if i+1 < len(lista) and lista[i+1] <> "--":
|
||
#estamos en un parametro y valor
|
||
params[lista[i][2:]] = lista[i+1]
|
||
|
||
def conecta_a_ldap(uri,contra):
|
||
""" Conexión al servidor ldap
|
||
"""
|
||
try:
|
||
usuario_admin = "cn=admin,ou=People,dc=instituto,dc=extremadura,dc=es"
|
||
#conexion_ldap = ldap.initialize(uri,trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)
|
||
conexion_ldap = ldap.initialize(uri)
|
||
conexion_ldap.protocol_version=ldap.VERSION3
|
||
conexion_ldap.bind_s(usuario_admin, contra)
|
||
except ldap.LDAPError, e:
|
||
return None
|
||
|
||
return conexion_ldap
|
||
|
||
def desconecta_de_ldap(conexion_ldap):
|
||
""" Desconectar del servidor ldap
|
||
"""
|
||
conexion_ldap.unbind_s()
|
||
|
||
def buscar_en_ldap(conexion_ldap, filtro, atributos, baseDN = "ou=People,dc=instituto,dc=extremadura,dc=es", alcance = ldap.SCOPE_SUBTREE):
|
||
## Realiza una consulta al servidor ldap, utilizando un filtro y delvolviendo unos atributos, la salida es una lista de tuplas
|
||
try:
|
||
return conexion_ldap.search_s(baseDN, alcance, filtro, atributos)
|
||
except:
|
||
pass
|
||
else:
|
||
return []
|
||
|
||
def existeArchivoImagen(archivo):
|
||
""" Funcion que determina si existe un archivo
|
||
"""
|
||
return os.path.exists(archivo)
|
||
|
||
def main():
|
||
params = {}
|
||
lista = sys.argv
|
||
lee_parametros(lista,params)
|
||
#comprobaremos las combinaciones de parametros en linea de comandos
|
||
if not params.has_key("contra"):
|
||
print 'uso: ./actualizafotosldap.py --contra contraseña_ldap [--depurastudents {on,off}] [--urildap ldaps://servidor_ldap:puerto] [--ruta rutaalarchivozipderayuela]'
|
||
sys.exit(1)
|
||
if not params.has_key("urildap"):
|
||
print "No se ha establecido el servidor ldap, usando por defecto 'ldaps://ldap:636'"
|
||
params["urildap"] = "ldaps://ldap:636"
|
||
if not params.has_key("ruta"):
|
||
print "No se ha establecido la ruta del archivo, usando por defecto './ExportacionDatosAlumnado.zip'"
|
||
params["ruta"] = "./ExportacionDatosAlumnado.zip"
|
||
if not params.has_key("depurastudents"):
|
||
print "No se ha establecido depurastudents, no se eliminarán alumnos del grupo students que no existan en la rama People"
|
||
params["depurastudents"] = "off"
|
||
|
||
#Emite mensajes
|
||
print "Los valores pasado son los siguientes:"
|
||
print "URI Servidor ldap: ",params["urildap"]
|
||
print "Ruta al archivo: ",params["ruta"]
|
||
print "Eliminar alumn@s del grupo students no existentes en People:",params["depurastudents"]
|
||
print "Si estás conforme, pulsa intro, sino pulsa CTRL+C y aborta la ejecución"
|
||
raw_input()
|
||
#Comprobemos la existencia del archivo
|
||
if not os.path.exists(params["ruta"]):
|
||
print params['ruta']," no existe"
|
||
exit(2)
|
||
print "Intentando la conexión al URI de ldap '"+params["urildap"]+"'"
|
||
|
||
conexion_ldap = conecta_a_ldap(params["urildap"],params["contra"])
|
||
|
||
if conexion_ldap == None:
|
||
print "Error en la conexión al servidor ldap:",params["urildap"],"revise nombre servidor y/o contraseña"
|
||
exit(3)
|
||
|
||
#busqueda de los alumnos(pertenecen al grupo students
|
||
resultado_busqueda_alumnos = buscar_en_ldap(conexion_ldap, 'member=*', ['member','memberUid'],baseDN="cn=students,ou=Group,dc=instituto,dc=extremadura,dc=es")
|
||
|
||
if resultado_busqueda_alumnos is None:
|
||
print "No existen alumnos que pertenezcan al grupo students..."
|
||
exit(4)
|
||
|
||
print "Descomprimiendo ZIP de alumnos de rayuela en la carpeta actual..."
|
||
descomprime_zip_en_directorio(params["ruta"], "temp")
|
||
|
||
|
||
alumnos = resultado_busqueda_alumnos[0][1]["memberUid"]
|
||
encontrados = 0
|
||
alumnos_a_borrar_grupo_students = []
|
||
print "Total de alumnos encontrados",len(alumnos)
|
||
print "Procesando alumnos..."
|
||
separador = os.sep
|
||
tipos_imagen = ['.jpg', '.png', '.jpeg' , '.bmp', '.tiff','.jpg']
|
||
alumnos_sin_foto = []
|
||
for alumno in alumnos:
|
||
datos_alumno = buscar_en_ldap(conexion_ldap, 'uid='+alumno, ['cn','uid','employeeNumber'])
|
||
if len(datos_alumno) == 0:
|
||
alumnos_a_borrar_grupo_students.append(alumno)
|
||
else:
|
||
encontrados += 1
|
||
try:
|
||
if not datos_alumno[0][1].has_key('employeeNumber'):
|
||
print "El alumno",alumno,"no tiene atributo 'employeeNumber'... saltando"
|
||
continue
|
||
if not datos_alumno[0][1].has_key('uid'):
|
||
print "El alumno",alumno,"no tiene atributo 'uid'... saltando"
|
||
continue
|
||
|
||
nie = datos_alumno[0][1]['employeeNumber'][0]
|
||
print "Actualizando foto del alumno",datos_alumno[0][1]['cn'][0],'Nie:',nie
|
||
archivo_imagen_sin_tipo = '.'+separador+'temp'+separador+nie
|
||
encontrada_foto = False
|
||
for patron in tipos_imagen:
|
||
archivo_imagen = archivo_imagen_sin_tipo+patron
|
||
if existeArchivoImagen(archivo_imagen):
|
||
print "encontrado archivo de imagen",archivo_imagen
|
||
encontrada_foto = True
|
||
break
|
||
if not encontrada_foto:
|
||
alumnos_sin_foto.append(datos_alumno[0][1]['cn'][0]+' Nie:'+nie)
|
||
print "alumno sin archivo de imagen"
|
||
continue
|
||
|
||
foto = Image.open(archivo_imagen)
|
||
if (not foto.format == 'JPEG'):
|
||
foto.save('foto', 'JPEG')
|
||
foto = Image.open('foto')
|
||
foto.thumbnail((80, 100), Image.ANTIALIAS)
|
||
foto.save('foto', 'JPEG')
|
||
uid = datos_alumno[0][1]['uid'][0]
|
||
dn='uid='+uid+',ou=People,dc=instituto,dc=extremadura,dc=es'
|
||
atributos = [ (ldap.MOD_DELETE,'jpegPhoto',None) ]
|
||
conexion_ldap.modify_s(dn,atributos)
|
||
atributos = [ (ldap.MOD_ADD,'jpegPhoto',open('foto',"rb").read()) ]
|
||
conexion_ldap.modify_s(dn,atributos)
|
||
except ldap.LDAPError,e:
|
||
pass
|
||
#puede pasar que no exista el nie o bien no tenga atributo, pero
|
||
#la acción es ignorar los errores...
|
||
|
||
os.remove('foto')
|
||
|
||
print "Se han procesado",encontrados,"alumn@s..."
|
||
print ""
|
||
print ""
|
||
print "No se han encontrado las fotos de estos",len(alumnos_sin_foto),"alumn@s"
|
||
print "Estos son los alumno@s sin foto:"
|
||
for asinfoto in alumnos_sin_foto:
|
||
print asinfoto
|
||
|
||
print ""
|
||
print ""
|
||
print "No se han encontrado en la rama People",len(alumnos)-encontrados,"alumn@s"
|
||
if params["depurastudents"] == "on" and len(alumnos) > encontrados:
|
||
print ""
|
||
print ""
|
||
print "Procediendo al borrado de alumnos del grupo students no existentes en la rama People"
|
||
resultado_busqueda_alumnos_modificado = copy.deepcopy(resultado_busqueda_alumnos)
|
||
for aborrar in alumnos_a_borrar_grupo_students:
|
||
print "Borrando membresía de students para el alumno no existente ...",aborrar
|
||
#Eliminamos de la lista de memberUid ese alumno
|
||
resultado_busqueda_alumnos_modificado[0][1]['memberUid'].remove(aborrar)
|
||
#Eliminamos de la lista de member ese alumno
|
||
resultado_busqueda_alumnos_modificado[0][1]['member'].remove('uid='+aborrar+',ou=People,dc=instituto,dc=extremadura,dc=es')
|
||
|
||
print "Ejecutando modificación en el árbol ldap..."
|
||
dn = 'cn=students,ou=Group,dc=instituto,dc=extremadura,dc=es'
|
||
ldif = modlist.modifyModlist(resultado_busqueda_alumnos[0][1],resultado_busqueda_alumnos_modificado[0][1])
|
||
conexion_ldap.modify_s(dn,ldif)
|
||
|
||
print ""
|
||
print ""
|
||
print "Eliminando carpeta temporal..."
|
||
shutil.rmtree("temp")
|
||
print "Desconectando del servidor ldap '"+params["urildap"]+"'"
|
||
desconecta_de_ldap(conexion_ldap)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|
||
Exportar a: Unified diff
Importacion inicial