Proyecto

General

Perfil

« Anterior | Siguiente » 

Revisión 47

Añadido por Francisco Mora hace más de 14 años

Importacion inicial

Ver diferencias:

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