def main(): log = inicializar_log() try: cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) repo_eventos = RepoEventos(cfg, cliente_mongo) gestion = Gestion(cfg, log) ejecucion_ok = True log.escribir( u'-- GESTIÓN DE EVENTOS INICIADO (v{0}) --'.format( version.__version__), log.INFO) # Procesar posibles eventos activos log.escribir(u'Buscar eventos activos...', log.INFO) eventos_activos = repo_eventos.obtener_eventos_activos() if eventos_activos: gestion.actualizar_datos_eventos(eventos_activos) else: log.escribir(u'No hay eventos activos', log.INFO) except Exception as ex: ejecucion_ok = False log.escribir(u'Se ha producido un error, {0}'.format(ex), log.ERROR) finally: repo.insertar_ejecucion(cliente_mongo, ejecucion_ok, 'Gestion') log.escribir(u'-- FIN GESTIÓN DE EVENTOS --', log.INFO)
def __init__(self, cfg, log): self.cfg = cfg self.log = log self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.analisis = Analisis(self.cfg, self.log) self.gestion = Gestion(self.cfg, self.log) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.repo_nucleos = RepoNucleos(cfg, self.cliente_mongo) self.repo_tipos_evento = RepoTiposEvento(cfg, self.cliente_mongo)
def __init__(self, cfg, log): self.cfg = cfg self.log = log self.twitter = Twitter(self.cfg, self.log) self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.repo_estaciones = RepoEstaciones(cfg, self.cliente_mongo) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.tipo_json = 'json' self.tipo_binario = 'octet-stream' self.campos_analisis_foto = 'Categories, Tags, Description, Faces, ImageType, Adult'
def __init__(self, cfg, log): self.cfg = cfg self.log = log self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.repo_confederaciones = RepoConfederaciones( cfg, self.cliente_mongo) self.repo_estaciones = RepoEstaciones(cfg, self.cliente_mongo) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.repo_variables = RepoVariables(cfg, self.cliente_mongo) self.repo_tipo_evento = RepoTiposEvento(cfg, self.cliente_mongo) self.twitter = Twitter(self.cfg, self.log)
def setUpClass(cls): cls.log = LogSodin(cfg, cfg.FICHERO_LOG_GESTOR, LogSodin.LOGGER_MONITOR) cls.log.configurar_log() cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.repo_tipos_evento = RepoTiposEvento(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.analisis = Analisis(cfg, cls.log) cls.twitter = Twitter(cfg, cls.log)
def setUpClass(cls): cls.chc = CHCantabrico(cfg) cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_confederaciones = RepoConfederaciones(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.repo_variables = RepoVariables(cfg, cls.cliente_mongo) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.nombre_tipo_fluvial = 'Fluvial' cls.cod_tipo_fluvial = 1 cls.cod_chc = 1 #CHCantabrico
def post_proceso_de_evento(self, evento): '''Analiza las fotos y textos, procesa las medidas de los sensores, extrae estadisticas y metadatos y guarda todo en un objeto PostEvento en la BD''' # Analisis ia de fotos y textos de los tweets self.log.escribir(u'2) Procesar tweets', self.log.INFO) tweets_post_procesados = self.analisis_tweets(evento['datosTwitter']) # Analizar datos del medio self.log.escribir(u'3) Procesar medidas de sensores', self.log.INFO) medidas_in_situ = evento['datosConfederaciones'] + evento[ 'datosPuertos'] medidas_post_procesadas = self.procesar_medidas(medidas_in_situ) # Guardar PostEvento en BD self.log.escribir(u'4) Insertar PostEvento en BD', self.log.INFO) post_evento = self.crear_post_evento(evento, tweets_post_procesados, medidas_post_procesadas) repo_eventos = RepoEventos(self.cfg, self.cliente_mongo) return repo_eventos.insertar_post_evento(post_evento)
def setUpClass(cls): cls.log = LogSodin(cfg, cfg.FICHERO_LOG_MONITOR, LogSodin.LOGGER_MONITOR) cls.log.configurar_log() cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_confederaciones = RepoConfederaciones(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.repo_variables = RepoVariables(cfg, cls.cliente_mongo) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.repo_tipos_evento = RepoTiposEvento(cfg, cls.cliente_mongo)
def setUpClass(cls): cls.Chc = CHCantabrico(cfg) cls.log = LogSodin(cfg, cfg.FICHERO_LOG_MONITOR, LogSodin.LOGGER_MONITOR) cls.log.configurar_log() cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_variables = RepoVariables(cfg, cls.cliente_mongo) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.repo_tipos_evento = RepoTiposEvento(cfg, cls.cliente_mongo) cls.CODIGO_CONFEDERACION_CHC = 1
def setUpClass(cls): cls.log = LogSodin(cfg, cfg.FICHERO_LOG_MONITOR, LogSodin.LOGGER_MONITOR) cls.log.configurar_log() cls.twitter = Twitter(cfg, cls.log) cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.repo_nucleos = RepoNucleos(cfg, cls.cliente_mongo) cls.repo_tipos_evento = RepoTiposEvento(cfg, cls.cliente_mongo) cls.repo_confederaciones = RepoConfederaciones(cfg, cls.cliente_mongo) cls.gestion = Gestion(cfg, cls.log) cls.coordinador_evento = CoordinadorEvento(cfg, cls.log)
def setUpClass(cls): cls.log = LogSodin(cfg, cfg.FICHERO_LOG_GESTOR, LogSodin.LOGGER_MONITOR) cls.log.configurar_log() cls.gestion = Gestion(cfg, cls.log) cls.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) cls.repo_confederaciones = RepoConfederaciones(cfg, cls.cliente_mongo) cls.repo_variables = RepoVariables(cfg, cls.cliente_mongo) cls.repo_estaciones = RepoEstaciones(cfg, cls.cliente_mongo) cls.repo_eventos = RepoEventos(cfg, cls.cliente_mongo) cls.repo_tipos_evento = RepoTiposEvento(cfg, cls.cliente_mongo) cls.cod_tipo_evento_fluvial = 1 cls.Coordinador = CoordinadorEvento(cfg, cls.log) cls.id_estacion = 'N020' #Pontenova cls.cod_chc = 1 cls.nivel_rio = 2.14
class Gestion(object): """Clase para gestionar los eventos mientras permanecen activos""" def __init__(self, cfg, log): self.cfg = cfg self.log = log self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.repo_confederaciones = RepoConfederaciones( cfg, self.cliente_mongo) self.repo_estaciones = RepoEstaciones(cfg, self.cliente_mongo) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.repo_variables = RepoVariables(cfg, self.cliente_mongo) self.repo_tipo_evento = RepoTiposEvento(cfg, self.cliente_mongo) self.twitter = Twitter(self.cfg, self.log) def actualizar_datos_eventos(self, eventos_activos): '''Obtiene los ultimos datos y los guarda en el evento''' for evento in eventos_activos: self.guardar_datos_en_evento(evento) self.repo_eventos.actualizar_evento(evento) self.log.escribir(u'OK - Evento actualizado con los últimos datos', self.log.INFO) def guardar_datos_en_evento(self, evento): estacion = self.repo_estaciones.obtener_estacion(evento['idEstacion']) tipo = self.repo_eventos.obtener_tipo_evento(evento['codigoTipo']) self.log.escribir( u'EVENTO {0} activo en {1}. Fecha: {2}'.format( tipo['nombre'], estacion['nombre'], evento['fechaInicio']), self.log.INFO) if tipo == self.repo_tipo_evento.obtener_tipo_evento_fluvial(): # datos de estaciones saih para eventos fluviales self.log.escribir( u'1) Obtener últimos datos de estaciones SAIH para el evento', self.log.INFO) self.guardar_datos_de_saih(evento, estacion) else: # datos de boyas de puertos del estado para eventos costeros self.log.escribir( u'1) Obtener últimos datos de boyas para el evento', self.log.INFO) self.guardar_datos_de_boyas(evento, estacion) # datos twitter self.log.escribir(u'2) Buscar nuevos tweets sobre el evento', self.log.INFO) self.guardar_nuevos_tweets_evento(evento, estacion) # datos aemet? def guardar_datos_de_saih(self, evento, estacion): confederacion = self.repo_confederaciones.obtener_confederacion( estacion['codigoConfederacion']) proveedor_confe = self.repo_confederaciones.obtener_proveedor_saih( confederacion) for variable_estacion in estacion['variables']: variable = self.repo_variables.obtener_variable( variable_estacion['codigo']) try: ultima_medida = proveedor_confe.ultima_medida_de_estacion( estacion, variable) Gestion._agregar_medida_a_evento(evento, 'datosConfederaciones', ultima_medida) self.log.escribir( u'Último dato de {0} añadido al evento'.format( variable['nombre']), self.log.INFO) except ValueError as verr: self.log.escribir( u'No se ha podido obtener la medida. {0}'.format( verr.message), self.log.WARNING) continue def guardar_datos_de_boyas(self, evento, estacion): proveedor_boyas = self.repo_confederaciones.obtener_proveedor_boyas() for variable_estacion in estacion['variables']: variable = self.repo_variables.obtener_variable( variable_estacion['codigo']) try: ultima_medida = proveedor_boyas.ultima_medida_de_estacion( estacion, variable) Gestion._agregar_medida_a_evento(evento, 'datosPuertos', ultima_medida) self.log.escribir( u'Último dato de {0} añadido al evento'.format( variable['nombre']), self.log.INFO) except ValueError as verr: self.log.escribir( u'No se ha podido obtener la medida. {0}'.format( verr.message), self.log.WARNING) continue def guardar_nuevos_tweets_evento(self, evento, estacion): '''Busca y guarda nuevos tweets relacionados con un evento concreto''' # Configurar peticion de busqueda en twitter props = self.propiedades_peticion_twitter(evento, estacion) # Buscar nuevos tweets por lotes tweets = self.twitter.busqueda_tweets_por_lotes( props, config_twitter.NUM_LOTES) self.log.escribir(u'Filtro avanzado de tweets', self.log.INFO) tweets_filtrados = self.twitter.filtro_avanzado_tweets_evento( tweets, evento) # Guardar nuevos tweets en evento de BD if not tweets_filtrados: self.log.escribir( u'No se han encontrado nuevos tweets sobre el evento', self.log.INFO) evento['datosTwitter'].extend(tweets_filtrados) self.log.escribir( u'{0} nuevos tweets agregados al evento'.format( str(len(tweets_filtrados))), self.log.INFO) @staticmethod def _agregar_medida_a_evento(evento, campo_datos, medida): '''Agrega una medida de una estación a un evento''' evento[campo_datos].append(medida.to_json_obj()) def propiedades_peticion_twitter(self, evento, estacion): tipo_fluvial = self.repo_tipo_evento.obtener_tipo_evento_fluvial() toponimos = evento['toponimos'] query_toponimos = u'"{0}"'.format(toponimos[0]) for toponimo in toponimos[1:]: query_toponimos += u' OR "{0}"'.format(toponimo) if evento['codigoTipo'] == tipo_fluvial['codigo']: query = self.twitter.crear_query_twitter( query_toponimos, config_twitter.PALABRAS_CLAVE_FLUVIAL, config_twitter.PALABRAS_EXCLUIDAS, config_twitter.CUENTAS_OFICIALES) else: query = self.twitter.crear_query_twitter( query_toponimos, config_twitter.PALABRAS_CLAVE_COSTERO, config_twitter.PALABRAS_EXCLUIDAS, config_twitter.CUENTAS_OFICIALES) #Activar para filtrar espacialmente la búsqueda de tweets #coords = Gestion.obtener_centroide_estacion(estacion) #query_geo = Twitter.crear_query_geo(coords[0], coords[1]) query_geo = '' id_ultimo_tweet = self.obtener_id_ultimo_tweet_evento(evento) return { 'query': query, 'query_geo': query_geo, 'id_ultimo': id_ultimo_tweet, 'next_max_id': None, 'max_num_tweets': config_twitter.MAX_TWEETS_PETICION } def obtener_id_ultimo_tweet_evento(self, evento): '''Obtiene la id del último tweet de un evento guardado en la BD''' id_ultimo_tweet = 0 try: id_ultimo_tweet = evento['datosTwitter'][0]['id'] except IndexError: self.log.escribir(u'Aun no hay tweets en el evento', self.log.DEBUG) finally: return id_ultimo_tweet @staticmethod def obtener_centroide_estacion(estacion_evento): try: return (estacion_evento['coordenadas']['lon'], estacion_evento['coordenadas']['lat']) except AttributeError as atterr: raise AttributeError( u'Error obteniendo centroide de un evento. {0}'.format( atterr.message))
class Analisis(object): """Clase encargada del analisis y postproceso de un evento de inundación""" def __init__(self, cfg, log): self.cfg = cfg self.log = log self.twitter = Twitter(self.cfg, self.log) self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.repo_estaciones = RepoEstaciones(cfg, self.cliente_mongo) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.tipo_json = 'json' self.tipo_binario = 'octet-stream' self.campos_analisis_foto = 'Categories, Tags, Description, Faces, ImageType, Adult' def post_proceso_de_evento(self, evento): '''Analiza las fotos y textos, procesa las medidas de los sensores, extrae estadisticas y metadatos y guarda todo en un objeto PostEvento en la BD''' # Analisis ia de fotos y textos de los tweets self.log.escribir(u'2) Procesar tweets', self.log.INFO) tweets_post_procesados = self.analisis_tweets(evento['datosTwitter']) # Analizar datos del medio self.log.escribir(u'3) Procesar medidas de sensores', self.log.INFO) medidas_in_situ = evento['datosConfederaciones'] + evento[ 'datosPuertos'] medidas_post_procesadas = self.procesar_medidas(medidas_in_situ) # Guardar PostEvento en BD self.log.escribir(u'4) Insertar PostEvento en BD', self.log.INFO) post_evento = self.crear_post_evento(evento, tweets_post_procesados, medidas_post_procesadas) repo_eventos = RepoEventos(self.cfg, self.cliente_mongo) return repo_eventos.insertar_post_evento(post_evento) def analisis_tweets(self, tweets): tweets_postevento = [] for tweet in tweets: try: tweets_postevento.append(self.procesar_tweet(tweet)) except Exception as ex: self.log.escribir( u'Se ha producido un error analizando el tweet. {0}'. format(ex.message), self.log.WARNING) continue return tweets_postevento def procesar_tweet(self, tweet): self.log.escribir(u' Analizar tweet:', self.log.INFO) foto_procesada = self.analizar_foto_del_tweet(tweet) texto_procesado = self.analizar_texto_del_tweet(tweet) metadatos = self.extraer_metadatos_del_tweet(tweet) tweet_postevento = { 'id_tweet': str(tweet['id']), 'metadatos': metadatos, 'datos_foto': foto_procesada, 'datos_texto': texto_procesado } return tweet_postevento def analizar_foto_del_tweet(self, tweet): self.log.escribir(u' - Buscar fotos asociadas', self.log.INFO) try: foto = None url_foto = self.twitter.obtener_url_foto_de_tweet(tweet) if url_foto is not None: self.log.escribir( u' Ejecución de análisis i.a. de la foto', self.log.INFO) datos_analisis = self.analizar_foto_externa( self.campos_analisis_foto, url_foto) foto = self.crear_objeto_foto(self.campos_analisis_foto, datos_analisis, url_foto) else: self.log.escribir(u' Tweet sin foto asociada', self.log.INFO) except Exception as ex: self.log.escribir( u'No se ha podido hacer el análisis de imagen. {0}'.format( ex.message), self.log.WARNING) finally: return foto def analizar_foto_externa(self, campos_busqueda, url_foto): (cabeceras, parametros) = self.config_peticion_api_vision(campos_busqueda, self.tipo_json) datos_analisis = cpu_vision.process_request({'url': url_foto}, None, cabeceras, parametros) return datos_analisis def analizar_foto_en_disco(self, campos_busqueda, ruta_en_disco): with open(ruta_en_disco, 'rb') as fichero: datos = fichero.read() (cabeceras, parametros) = self.config_peticion_api_vision(campos_busqueda, self.tipo_binario) datos_analisis = cpu_vision.process_request(None, datos, cabeceras, parametros) return datos_analisis def config_peticion_api_vision(self, campos_busqueda, tipo): '''Genera las cabeceras y parametros necesarios para la peticion a la api''' cabeceras = dict() cabeceras[ 'Ocp-Apim-Subscription-Key'] = self.cfg.COMPUTER_VISION_API_KEY cabeceras['Content-Type'] = 'application/{0}'.format(tipo) parametros = { 'visualFeatures': campos_busqueda, 'language': 'en', 'details': 'Landmarks' } return (cabeceras, parametros) # pylint: disable=R0201 def crear_objeto_foto(self, campos, datos_analisis, url_foto): foto_procesada = {} for campo in campos.replace(' ', '').split(','): campo_camelcase = campo[:1].lower() + campo[1:] foto_procesada[campo] = datos_analisis[campo_camelcase] # Añadir la url original de la foto foto_procesada['url'] = url_foto return foto_procesada def analizar_texto_del_tweet(self, tweet): try: self.log.escribir(u' - Análisis semántico del texto', self.log.INFO) (palabras_clave, sentimiento) = text_analytics.analisis_texto( tweet['id'], tweet['text']) texto_procesado = { 'texto': tweet['text'], 'palabras_clave': palabras_clave, 'sentimiento': sentimiento } except Exception as ex: self.log.escribir( u'No se ha podido hacer el análisis del texto. {0}'.format( ex.message), self.log.WARNING) texto_procesado = { 'texto': tweet['text'], 'palabras_clave': [], 'sentimiento': 1 } finally: return texto_procesado def extraer_metadatos_del_tweet(self, tweet): self.log.escribir(u' - Extracción de metadatos del tweet', self.log.INFO) return { 'coordenadas': tweet.get('coordinates'), 'hashtags': tweet.get('entities').get('hashtags', []), 'n_retweets': tweet.get('retweet_count', 0), 'n_likes': tweet.get('favorite_count', 0), #'sensible': tweet['possibly_sensitive'], 'fecha_creacion': tweet.get('created_at'), 'verified': tweet.get('user').get('verified'), 'account': tweet.get('user').get('screen_name') #todo: guardar si tiene enlaces o no. links:true } def procesar_medidas(self, medidas): '''Estandarizacion de los datos de los sensores''' self.log.escribir(u' - Estandarización de datos', self.log.INFO) # Pasar las fechas internas de las medidas a cadena para poder insertar # en BD for medida in medidas: medida['fecha'] = util.convertir_fecha_a_cadena( medida['fecha'], self.cfg.FORMATO_FECHA) return medidas def crear_post_evento(self, evento, tweets_procesados, medidas_procesadas): tipo = self.repo_eventos.obtener_tipo_evento(evento['codigoTipo']) estacion = self.repo_estaciones.obtener_estacion(evento['idEstacion']) try: nuevo_post_evento = PostEvento({ 'idEvento': str(evento['_id']), 'tipo': tipo['nombre'], 'lugar': estacion['nombre'], 'idEstacion': evento['idEstacion'], 'coords': estacion['coordenadas'], 'medidas': medidas_procesadas, 'tweets': tweets_procesados, 'fechaInicio': util.convertir_fecha_a_cadena(evento['fechaInicio'], self.cfg.FORMATO_FECHA), 'fechaFin': util.convertir_fecha_a_cadena(evento['fechaFin'], self.cfg.FORMATO_FECHA) }) return nuevo_post_evento except AttributeError as aterr: raise AttributeError(u'Error creando post evento. {0}'.format( aterr.message))
class CoordinadorEvento(object): """Clase que coordina el ciclo de vida de un evento de inundacion""" def __init__(self, cfg, log): self.cfg = cfg self.log = log self.cliente_mongo = repo.inicializar_cliente(cfg.URI_MONGODB, cfg.NOMBRE_BD) self.analisis = Analisis(self.cfg, self.log) self.gestion = Gestion(self.cfg, self.log) self.repo_eventos = RepoEventos(cfg, self.cliente_mongo) self.repo_nucleos = RepoNucleos(cfg, self.cliente_mongo) self.repo_tipos_evento = RepoTiposEvento(cfg, self.cliente_mongo) def gestionar_alerta(self, estacion, variable, hay_alerta): '''Comprueba el estado de las alertas en una estacion, gestionando un nuevo evento o actualizando uno existente''' evento_estacion = self.obtener_evento_en_estacion(estacion, variable['codigoTipoEvento']) if not hay_alerta and evento_estacion: #Si no hay alerta y existe un evento, hay que desactivarlo if not self.evento_mas_24h(evento_estacion['fechaInicio']): #Si no han pasado 24h el evento se mantiene activo self.log.escribir(u' - Valores normalizados en las primeras 24h, el EVENTO SIGUE ACTIVO', self.log.INFO) return self.desactivar_evento(evento_estacion) self.iniciar_postproceso_evento(evento_estacion) return if hay_alerta and evento_estacion is None: #Si hay alerta y no existe un evento en BD hay que crear uno toponimos = self.crear_lista_toponimos(estacion) res_evento = self.guardar_evento_nuevo(estacion['id'], variable['codigoTipoEvento'], toponimos) self.log.escribir(u' - Valores superan umbral, NUEVO EVENTO ACTIVADO', self.log.INFO) #Insertar datos iniciales en el nuevo evento nuevo_evento = self.repo_eventos.obtener_evento(res_evento) self.gestion.actualizar_datos_eventos([nuevo_evento]) return res_evento if hay_alerta and evento_estacion: self.log.escribir(u' - Valores superan umbral, el EVENTO SIGUE ACTIVO', self.log.INFO) return def evento_mas_24h(self, fecha_inicio_evento): utc = pytz.timezone(u'UTC') fecha_utc = utc.localize(fecha_inicio_evento) ahora = datetime.now(pytz.utc) ayer = ahora + relativedelta(days=-1) return fecha_utc < ayer def obtener_evento_en_estacion(self, estacion, cod_tipo): '''Devuelve el evento activo en la estacion o None si no hay ninguno''' eventos_activos = self.repo_eventos.obtener_eventos_activos_de_tipo(cod_tipo) return util.filtrar_lista(eventos_activos, 'idEstacion', estacion['id']) def desactivar_evento(self, evento): evento['activo'] = False evento['fechaFin'] = util.fecha_actual(self.cfg.FORMATO_FECHA) res = self.repo_eventos.actualizar_evento(evento) if res.modified_count == 1: self.log.escribir(u' - Valores normalizados, EVENTO DESACTIVADO', self.log.INFO) else: self.log.escribir(u' - No se ha podido desactivar el evento. Error actualizando la BD', self.log.WARNING) def iniciar_postproceso_evento(self, evento): self.log.escribir(u' Iniciando Análisis y PostProceso del Evento', self.log.INFO) res = self.analisis.post_proceso_de_evento(evento) if res.acknowledged: self.log.escribir(u' PostEvento guardado con éxito', self.log.INFO) else: self.log.escribir(u' No se ha podido almacenar el PostEvento', self.log.WARNING) def guardar_evento_nuevo(self, id_estacion, cod_tipo_evento, toponimos): evento = self.crear_evento(id_estacion, cod_tipo_evento, toponimos) res = self.repo_eventos.insertar_evento(evento) return res.inserted_id def crear_evento(self, id_estacion, cod_tipo, toponimos): try: nuevo_evento = Evento({ 'fechaInicio' : util.fecha_actual_str(self.cfg.FORMATO_FECHA), 'fechaFin': None, 'codigoTipo' : cod_tipo, 'idEstacion' : id_estacion, 'activo': True, 'toponimos': toponimos, 'datosAemet': [], 'datosPuertos':[], 'datosConfederaciones':[], 'datosTwitter':[] }) return nuevo_evento except AttributeError as aterr: raise AttributeError(u'Error creando nuevo evento. {0}'.format(aterr.message)) def crear_lista_toponimos(self, estacion): # Crear query con un máximo de 200 caracteres. La busqueda en twitter # está limitada # tipo_fluvial = self.repo_tipos_evento.obtener_tipo_evento_fluvial() lista_toponimos = [] # Topónimos de la estación fluvial / costera lista_toponimos.extend([estacion['nombre'], estacion['rio_costa'], estacion['sistema']]) if estacion['codigoTipo'] == tipo_fluvial['codigo']: # Topónimos de núcleos cercanos a la estación fluvial distancia_max = 4000 #4km nombres_nucleos_cercanos = self.repo_nucleos.obtener_nucleos_cercanos(estacion['coordenadas'], distancia_max) else: # Topónimos de núcleos costeros cercanos a la boya distancia_max = 40000 #40km nombres_nucleos_cercanos = self.repo_nucleos.obtener_nucleos_costeros_cercanos(estacion['coordenadas'], distancia_max) for nombre in nombres_nucleos_cercanos: #Hay que limitar los caracteres de la lista de toponimos a un #máximo de 200 por si acaso. #La query final no puede superar los 500 (max de la api de twitter) if nombre.find(".") != -1: #Controlar que no entren nombres con caracteres que rompan la api de twitter continue lista_toponimos.append(nombre) if len(str(lista_toponimos)) > 175: break return lista_toponimos