#!/usr/bin/env python #-*- coding: iso8859-15 -*- ########################################################## # PESYR_FTP v1.0 # ########################################################## # Autor: Juan Miguel Taboada Godoy # # Fecha: Szczecin, 19 de Julio de 2006 # # Descripción: Adquisitor de datos de Telemandos PESRs # # mediante el sistema de consultas por FTP # # Versión: 2006071900 # # # # Codigo fuente bajo licencia GNU/GPL # # Centrologic (Computational Logistic Center) # # http://www.centrologic.com - info@centrologic.com # ########################################################## # Librerías que voy a usar {{{1 import time import datetime import commands import os import shutil import gzip from lib.MATH_GRA import digitos from lib.FTP import FTP from lib.DATE import tempo_limit from lib.HERENCIA import BASE,DEFAULTCONFIG # }}}1 # Funciones generales {{{1 # Función de control de bloqueo: bloquear {{{2 def bloquear(ftp,locker): # Anulamos el funcionamiento del bloqueador return # Creo el candado de bloqueo try: comando="echo \"Candado de bloqueo de recolector\" > %s" % locker commands.getoutput(comando) except Exception: raise LockError,"No puedo crear el fichero bloqueo local para enviarlo al INFOCEL" # Subo el candado de bloqueo ok=False cuenta=3 # Intentamos 3 veces antes de decidir que no es posible transferir while ((not ok) and cuenta): try: ftp.PUT(locker) ok=True except Exception,e: if (cuenta>0): cuenta=cuenta-1 else: raise LockError,"No se ha podido subir el fichero de bloqueo al INFOCEL: %s" % (e) # Borro el candado de bloqueo local sin importar si falla try: os.remove(locker) except Exception: pass # }}}2 # Función de control de bloqueo: desbloquear {{{2 def desbloquear(ftp,locker): # Anulamos el funcionamiento del desbloqueador return # Elimino el candado de bloqueo del servidor ok=False cuenta=3 # Intentamos 3 veces antes de decidir que no es posible transferir while ((not ok) and cuenta): try: salida=ftp.REMOVE(locker) ok=True except Exception,e: if (cuenta>3): cuenta=cuenta-1 else: raise LockError,"No he podido eliminar el fichero de bloqueo del INFOCEL: %s" % (e) # Devuelvo el resultado return salida # }}}2 # Función de control de bloqueo: bloqueado {{{2 def bloqueado(ftp,locker): # Anulamos el funcionamiento del desbloqueador return False # Compruebo si el candado de bloqueo está en el servidor ok=False cuenta=3 # Intentamos 3 veces antes de decidir que no es posible transferir while ((not ok) and cuenta): try: salida=ftp.EXISTF(locker) ok=True except Exception,e: if (cuenta>3): cuenta=cuenta-1 else: raise LockError,"No he podido comprobar si el INFOCEL tiene fichero de bloqueo o no: %s" % (e) # Devuelvo el resultado return salida # }}}2 # Función que lee el valor de una línea de la cabecera del registro {{{2 def getf_valor(control,linea): # Estado estado=1 # Recorro los caracteres de la línea variable="" valor="" for caracter in linea: # Añadido el '\r' para compatibilidad con ficheros de Windows if (caracter!='\n') and (caracter!='\r'): if (estado==1): # Recojo el nombre de la variable if (caracter=='='): # Cambio de estado estado=2 else: # Recogo el nombre variable=variable+caracter else: # Recojo el valor de la variable valor=valor+caracter # Compruebo variable con control if (variable==control): # Todo ha ido bien return valor else: # Hubo un error raise IOError,"Variable '%s' en cabecera no coincide con esperada '%s'" % (variable,control) # }}}2 # }}}1 # ### CONFIG ### ###################################### ## Acceso a Telemando mediante PESYR: configuracion por defecto class CONFIG(DEFAULTCONFIG): # Constructor {{{1 def __init__(self): # Cargo las acciones del padre DEFAULTCONFIG.__init__(self,"PESYR_FTP") # }}}1 # Config Telemando {{{1 # download_descarga {{{2 ## Actualizar cada n-segundos ## \param self - ## \param arg Segundos entre acutalizaciones def download_tempo(self,arg=None): if (arg!=None): self._download_tempo=arg return self._download_tempo # }}}2 # bloqueo {{{2 ## Fichero que controla el candado de bloqueo ## \param self - ## \param arg Nombre del fichero def bloqueo(self,arg=None): if (arg!=None): self._bloqueo=arg return self._bloqueo # }}}2 # borrado {{{2 ## Umbral en kilobytes para borrar los registros del Telemando ## \param self - ## \param arg Kilobytes def borrado(self,arg=None): if (arg!=None): self._borrado=arg return self._borrado # }}}2 # }}}1 # Config Servidor SMS {{{1 # smsserver {{{2 ## Servidor SMS ## \param self - ## \param arg Direccion IP o host del sevidor SMS def smsserver(self,arg=None): if (arg!=None): self._smsserver=arg return self._smsserver; # }}}2 # smsport {{{2 ## Puerto del servidor SMS ## \param self - ## \param arg Puerto del sevidor SMS def smsport(self,arg=None): if (arg!=None): self._smsport=arg return self._smsport; # }}}2 # }}}2 # smsuser {{{2 ## Usuario de acceso al servidor SMS ## \param self - ## \param arg Usuario de acceso def smsuser(self,arg=None): if (arg!=None): self._smsuser=arg return self._smsuser; # }}}2 # }}}2 # smspasswd {{{2 ## Clave del usuario para el acceso al servidor SMS ## \param self - ## \param arg Clave de acceso def smspasswd(self,arg=None): if (arg!=None): self._smspasswd=arg return self._smspasswd; # }}}2 # }}}1 # Config Servidor REGISTROS {{{1 # regserver {{{2 ## Servidor REG ## \param self - ## \param arg Direccion IP o host del sevidor REG def regserver(self,arg=None): if (arg!=None): self._regserver=arg return self._regserver; # }}}2 # regport {{{2 ## Puerto del servidor REG ## \param self - ## \param arg Puerto del sevidor REG def regport(self,arg=None): if (arg!=None): self._regport=arg return self._regport; # }}}2 # reguser {{{2 ## Usuario de acceso al servidor REG ## \param self - ## \param arg Usuario de acceso def reguser(self,arg=None): if (arg!=None): self._reguser=arg return self._reguser; # }}}2 # regpasswd {{{2 ## Clave del usuario para el acceso al servidor REG ## \param self - ## \param arg Clave de acceso def regpasswd(self,arg=None): if (arg!=None): self._regpasswd=arg return self._regpasswd; # }}}2 # }}}1 # Config Directorios {{{1 # sms_temp {{{2 ## Nombre del fichero temporal para la creacion del mensaje SMS a enviar ## \param self - ## \param arg Nombre del fichero temporal def sms_temp(self,arg=None): if (arg!=None): self._sms_temp=arg return self._sms_temp; # }}}2 # sms_remoto {{{2 ## Cabecera para el nombre del fichero SMS en el servidor remoto ## \param self - ## \param arg Texto de cabecera def sms_remoto(self,arg=None): if (arg!=None): self._sms_remoto=arg return self._sms_remoto; # }}}2 # dirtemp {{{2 ## Directorio donde almacenar temporalmente los registros descargados ## \param self - ## \param arg Directorio local def dirtemp(self,arg=None): if (arg!=None): self._dirtemp=arg return self._dirtemp; # }}}2 # sms_send {{{2 ## Directorio donde colocar el mensaje SMS ## \param self - ## \param arg Directorio remoto def sms_send(self,arg=None): if (arg!=None): self._sms_send=arg return self._sms_send; # }}}2 # sms_bien {{{2 ## Directorio donde comprobar si el mensaje SMS se ha enviado correctamente ## \param self - ## \param arg Directorio remoto def sms_bien(self,arg=None): if (arg!=None): self._sms_bien=arg return self._sms_bien; # }}}2 # sms_mal {{{2 ## Directorio donde comprobar si el mensaje SMS no se ha enviado debido a errores ## \param self - ## \param arg Directorio remoto def sms_mal(self,arg=None): if (arg!=None): self._sms_mal=arg return self._sms_mal; # }}}2 # reg_lock {{{2 ## Nombre del fichero de bloqueo en el servidor REG ## \param self - ## \param arg Nombre del fichero remoto def reg_lock(self,arg=None): if (arg!=None): self._reg_lock=arg return self._reg_lock; # }}}2 # reg_recv {{{2 ## Directorio donde se espera recibir el registro ## \param self - ## \param arg Directorio remoto def reg_recv(self,arg=None): if (arg!=None): self._reg_recv=arg return self._reg_recv; # }}}2 # reg_save {{{2 ## Directorio donde se guardara la copia del registro ## \param self - ## \param arg Directorio remoto def reg_save(self,arg=None): if (arg!=None): self._reg_save=arg return self._reg_save; # }}}2 # }}}1 # Ciclos de espera {{{1 # espera_sms_recogido {{{2 ## Ciclos de espera para que un mensaje SMS sea recogido ## \param self - ## \param arg Ciclos de 10 segundos def espera_sms_recogido(self,arg=None): if (arg!=None): self._espera_sms_recogido=arg return self._espera_sms_recogido; # }}}2 # espera_sms_procesado {{{2 ## Ciclos de espera para que un mensaje SMS sea procesado ## \param self - ## \param arg Ciclos de 10 segundos def espera_sms_procesado(self,arg=None): if (arg!=None): self._espera_sms_procesado=arg return self._espera_sms_procesado; # }}}2 # espera_reg_referencia {{{2 ## Ciclos de espera para que se atienda la llamada del Telemando ## \param self - ## \param arg Ciclos de 10 segundos def espera_reg_referencia (self,arg=None): if (arg!=None): self._espera_reg_referencia=arg return self._espera_reg_referencia; # }}}2 # espera_reg_registro {{{2 ## Ciclos de espera para que se descargue toda la informacion de un Telemando ## \param self - ## \param arg Ciclos de 10 segundos def espera_reg_registro(self,arg=None): if (arg!=None): self._espera_reg_registro=arg return self._espera_reg_registro; # }}}2 # }}}1 # Checker {{{1 ## Comprueba que el conjunto minimo de datos requeridos por la clase han sido declarados por el usuario: \n ## - download_tempo() ## - debug() ## - smsserver() ## - smsport() ## - smsuser() ## - smspasswd() ## - regserver() ## - regport() ## - reguser() ## - regpasswd() ## - sms_temp() ## - sms_remoto() ## - dirtemp() ## - sms_send() ## - sms_bien() ## - sms_mal() ## - reg_lock() ## - reg_recv() ## - reg_save() ## - bloqueo() ## - borrado() ## \param self - def check(self): self._check("download_tempo") self._check("debug") self._check("smsserver") self._check("smsport") self._check("smsuser") self._check("smspasswd") self._check("regserver") self._check("regport") self._check("reguser") self._check("regpasswd") self._check("sms_temp") self._check("sms_remoto") self._check("dirtemp") self._check("sms_send") self._check("sms_bien") self._check("sms_mal") self._check("reg_lock") self._check("reg_recv") self._check("reg_save") self._check("bloqueo") self._check("borrado") self.check_default() # }}}1 # ### TELEMANDO ### ################################### ## Acceso a Telemando mediante PESYR: Telemando class TELEMANDO(BASE): # Constructor {{{1 ## Constructor ## \param self - ## \param id Identificador del Telemando (ALFANUMERICO) def __init__(self,id): # Cargo las acciones del padre BASE.__init__(self,id,"PESYR_FTP") # Inicializo el estado interno del Telemando self.__incongruencias=[] # }}}1 # Guarda la config {{{1 ## Guarda la configuracion del Telemando ## \param self - ## \param config Copnfiguración por defecto obtenida de la clase CONFIG ## \param id ID del Telemando fisico ## \param name Nombre del Telemando ## \param phone Telefono ## \param password Clave def config(self,config,id,name,phone,password): # Configuración por defecto self.default_config(config) # Cargo los datos en la config self.id(id) self.name(name) self.phone(phone) self.password(password) # Chequeo la config self.check() # }}}1 # Guarda el ID {{{1 ## Guarda el ID del Telemando Fisico ## \param self - ## \param arg ID del Telemando Fisico def id(self,arg=None): if (arg!=None): self._id=arg return self._id; # }}}1 # Guarda el Nombre {{{1 ## Guarda el nombre ## \param self - ## \param arg Nombre def name(self,arg=None): if (arg!=None): self._name=arg return self._name; # }}}1 # Guarda el Telefono {{{1 ## Numero de telefono ## \param self - ## \param arg Numero de telefono def phone(self,arg=None): if (arg!=None): self._phone=arg return self._phone; # }}}1 # Guarda la clave {{{1 ## Guarda la clave del Telemando ## \param self - ## \param arg Clave del Telemando def password(self,arg=None): if (arg!=None): self._password=arg return self._password; # }}}1 # espera_reg_registro {{{1 ## Ciclos de espera para que se descargue toda la informacion de un Telemando ## \param self - ## \param arg Ciclos de 10 segundos def espera_reg_registro(self,arg=None): if (arg!=None): self._espera_reg_registro=arg return self._espera_reg_registro; # }}}1 # borrado {{{1 ## Umbral en kilobytes para borrar los registros del Telemando ## \param self - ## \param arg Kilobytes def borrado(self,arg=None): if (arg!=None): self._borrado=arg return self._borrado # }}}1 # download_descarga {{{1 ## Actualizar cada n-segundos ## \param self - ## \param arg Segundos entre acutalizaciones def download_tempo(self,arg=None): if (arg!=None): self._download_tempo=arg return self._download_tempo # }}}1 # Checker {{{1 ## Comprueba que el conjunto minimo de datos requeridos por la clase han sido declarados por el usuario: \n ## - ip() ## - name() ## - phone() ## - password() ## \param self - def check(self): self._check("id") self._check("name") self._check("phone") self._check("password") self.check_default() # }}}1 # Función para enviar un SMS (devuelve 1/0 si se ha enviado BIEN/MAL) {{{1 ## Funcion para enviar un SMS ## \param self - ## \param ftp Conexion FTP con el servidor SMS ## \param dir_send Directorio donde colocar el mensaje para ser enviado ## \param dir_bien Directorio de mensajes enviados correctamente ## \param dir_mal Directorio de mensajes enviados incorrectamente ## \param sms Fichero con el mensaje SMS ## \param espera_recogido Ciclos de espera a que el mensaje sea recogido ## \param espera_resultado Ciclos de espera por un resultado ## \param hora Hora a incluir en la cabecera del nombre del fichero SMS ## \param cabecera Texto de cabecera del nombre del fichero SMS en el servidor remoto ## \param cola Texto de cola del nombre del fichero SMS en el servidor remoto (Por defecto no se pone texto) ## \return Devuelve 0 si ha enviado MAL, 1 si ha enviado BIEN def enviar_sms(self,ftp,dir_send,dir_bien,dir_mal,sms,espera_recogido,espera_resultado,hora,cabecera,cola=""): # Me situo en el directorio de mensajes self.debug("SMS: Entrando en directorio destino (CD)") try: ftp.CD(dir_send) except Exception,e: raise IOError,"Error al situarme en el directorio destino del INFOCEL: %s" % (e) # Subo el fichero al servidor self.debug("SMS: Subienfo fichero con mensaje (PUT)") try: ftp.PUT(sms) except Exception,e: raise IOError,"Error en el envío del fichero de ordenes al INFOCEL: %s" % (e) # Renombro el fichero al nombre que le toca self.debug("SMS: Renombrando fichero de ordenes en el destino (RENAME)") old_sms=sms sms="%s%d%s.txt" % (cabecera,hora,cola) try: ftp.RENAME(old_sms,sms) except Exception,e: raise IOError,"Error al renombrar el fichero de ordenes en el INFOCEL al nombre que le corresponde: %s" % (e) # Espero a que sea recogido por el servidor (que no exista) o bien hasta un máximo de n veces self.debug("SMS: Esperando a que INFOCEL recoja el fichero de ordenes (EXISTF) [%s]" % (espera_recogido*10)) recogido=False veces=0 while (not recogido) and (veces<=espera_recogido): # Recojo si el fichero está en el servidor try: recogido=not ftp.EXISTF(sms) except Exception,e: raise IOError,"Error al comprobar si el fichero de ordenes ha sido recogido o no por el INFOCEL: %s" % (e) # Si el mensaje no ha sido recogido if (not recogido): # Duerme 10 segundos time.sleep(10) # Incremento las veces veces=veces+1 # Si salimos del bucle por error (indico que hubo un error) if (not recogido): self.debug("SMS: El fichero de ordenes no ha sido recogido por el INFOCEL") # Elimino el mensaje del servidor m="El fichero de ordenes no ha sido recogido por el INFOCEL" try: ftp.REMOVE(sms) except Exception: m="%s\n%s" % (m,"No se pudo eliminar el fichero de ordenes del INFOCEL") # Genero una excepción con el error raise MotorError,m # Hasta encontrar el resultado o durante un máximo de n veces self.debug("SMS: Esperando el procesado del fichero de ordenes en el INFOCEL (EXISTF) [%s]" % (espera_resultado*10)) resultado=0 veces=0 while (not resultado) and (veces<=espera_resultado): # Consulto el directorio BIEN a ver si está ahí el mensaje try: ftp.CD(dir_bien) resultado=ftp.EXISTF(sms) except Exception,e: raise IOError,"Error al comprobar en el directorio %s: %s" % (dir_bien,e) # Si el mensaje está en el directorio BIEN (devuelvo mensaje enviado) if (resultado): self.debug("SMS: Fichero de ordenes procesado correctamente (BIEN)") return 1 # Consulto el directorio MAL a ver si está ahí el mensaje try: ftp.CD(dir_mal) resultado=ftp.EXISTF(sms) except Exception,e: raise IOError,"Error al comprobar en el directorio %s: %s" % (dir_mal,e) # Si el mensaje está en el directorio MAL (devuelvo mensaje no enviado) if (resultado): self.debug("SMS: Fichero de ordenes no procesado por INFOCEL (MAL)") return 0 # Duerme 10 segundos time.sleep(10) # Incremento el número de veces veces=veces+1 # No se ha comprobado que se haya enviado el mensaje (ERROR) self.debug("SMS: El INFOCEL no ha generado ningun registro sobre el procesado del fichero de ordenes") raise SMSError,"El INFOCEL no ha generado ningun registro sobre el procesado del fichero de ordenes" # }}}1 # Función para recolectar un registro (devuelve 1/0 si se ha recolectado BIEN/MAL) {{{1 ## Funcion para recolectar un registro ## \param self - ## \param ftp Conexion con el servidor FTP REG ## \param reg_recv Directorio remoto donde buscar el registro y sus temporales ## \param reg_save Directorio remoto donde poner los registros guardados ## \param registro Nombre original del fichero de registros ## \param espera_referencia Tiempo de espera a que se comience la descarga del registro ## \param espera_registro Tiempo de espera a que el registro sea descargado completamente ## \param hora Hora a incluir en el nombre del registro ## \return 0 si se ha recolectado MAL, 1 si se ha recolectado BIEN def recolectar_registro(self,ftp,reg_recv,reg_save,registro,espera_referencia,espera_registro,hora): # Me muevo al directorio de recepción de registros self.debug("REG: Entrando al directorio de recepcion de registros (CD)") ftp.CD(reg_recv) # Compruebo que existe la referencia al registro o bien hasta un máximo de n intentos self.debug("REG: Esperando la referencia de registro (EXISTF) [%s]" % (espera_referencia*10)) existe=False veces=0 while ((not existe) and (veces<=espera_referencia)): # Comprueba si existe la referencia existe=ftp.EXISTF(registro) # Si no existe, sigo esperando if (not existe): # Duerme diez segundos time.sleep(10) # Incremento el número de veces veces=veces+1 # Si la referencia no existe, salgo con error if (not existe): # Genero el nombre de fichero para deteccion de perdida de identidad. Simulo la perdida de identidad yy*xxxx (* se pone a 0) referencia_nueva_identidad="%s0%s" % (registro[:2],registro[3:]) registro_nueva_identidad="%s.txt" % (referencia_nueva_identidad) # Compruebo si el Telemando ha perdido su identidad if ((ftp.EXISTF(referencia_nueva_identidad)) or (ftp.EXISTF(registro_nueva_identidad))): self.debug("REG: Se ha detectado que el Telemando ha perdido su identidad. Deberia llamarse %s pero se llama %s" % (registro,referencia_nueva_identidad)) raise MotorError,"El Telemando %s no respondio a la llamada (ERROR: se ha confirmada la perdida de identidad del Telemando, proceda a reparacion manual).\nMensaje a enviar \"sms_repair%s.txt\":\nmedio=SMS\ndestino=#%s\nmensaje=#PIN1234#ESCMEM=2,1:4*#PEDINF\n" % (registro,int(time.time()),self.valor("phone")) # self.debug("REG: La referencia de registro no ha sido creada aun, interpretamos que el Telemando no respondio a la peticion de datos") raise MotorError,"El Telemando %s no respondio a la peticion de datos (ERROR: Timeout referencia de registro)" % (registro) # Mensaje de que la referencia se ha leido # Espero a que exista el registros hasta un máximo de 100 intentos self.debug("REG: Esperando al registro (EXISTF) [%s]" % (espera_registro*10)) existe=0 veces=0 while (not existe) and (veces<=espera_registro): # Comprueba si existe el registro existe=ftp.EXISTF("%s.txt" % registro) # Si no existe, sigo esperando if (not existe): # Duerme 10 segundos time.sleep(10) # Cuanto una vez más veces=veces+1 # Si el registro no existe, salgo con error if (not existe): self.debug("REG: El registro no ha sido creado aun, interpretamos que hubo un error de INFOCEL durante el proceso") raise MotorError,"Timeout alcanzado: Referencia del registro no detectada" # Duerme 10 segundos como educación al programa remoto self.debug("REG: Esperando segun protocolo de educacion con INFOCEL [10]") time.sleep(10) # Descargo el registro self.debug("REG: Descargando el registro (GET)") ftp.GET("%s.txt" % registro,40*espera_registro) # Recuerdo el tamano del fichero descargado (antes de comprimir) tamano_registro=os.path.getsize("%s.txt" % (registro)) # Comprimo el fichero recibido FILEGZ=gzip.open("%s.txt.gz" % (registro),"w") FILEGZ.write(open("%s.txt" % (registro),"r").read()) FILEGZ.close() # Elimino el registro no comprimido os.unlink("%s.txt" % (registro)) # Borro los registros del servidor self.debug("REG: Eliminando la referencia de registro del INFOCEL (REMOVE)") ftp.REMOVE(registro) self.debug("REG: Eliminando el registro del INFOCEL (REMOVE)") ftp.REMOVE("%s.txt" % registro) # Creo un nuevo nombre para el regisro (para ser guardados) nuevo_registro="%d_%s" % (hora,registro) # Subo los registros a la carpeta de guardados self.debug("REG: Obteniendo directorio actual (PWD)") actual=ftp.PWD() self.debug("REG: Entrado al directorio de backups (CD)") ftp.CD(reg_save) self.debug("REG: Subiendo fichero de registros (PUT)") ftp.PUT("%s.txt.gz" % registro,40*espera_registro) self.debug("REG: Renombrando el fichero de registros (RENAME)") ftp.RENAME("%s.txt.gz" % registro,"%s.pesyr.dat.gz" % nuevo_registro) self.debug("REG: Volviendo al directorio original (CD)") ftp.CD(actual) # Devuelvo el tamano del registro descargado return tamano_registro # }}}1 # Descarga los datos del Telemando {{{1 ## \internal ## Descarga los datos del Telemando ## \param self - ## \param unlock Indica si se puede desbloquear el servidor o no (True/False) def download_extendido(self,unlock): # Creo el nombre del fichero origen {{{2 origen="%s.txt" % (self.valor("id")) # }}}2 # Creo el nombre del fichero destino {{{2 date=datetime.datetime.fromtimestamp(time.time()) fecha=date.timetuple() destino="%s_%s.pesyr" % (self.internal_id(),tempo_limit(fecha,self.valor("download_tempo"))) # }}}2 self.debug("Inicia la descarga de datos [%s,%s]" % (origen,destino)) # Cambio al directorio destino {{{2 self.debug("Cambia al directorio %s" % (self.valor("dirtemp"))) pwd=os.getcwd() try: os.chdir(self.valor("dirtemp")) except Exception: # Genero un error porque no puedo cambiarme al directorio destino raise IOError,"Error al cambiar al directorio \"%s\"" % (self.valor("dirtemp")) # Habilito una incongruencia self.habilitar(("sincronizar1",pwd)) # }}}2 # Descarga de los registros del Telemando físico {{{2 # Revisa si el registro existe {{{3 self.debug("Comprobando existencia previa del registro") file_exists=((os.path.exists("bak/%s.dat" % (destino))) or (os.path.exists("bak/%s.dat.gz" % (destino)))) # }}}3 # Test de existencia: Si no dispone del registo se lo baja if (not (file_exists)): # Conecto al FTP {{{3 self.debug("REG: Conectando al FTP") try: reg=FTP(self.valor("regserver"),self.valor("regport"),self.valor("reguser"),self.valor("regpasswd")) except Exception,e: # Genero un error raise ConnectionError,"No se pudo conectar al directorio de REGISTROS de INFOCEL: %s" % e # }}}3 # Compruebo el candado de bloqueo {{{3 if bloqueado(reg,self.valor("reg_lock")): self.debug("REG: INFOCEL esta bloqueado con un candado de bloqueo de Grafista") if (unlock): try: self.debug("REG: Desbloqueando servidor (Restriccion permitida en tiempo de ejecuccion)") desbloquear(reg,self.valor("reg_lock")) except Exception: m="INFOCEL bloqueado con un fichero de bloqueo de Grafista. El programa da permiso para desbloquear al servidor: se intentó desbloquear sin éxito." try: self.debug("REG: Desconectando de INFOCEL") reg.DISCONNECT() except Exception: m="%s\n%s" % (m,"Error al desconectar de INFOCEL/REGISTROS") # Genero un error raise LockError,m else: # Desconecto del servidor FTP sin importar si falla o no m="INFOCEL bloqueado con un fichero de bloqueo de Grafista" try: self.debug("REG: Desconectando de INFOCEL") reg.DISCONNECT() except Exception: m="%s\n%s" % (m,"Error al desconectar de INFOCEL/REGISTROS") # Genero un error raise LockError,m else: # }}}3 # Activo el candado de bloqueo {{{3 self.debug("REG: Bloqueando servidor") bloquear(reg,self.valor("reg_lock")) # }}}3 # Conecto al servidor FTP de SMSs {{{3 try: self.debug("SMS: Conectando al FTP") sms=FTP(self.valor("smsserver"),self.valor("smsport"),self.valor("smsuser"),self.valor("smspasswd")) except Exception,e: # Desconecto del servidor FTP sin importar si falla m="No se pudo conectar al directorio de MENSAJES de INFOCEL: %s" % (e) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando de INFOCEL") reg.DISCONNECT() except Exception: m="%s\n%s" % (m,"Error al desconectar de INFOCEL/REGISTROS") # Genero un error raise ConnectionError,"No se pudo conectar al directorio de MENSAJES de INFOCEL: %s" % e # }}}3 # Obtengo la hora actual {{{3 hora=time.time() # }}}3 # Elimino posibles registros antiguos del servidor (de intentos fallidos) {{{3 try: self.debug("REG: Eliminando referencia de registro antigua") reg.REMOVE(self.valor("id")) # REFERENCIA DE REGISTRO except Exception,e: pass try: self.debug("REG: Eliminando registro antiguo") reg.REMOVE("%s.txt" % (self.valor("id"))) # REGISTRO except Exception,e: pass # }}}3 # Creo el mensaje SMS localmente {{{3 # Recojo los datos de fecha y hora (sincronizo a un mintuso más tarde para evitar los retrasos de envío del SMS) timetmp=datetime.datetime.fromtimestamp(hora+60).timetuple() # (anyoP,mesP,diaP,horaP,minutosP,segundosP,semanaP,temp1,temp2)=timetmp anyoP=timetmp[0] mesP=timetmp[1] diaP=timetmp[2] horaP=timetmp[3] minutosP=timetmp[4] semanaP=timetmp[6] # Reduzco a dos digitos el tamaño del año anyoP=str(anyoP)[2:] # Confirmo los digitos de todos los numeros mesP=digitos(mesP,2) diaP=digitos(diaP,2) horaP=digitos(horaP,2) minutosP=digitos(minutosP,2) # Genero el día de la semana if (semanaP==0): semanaP='L' elif (semanaP==1): semanaP='M' elif (semanaP==2): semanaP='X' elif (semanaP==3): semanaP='J' elif (semanaP==4): semanaP='V' elif (semanaP==5): semanaP='S' elif (semanaP==6): semanaP='D' else: raise IOError,"ERROR de programacion: El dia de la semana obtenido no es reconocido por el sistema." # Genero la fecha y hora en formato PESYR fechaPESYR="%s/%s-%s%s" % (diaP,mesP,semanaP,anyoP) horaPESYR="%s:%s" % (horaP,minutosP) # Creo el mensaje try: self.debug("Creando fichero de ordenes") smstempfile=open(self.valor("sms_temp"),"w") smstempfile.write("medio=SMS\ndestino=#%s\nmensaje=#PIN%s #DIA=%s- #HORA=%s- #LEEREG" % (self.valor("phone"),self.valor("password"),fechaPESYR,horaPESYR)) smstempfile.close() except Exception,e: # Desbloqueo el servidor sin importar que falle m="No se pudo crear el fichero de ordenes temporal para enviarlo al INFOCEL: %s" % e try: self.debug("SMS: Desconectando de INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando de INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar de INFOCEL/REGISTROS: %s" % (e)) # Devuelvo un error raise IOError,m # }}}3 # Envío el mensaje SMS al servidor {{{3 self.debug("Enviando fichero de ordenes") try: enviado=self.enviar_sms(sms,self.valor("sms_send"),self.valor("sms_bien"),self.valor("sms_mal"),self.valor("sms_temp"),self.valor("espera_sms_recogido"),self.valor("espera_sms_procesado"),hora,self.valor("sms_remoto")) except IOError,e: # Desbloqueo el servidor {{{4 m="Fichero de ordenes no enviado por error durante el proceso de envio al INFOCEL: %s" % e try: self.debug("SMS: Desconectando de INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Elimino ficheros temporales {{{4 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}4 # Devuelvo un error raise IOError,m except MotorError,e: # Desbloqueo el servidor {{{4 m="Fichero de ordenes no enviado por error durante el proceso de envio: %s" % e try: self.debug("SMS: Desconectando de INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar de INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando de INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar de INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Elimino ficheros temporales {{{4 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}4 # Devuelvo un error raise MotorError,m except SMSError,e: # Desbloqueo el servidor {{{4 m="Fichero de ordenes no enviado por error durante el proceso de envio al INFOCEL: %s" % e try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Elimino ficheros temporales {{{4 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}4 # Devuelvo un error raise SMSError,m # }}}3 # Elimino el mensaje SMS local sin importar si falla {{{3 try: self.debug("Eliminando fichero de ordenes local") os.remove(self.valor("sms_temp")) except Exception: pass # }}}3 # Compruebo resultado del envío {{{3 self.debug("Comprobando resutados del procesado del fichero de ordenes") if enviado==0: # Desbloqueo el servidor {{{4 m="Fichero de ordenes no enviado por fallo en el SERVICIO de SMSs" try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Devuelvo un error raise SMSError,m elif enviado==-1: # Desbloqueo el servidor {{{4 m="Fichero de ordenes no enviado por fallo en INFOCEL" try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Devuelvo un error raise MotorError,m # }}}3 # Desconecto del servidor de SMSs sin importar que falle {{{3 try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: self.debug("Ocultado error en Telemando %s al desconectar del INFOCEL/MENSAJES: %s" % (self.internal_id(),e)) # }}}3 # Recolecto el registro del servidor {{{3 self.debug("Recolectando el registro del INFOCEL") try: tamano_registro=self.recolectar_registro(reg,self.valor("reg_recv"),self.valor("reg_save"),self.valor("id"),self.valor("espera_reg_referencia"),self.valor("espera_reg_registro"),hora) except Exception,e: # Desbloqueo el servidor {{{4 m="Registro no recolectado por error en el proceso: %s" % e try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: m="%s\n%s" % (m,"No he podido desbloquear el INFOCEL: %s" % (e)) try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/REGISTROS: %s" % (e)) # }}}4 # Devuelvo un error de comunicaciones raise ConnectionError,m # }}}3 # Desactivo el candado de bloqueo {{{3 try: self.debug("REG: Desbloqueando INFOCEL") desbloquear(reg,self.valor("reg_lock")) except Exception,e: self.debug("Ocultado error en Telemando %s al desbloquear el INFOCEL: %s" % (self.internal_id(),e)) # }}}3 # Desconecto del servidor FTP sin importar lo que pase {{{3 try: self.debug("REG: Desconectando del INFOCEL") reg.DISCONNECT() except Exception,e: self.debug("Ocultado error en Telemando %s al desconectar del INFOCEL/REGISTROS: %s" % (self.internal_id(),e)) # }}}3 # Procesa los datos descargados {{{2 self.debug("Procesando los datos descargados") # Abro el fichero del registro {{{3 self.debug("Abriendo el fichero del registro") try: FILE = gzip.open("%s.gz" % (origen), 'r') except IOError,e: raise IOError,"No se puede abrir el fichero de registros \"%s\": %s" % (origen,e) # }}}3 # Leo la cabecera del fichero {{{3 self.debug("Leyendo cabecera del fichero de registros") try: # Leo el inicio de la cabecera FILE.readline() # Leo el medio # medio= getf_valor("medio",FILE.readline()) # Leo el telefono # telefono= getf_valor("telefono",FILE.readline()) # Leo el producto producto=getf_valor("producto",FILE.readline()) # Leo el montaje # montaje= getf_valor("montaje",FILE.readline()) # Leo el número de serie serie=getf_valor("serie",FILE.readline()) # Leo la version # version= getf_valor("versión",FILE.readline()) # Leo el servicio # servicio= getf_valor("servicio",FILE.readline()) # Leo el inicio de los registros FILE.readline() except Exception,e: raise IOError,"Error al leer la cabecera del registro recogido: %s" % (e) #}}}3 # Compruebo que el fichero cumple los patrones de similitud con la llamada {{{3 self.debug("Comprobando patrones de similitud con la llamada") similitud="%s%s" % (producto,serie) if (self.valor("id")!=similitud): raise TerminalError,"INFOCEL ha entregado un fichero que no cumple los patrones de similitud con este Telemando, es decir, el fichero generado por INFOCEL contiene información que no es para este Telemando. Esto es un error muy grave de INFOCEL debido a que está entregando ficheros con un nombre cuyo contenido no concuerda con su contenido.\n\nResultado de salida:\nID TELEMANDO: %s%s\nID RECIBIDO: %s%s\n\nContacte con los programadores de ambas aplicaciones inmediatamente.\n" % (self.valor("id"),similitud) # }}}3 # Cierro el fichero de origen sin importar errores {{{3 self.debug("Cerrando el fichero") try: FILE.close() except Exception,e: self.debug("Ocultado error en Telemando %s al cerrar el fichero de registros. Error: %s" % (self.internal_id(),e)) # }}3 # Copio el fichero de registros al directorio de salida {{{3 self.debug("Copiando el fichero de registros al directorio de salida") try: os.rename("%s.gz" % (origen),"%s.dat.gz" % (destino)) shutil.copyfile("%s.dat.gz" % (destino),"dat/%s.dat.gz" % (destino)) shutil.copyfile("%s.dat.gz" % (destino),"bak/%s.dat.gz" % (destino)) os.unlink("%s.dat.gz" % (destino)) except Exception,e: self.debug("Error en Telemando %s al manejar el fichero de registros %s.gz - Error: %s" % (self.valor("id"),origen,e)) # }}}3 # Borro los registros almacenados en el servidor si el fichero descargado supera el tamano de umbral {{{3 if ((self.valor("borrado")!=False) and (tamano_registro>self.valor("borrado"))): self.debug("Solicitando al Telemando que limpie su memoria. Tamano detectado: %s - Tamano maximo: %s" % (tamano_registro,self.valor("borrado"))) # Conecto al servidor FTP de SMSs {{{4 try: self.debug("SMS: Conectando al FTP") sms=FTP(self.valor("smsserver"),self.valor("smsport"),self.valor("smsuser"),self.valor("smspasswd")) except Exception,e: # Genero un error raise ConnectionError,"No se pudo conectar al INFOCEL para limpiar la memoria de mensajes pendientes: %s" % e # }}}4 # Creo el mensaje SMS localmente {{{4 try: self.debug("Creando fichero de ordenes") smstempfile=open(self.valor("sms_temp"),"w") smstempfile.write("medio=SMS\ndestino=#%s\nmensaje=#PIN%s#RESETREG#STARTREG" % (self.valor("phone"),self.valor("password"))) smstempfile.close() except Exception,e: # Cierro la conexion al servidor sin importar que falle m="No se pudo crear el fichero temporal de orden de limpieza para enviarlo al INFOCEL: %s" % e try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) # Devuelvo un error raise IOError,m # }}}4 # Envío el mensaje SMS al servidor {{{4 self.debug("Enviando fichero de orden de limpieza") try: enviado=self.enviar_sms(sms,self.valor("sms_send"),self.valor("sms_bien"),self.valor("sms_mal"),self.valor("sms_temp"),self.valor("espera_sms_recogido"),self.valor("espera_sms_procesado"),hora,self.valor("sms_remoto"),"_clean") except IOError,e: # Cierro la conexion al servidor {{{5 m="Fichero de orden de limpieza no enviado por error durante el proceso: %s" % e try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL: %s" % (e)) # }}}5 # Elimino ficheros temporales {{{5 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}5 # Devuelvo un error raise IOError,m except MotorError,e: # Cierro la conexion al servidor {{{5 m="Fichero de orden de limpieza no enviado por error durante el envio: %s" % e try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) # }}}5 # Elimino ficheros temporales {{{5 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}5 # Devuelvo un error raise MotorError,m except SMSError,e: # Cierro la conexion al servidor {{{5 m="Fichero de orden de limpieza no enviado por error durante el envio: %s" % e try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) # }}}5 # Elimino ficheros temporales {{{5 try: self.debug("Eliminando ficheros temporales") os.remove(self.valor("sms_temp")) except Exception: pass # }}}5 # Devuelvo un error raise SMSError,m # }}}4 # Elimino el mensaje SMS local sin importar si falla {{{4 try: self.debug("Eliminando fichero local de orden de limpieza") os.remove(self.valor("sms_temp")) except Exception: pass # }}}4 # Compruebo resultado del envío {{{4 self.debug("Comprobando resutados del proceso del fichero de orden de limpieza") if enviado==0: # Desconecto del servidor {{{5 m="Fichero de orden de limpieza no enviado por fallo en el SERVICIO de SMSs" try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) # }}}5 # Devuelvo un error raise SMSError,m elif enviado==-1: # Desconecto del servidor {{{5 m="Fichero de orden de limpieza no enviado por fallo del INFOCEL" try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception: m="%s\n%s" % (m,"No he podido desconectar del INFOCEL/MENSAJES: %s" % (e)) # }}}5 # Devuelvo un error raise MotorError,m # }}}4 # Desconecto del servidor de SMSs sin importar que falle {{{4 try: self.debug("SMS: Desconectando del INFOCEL") sms.DISCONNECT() except Exception,e: self.debug("Ocultado error en Telemando %s al desconectar del INFOCEL/MENSAJES: %s" % (self.internal_id(),e)) # }}}4 # }}}3 # }}}2 else: # Muestro el mensaje de cancelacion self.debug("Cancelada descarga, no es necesario sincronizar") # Cambio al directorio origen try: os.chdir(pwd) except Exception,e: # Genero un error porque no puedo cambiarme al directorio destino raise TerminalError,"No se ha podido volver al directorio origen: %s" % (e) # Desabilito la incongruencia self.deshabilitar(("sincronizar1",pwd,self.valor("dirtemp"))) # }}}2 # Vuelvo al directorio origen {{{2 self.debug("Volviendo al directorio %s" % (pwd)) try: os.chdir(pwd) except Exception,e: # Genero un error porque no puedo cambiarme al directorio destino raise TerminalError,"No se ha podido volver al directorio origen: %s" % (e) # Desabilito la incongruencia self.deshabilitar(("sincronizar1",pwd,self.valor("dirtemp"))) # }}}2 # }}}1 # Control de descarga de los Telemandos {{{1 ## Control de descarga de los Telemandos ## \param self - ## \param unlock Indica si se puede desbloquear el servidor o no (True/False). Por defecto es False. ## \exception IOError Error de entrada/salida ## \exception ConnectionError Error temporal en la conexion ## \exception LockError Cuando el servidor remoto esta bloqueado por un candado de bloqueo ## \exception SMSError Error temporal al enviar el mensaje SMS ## \exception MotorError Error del motor de procesado de PESYR ## \exception ExecutionError Errores desconocidos y fuera de control def download(self,unlock=False): self.debug("Descargando datos para el Telemando '%s'" % (self._name)) try: self.download_extendido(unlock) except IOError,e: # Error definitivo de entrada/salida # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except ConnectionError,e: # Error temporal de conexión # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except LockError,e: # Error definitivo de servidor bloqueado # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except SMSError,e: # Error temporal al enviar el SMS # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except MotorError,e: # Error del motor de procesado # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except KeyboardInterrupt,e: # Necesito estabilizar el Telemando para seguir usándolo self.estabilizar() # Relanzo la excepción raise except Exception,e: error="El Telemando %s no ha sincronizado debido a un error desconocido (%s)" % (self.id(),e) self.debug(error) self.estabilizar() raise ExecutionError,error self.debug("") # }}}1 # Método para resolver incongruencias {{{1 ## \internal ## Metodo para resolver incongruencias ## \param self - def estabilizar(self): # Si hay incongruencias que resolver, las resuelvo for elemento in self.__incongruencias: # Sincronizar 1 if (elemento[0]=="sincronizar1"): self.debug("Resolviendo incongruencia 'sincronizar1'") # Obtengo el directorio al que debo cambiar pwd=elemento[1] try: # Cambio al directorio os.chdir(pwd) except Exception,e: raise TerminalError,"ESTABILIZADOR: No se ha podido volver al directorio origen: %s" % (e) # Si es una incongruencia desconocida else: # La situación es incongruente y no puede ser resuelta (lanzo una excepción Terminal) raise TerminalError,"ESTABILIZADOR: Se han detectado incongruencias desconocidas" # Todas las incongruencias han sido resueltas (la lista queda vacía) self.__incongruencias=[] # }}}1 # Método para habilitar incongruencias {{{1 ## \internal ## Metodo para habilitar incongruencias ## \param self - ## \param incongruencia ID Alfanumerico de la incongruencia def habilitar(self,incongruencia): # Las incongruencias las inserto al principio (mantengo lista invertida) self.debug("Activando control de incongruencia '%s'" % (incongruencia[0])) self.__incongruencias.insert(0,incongruencia) # }}}1 # Método para deshabilitar incongruencias {{{1 ## \internal ## Metodo para deshabilitar incongruencias ## \param self - ## \param incongruencia ID Alfanumerico de la incongruencia def deshabilitar(self,incongruencia): # Inicializo una lista vacía temp=[] # Para toda la lista (manteniendo el orden establecido) for elemento in self.__incongruencias: # Me quedo con las que no coincidan if (elemento!=incongruencia): self.debug("Desactivando control de incongruencia '%s'" % (incongruencia[0])) # Cargo el elemento a la lista temporal temp.append(elemento) # Rehago las lista de incongruencias con la temporal self.__incongruencias=temp # }}}1 # ### EXCEPTIONS ### ################################## # EXCEPTION CLASSES {{{1 # Excepciones básicas # Except (General Exception) {{{2 class Except(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string #}}}2 # LockError (Server locked error) {{{2 class LockError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # SMSError (Error en el servicio de SMSs) {{{2 class SMSError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # MotorError (Error en el motor que procesa los SMSs) {{{2 class MotorError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # ConnectionError (Conexión errónea al servidor) {{{2 class ConnectionError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # IOError (Error de entrada/salida) {{{2 class IOError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # ExecutionError (Error de ejecucción) {{{2 class ExecutionError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # Excepciones graves # TerminalError (Error irrecuperable del programa) {{{2 class TerminalError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # }}}1