# $Id: net-view.py,v 1.53 2003/10/22 17:50:44 jcea Exp $ # http://www.argo.es/~jcea/irc/modulos/net-view.htm # Este codigo se publica con la licencia "Affero Public License". # Basicamente la licencia GPL, pero incluyendo la clausula # de ejecucion en red. # Mas informacion en http://www.affero.org/oagpl.html import Olimpo debug=Olimpo.debug() or 0 versiones={} uptimes={} tiempo_offset={} rping={} rping_token="XX" rping_token_old="XX" padres={} class _info_nodos: def guarda(self,texto): global debug if debug : return f=open("historico.net","a+") f.write(texto+"\n") f.close() def __init__(self): self.info={} self.guarda("*** INICIO DE SESION") def anadir_info(self,nodo,info): global padres import types if type(info)!=types.StringType : import string info=string.join(info) self.guarda("%s: %s" %(nodo,info)) if self.info.has_key(nodo): self.info[nodo]+=[info] else : self.info[nodo]=[info] def mostrar_info(self,nodo): return self.info.get(nodo) info_nodos=_info_nodos() handle=None nuestro_nick="net-view" def server_split(server,causa): global versiones global tiempo_offset global info_nodos global padres global rping,rping_token,rping_token_old global uptimes import time try : del tiempo_offset[server] except : pass try : del rping[(server,padres[server])] except : pass if server : if not causa : try : p=padres[server] except : p="???" causa="Caida del HUB %s" %(p) versiones[server]=(versiones[server][0],causa,time.asctime(time.localtime(time.time()))) info=list(versiones[server][-2:]) info.append(padres[server]) info_nodos.anadir_info(server,info) else : # Se corta el enlace Olimpo <-> HUP versiones={} info_nodos=_info_nodos() tiempo_offset={} rping={} uptimes={} rping_token="XX" rping_token_old="XX" padres={} def server_join(server,id,padre): global padres global versiones global rping if padre : rping[(server,padre)]=[None,id,[]] if not padre : padre="ROOT (inicio del arbol)" padres[server]=padre versiones[server]=("(Sondeando: %s)" %(server),None,None) Olimpo.servmsg.envia_raw(handle,"VERSION :%s" %(id)) Olimpo.servmsg.envia_raw(handle,"TIME :%s" %(id)) def privmsg(nick,remitente,mensaje): def help(parametros): return ["\002HELP", " Muestra este mensaje de ayuda", "\002TIEMPOS", " Muestra el 'offset' de tiempos de los nodos de la red. El tiempo mostrado se obtiene cuando el servidor entra en la red, o cuando se hace un 'TIEMPOS_NOW'.", "\002TIEMPOS_NOW", " Consulta el 'offset' de tiempos de todos los nodos de la red.", "\002VERSIONES", " Muestra las versiones de cada nodo de la red, incluyendo los que estan en 'split'", "\002VERSIONES_VERBOSE", " Como el anterior, pero mostrando todos los 'flags'", "\002INFO ", " Muestra el historico de entradas y salidas de un nodo", "\002RPING", " Muestra informacion de 'lag' de cada enlace de la red", "\002UPTIME", " Muestra la fecha de arranque de cada nodo de la red", ] def tiempos(parametros) : def sort_mio(a,b) : a,b=abs(a[1]),abs(b[1]) if a>b : return 1 elif a %s: %s" %(i[0],i[1],historico)) return j def uptime(parametros) : global uptimes, versiones datos=[(uptimes.get(i,(0,"Desconocido")),i) for i in versiones.keys()] datos.sort() return ["%s: %s"%(j,i[1]) for i,j in datos] # El bucle es sobre tuplas def info(parametros): global info_nodos if len(parametros)<1 : return ["Te falta introducir el nombre del nodo"] nodo=parametros[0] inf=info_nodos.mostrar_info(nodo) if not inf : return ["El nodo indicado no existe"] return inf def envia(nick,remitente,lineas) : for i in lineas: Olimpo.privmsg.envia_nick(nick,remitente,i) comandos={"help":help, "tiempos":tiempos, "tiempos_now":tiempos_now, "info":info, "versiones":versiones,"versiones_verbose":versiones_verbose,"rping":rping, "uptime":uptime,} flags=Olimpo.privmsg.lee_flags_nick(remitente) if not (('o' in flags) or ('h' in flags)) : envia(nick,remitente,["No tienes permiso para acceder a este bot"]) return parametros=mensaje.split() if not parametros : return # Mensaje vacio (por ejemplo, espacios o tabuladores) comando=parametros[0].lower() parametros=parametros[1:] if not comandos.has_key(comando) : envia(nick,remitente,["Usa 'help'"]) return Olimpo.hace_log(remitente,mensaje) result=comandos[comando](parametros)[:] #Tenemos que hacer una copia result.append("\002Fin de %s." %(comando)) envia(nick,remitente,result) def servmsg(nick,remitente,mensaje): global versiones global padres global tiempo_offset import string import time mensaje2=mensaje.split() if mensaje2[0]=="351" : # VERSION mensaje=string.join(mensaje2[2:]) versiones[remitente]=(mensaje,None,None) info_nodos.anadir_info(remitente, [time.asctime(time.localtime(time.time())),padres[remitente]]) elif mensaje2[0]=="391" : # TIME tiempo_offset[remitente]=int(mensaje2[4]) else : # Respuesta desconocida raise "%s: %s" %(remitente,mensaje) def rpong(comando) : global rping,rping_token,rping_token_old global padres import time t=time.time() server,dummy1,dummy2,padre,ms,token=comando.split() server=server[1:] id,historico=(rping.setdefault((server,padre),[None,None,[]]))[-2:] if token!=rping_token : rping[(server,padre)]=[None,id,[]] else : historico.append(int(ms)) historico=historico[-5:] rping[(server,padre)]=[token,id,historico] return 0 # Para cumplir el API def server(comando) : global uptimes import time datos=comando.split() server,uptime=datos[2],int(datos[8]) if uptime : uptimes[server]=(uptime,time.ctime(uptime)) else : uptimes[server]=(0,"Desconocido") return 0 # Para cumplir el API def rping_temporizado() : import time import random import Olimpo global rping,rping_token,rping_token_old rping_token_old=rping_token rping_token=":%d" %(random.randrange(65536)+1) # Para que no incluya el cero for i,j in rping.items() : Olimpo.servmsg.envia_raw(handle,"RPING %s %s %s" %(i[1],j[1],rping_token)) Olimpo.notify.notifica_timer(int(time.time())+60,rping_temporizado) def inicio(): import time Olimpo.comentario_modulo("Versiones de los nodos de la red $Revision: 1.53 $") global handle handle=Olimpo.privmsg.nuevo_nick(nuestro_nick,"+odkirhB",privmsg) Olimpo.servmsg.serv_callback(handle,servmsg) Olimpo.notify.notifica_server_join(server_join) Olimpo.notify.notifica_server_split(server_split) Olimpo.notify.notifica_servers() Olimpo.notify.notifica_timer(int(time.time())+60,rping_temporizado) Olimpo.servmsg.intercepta_comando("RPONG",rpong) Olimpo.servmsg.intercepta_comando("SERVER",server)