#!/usr/bin/python # -*- coding: iso-8859-1 -*- # modulos import xmpp import time import commands import random # variables configurables bichoname = "bot" jid = "ulysses@gulic.org" password = "****" sala="gulic@jabber.gulic.org" # cosas de conversación sinonimos = { 'presaludo': ['Hola', 'Buenos dias', 'Buenas tardes', 'Buenas noches', 'Que tal', 'Oh', 'Passa'], 'gente': ['gente', 'penyita', 'linuxerillos', 'softwarelibretos', 'coleguitos', 'puntalillos', 'jabberistas'], 'saludo': ['como te va?', 'como lo llevas?', 'que paso?', 'como andas?'], 'malo': ['me da mal rollito', 'me da yuyu', 'me la pone mal', 'no me hace tilin', 'me disgusta', 'me desagrada', 'no me simpatiza'], 'cosasmalas': ['windows', 'microsoft', 'skype', 'esquipe', 'office', 'msn', 'hotmail', 'propietario', 'word', 'excel', 'access', 'powerpoint', 'explorer'], 'eresun': ['que sepas que eres un', 'por si no lo sabias eres un', 'todo el mundo sabe que eres', 'vete enterandote de que eres un'], 'insultos': ['tonto', 'bobo', 'estupido', 'engreido', 'bobalicon', 'desagradable', 'capullo'], 'apostilla': ['que lo sepas', 'por si no te habias enterado', 'por si no te quedaba claro', 'vale?', 'ejem', 'piiii', 'barbarita de dios'], 'presalida': [ 'bueno...', 'pos na...', 'ya se va haciendo la hora', 'en fin...', 'que le vamos a hacer'], 'salida1': ['me tengo que marchar', 'me voy', 'me retiro', 'me las piro', 'me escaqueo'], 'salida2': ['que mi parienta me reclama', 'que tengo que sacar al perro', 'que tengo que cambiar el agua al canario', 'que tengo que hacerme la comida', 'que tengo que alisarme las pestanas'], 'salida3': ['xD', ';-P', ';-))', ':))', 'X-D'], 'adios': ['bye', 'adios', 'agur', 'saludos', 'hasta luego'], 'verborrea': ['muy interesante, %s', 'ah si? bien hecho %s', 'pues no lo sabia %s', 'de verdad %s?', 'no me lo creo %s'], } rand=random.Random() rand.seed() def eligeme(sinon): "Devuelve un sinonimo de sinon" return rand.choice(sinonimos[sinon]) def eligemefrase(prefrase): "devuelve una frase compuesta de sinonimos separados por espacios" return " ".join(map(eligeme, prefrase.split(" "))) def buscame(frase, sinon): "Busca si una frase contiene un sinonimo de sinon" for palabra in sinonimos[sinon]: if frase.lower().find(palabra.lower()) != -1: return palabra return None # cosas de fechas ts2fecha = lambda ts: time.strftime("%Y/%m/%d %H:%M:%S", time.strptime(ts,'%Y%m%dT%H:%M:%S %Z')) ts2secs = lambda ts: time.mktime(time.strptime(ts,'%Y%m%dT%H:%M:%S %Z')) secs2fecha = lambda secs: time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(secs)) ejecuta = lambda str: Popen(str.split(' '), stdout=PIPE).communicate()[0] # clases class bot_base: def __init__(self, jid, password): j = xmpp.JID(jid) self.conecta(j.getNode(), password, j.getDomain()) def conecta(self, user, password, server, realserver='localhost'): self.server = server self.cl = xmpp.Client(server, debug=[]) if not self.cl.connect(server=(realserver,5223)): raise IOError('no pude conectar') if not self.cl.auth(user, password): raise IOError('no pude autentificar') self.cl.RegisterHandler('message',self.messageCB) def send(self, msg): self.cl.send(msg) def entra_sala(self, room): self.room = room self.send(xmpp.Presence(self.room + "/" + bichoname)) def mensaje(self, jid, mensaje, type): msg = xmpp.Message(jid, mensaje) msg.setType(type) self.send(msg) def mensaje_sala(self, mensaje): self.mensaje(self.room, mensaje, 'groupchat') def mensaje_usuario(self, jid, mensaje): self.mensaje(jid, mensaje, 'chat') def mensaje_broadcast(self, mensaje): self.mensaje(self.server + '/announce/online', mensaje, 'chat') def responde(self, mess, mensaje): # mess.buildReply(mensaje) no es cosa fina :-( if mess.getType() == 'error': pass # amos elif mess.getType() == 'groupchat': self.mensaje(mess.getFrom().getStripped(), mensaje, 'groupchat') else: self.mensaje(mess.getFrom(), mensaje, 'chat') def salir_sala(self): self.send(xmpp.Presence(self.room, 'unavailable')) def end(self): self.cl.disconnect() def messageCB(self, sess, mess): self.last_mess = mess nick=mess.getFrom() #.getResource() text=mess.getBody() tipo=mess.getType() ts=mess.getTimestamp() def itera(self): pass def procesa(self): self.cl.Process(1) class bot(bot_base): def __init__(self, *args, **kwargs): bot_base.__init__(self, *args, **kwargs) def messageCB(self, sess, mess): bot_base.messageCB(self, sess, mess) print "fecha=%s, tipo=%s, nick=%s, text=%s" % ( ts2fecha(mess.getTimestamp()), mess.getType(), mess.getFrom(), mess.getBody()) if mess.getType() == "error": pass elif mess.getType() == "chat": self.responde(mess, "he recibido con exito tu mensaje: \"%s\"" % mess.getBody() ) elif mess.getType() == "groupchat": if mess.getFrom().getResource() != bichoname or '': self.mensaje_sala("he recibido con exito un mensaje de %s" % mess.getFrom() ) def itera(self): for i in range(60): try: self.procesa() except KeyboardInterrupt: print "Break detectado... entiendo la indirecta... adios" break class ia (bot_base): def __init__(self, *args, **kwargs): bot_base.__init__(self, *args, **kwargs) self.exit = 0 def messageCB(self, sess, mess): bot_base.messageCB(self, sess, mess) if mess.getFrom().getResource().find(bichoname) != -1: #print 'nobot' return # no nos vamos a responder a nosotros mismos, estaria bueno ;-) if mess.getFrom().getResource() == '': #print 'nosala' return # tampoco a la sala if time.time() - 3600*time.daylight - ts2secs(mess.getTimestamp()) > 10: #print 'noviejos' return # tampoco a los antiguos if mess.getType() == 'chat': if mess.getFrom().getDomain() == 'jabber.gulic.org': self.prueba_directo(mess, mess.getFrom().getResource()) else: self.prueba_directo(mess, mess.getFrom().getNode()) elif mess.getType() == 'groupchat': if mess.getBody().find(bichoname+':') != -1: self.prueba_directo(mess, mess.getFrom().getResource()) elif mess.getBody().find(bichoname) != -1: self.prueba_indirecto(mess, mess.getFrom().getResource()) else: self.prueba_colateral(mess, mess.getFrom().getResource()) else: return def itera(self): try: self.exit = 0 while self.exit == 0: self.procesa() except KeyboardInterrupt: print 'Exiting...' return def responde(self, mess, mensaje): bot_base.responde(self, mess, mensaje) #print 'post-respondido: ', mensaje, mess.getFrom(), '->', mess.getTo() #.getResource() def prueba_directo(self, mess, quien): entrada = mess.getBody() if entrada.find('uptime') != -1: salida = commands.getoutput('uptime') elif entrada.find('who') != -1: salida = commands.getoutput('who | wc -l') + " personas ahora mismo en ulysses" elif entrada.find('adios') != -1: self.exit = 1 return else: salida = "no te entiendo, "+quien self.responde(mess, salida) def prueba_indirecto(self, mess, quien): entrada = mess.getBody() tmp = buscame(entrada, 'presaludo') if tmp is not None: salida = "%s %s, %s" % ( eligeme('presaludo'), quien, eligeme('saludo')) self.responde(mess, salida) return tmp = buscame(entrada, 'insultos') if tmp is not None: salida = "%s a mi? %s %s" % ( tmp, quien, eligemefrase ('eresun insultos apostilla')) self.responde(mess, salida) return salida = eligeme('verborrea') % quien self.responde(mess, salida) def prueba_colateral(self, mess, quien): entrada = mess.getBody() tmp = buscame(entrada, 'cosasmalas') if tmp is not None: salida = "%s %s, %s" % ( tmp, eligeme('malo'), quien) self.responde(mess, salida) return tmp = buscame(entrada, 'presaludo') if tmp is not None: salida = "%s %s, %s" % ( tmp, quien, eligeme('saludo')) self.responde(mess, salida) return tmp = buscame(entrada, 'insultos') if tmp is not None: salida = "ahi, %s, dale dale %s" % ( quien, eligeme('apostilla')) self.responde(mess, salida) return tmp = buscame(entrada, 'adios') if tmp is not None: salida = "%s %s" % (eligeme('adios'), quien) self.responde(mess, salida) return return # normalmente en este caso pasamos de lo que no entendemos :-) # main app if __name__ == "__main__": mybot = ia(jid + "/" + bichoname, password) mybot.entra_sala(sala) mybot.mensaje_sala( eligemefrase('presaludo gente')) mybot.itera() #mybot.mensaje_broadcast("mensajito de prueba para el broadcast") #mybot.mensaje_usuario("amd77@gulic.org", "mensajito de prueba para amd77@gulic.org") mybot.mensaje_sala( eligemefrase('presalida salida1 salida2 salida3 adios')) mybot.salir_sala() mybot.end()