Ένα μικρό jabber client module που έγραψα, βασισμένο στο twisted python framework. To client παρέχει όλες τις βασικές συναρτήσεις για login στο jabber server, για επικοινωνία με άλλα jabber accounts και εγκρίνει αυτόματα τις αιτήσεις για “αναγνώριση” (presence notifications)
Στο συγκεκριμένο client έχουν βασιστεί και τα echo, fortune και marx bots (σχετικό post).
#!/usr/bin/env python
from twisted.words.protocols.jabber import jid,xmlstream,client
from twisted.words.xish import domish
from twisted.internet import reactor
from string import join, letters
from random import sample
class Jclient:
def __init__(self, server, username, password, resource="Jclient", port=5222, observers=None):
self.username = username
self.password = password
self.resource = resource
self.server = server
self.port = port
self.observers = observers
def connect(self):
self.myJid = jid.JID('%s/%s' % (self.username, self.resource))
factory = client.basicClientFactory(self.myJid, self.password)
factory.addBootstrap('//event/stream/authd', self.authd)
reactor.connectTCP(self.server, self.port, factory)
reactor.run()
def authd(self, xmlstream):
#save xmlstream
self.xmlstream = xmlstream
# send presence
presence = domish.Element(('jabber:client', 'presence'))
xmlstream.send(presence)
self.watchdog()
def watchdog(self):
if not self.observers:
self.observers = {}
#self.observers['/*'] = self.logger
self.observers['/message'] = self.messageHandler
self.observers['/presence'] = self.presenceHandler
for trigger, function in self.observers.items():
self.xmlstream.addObserver(trigger, function)
def logger(self, xmlstream):
print xmlstream.toXml()
def messageHandler(self, xmlstream):
“”"
Returns sender’s jid, receiver’s jid and message
“”"
sender = xmlstream['from']
receiver = xmlstream['to']
message = xmlstream.body.children[0]
id = xmlstream['id']
return sender, receiver, id, message
def send(self, msg):
self.xmlstream.send(msg)
def newMsg(self, to, message, id=None, type=”chat”):
if not id:
# generate id
id = ‘jc’ + join(sample(letters, 5), ”)
msg = domish.Element((’jabber:client’, ‘message’), attribs={’to’:to, ‘from’:self.myJid.full(), ‘type’: type, ‘id’: id})
msg.addElement(’body’, content=message)
return msg
def replyMsg(self, xmlstream, message, type=None):
“”"
Creates reply AND sends it
“”"
msg = self.newMsg(xmlstream['from'], message, None, type or xmlstream['type'])
self.send(msg)
def presenceHandler(self, xmlstream):
“”"
Should implement auto add and auto delete from
presence lists
“”"
if ‘type’ in xmlstream.attributes:
if xmlstream['type'] == ‘error’:
pass
elif xmlstream['type'] == ‘probe’:
msg = domish.Element((’jabber:client’, ‘presence’), attribs = {’to’: xmlstream['from'], ‘from’:xmlstream['to']})
# always free to chat
msg.addElement(’show’, content=”chat”)
else:
msg = domish.Element((’jabber:client’, ‘presence’), attribs = {’type’:xmlstream['type'], ‘to’:xmlstream['from'], ‘from’:xmlstream['to']})
if msg:
self.xmlstream.send(msg)
def __del__(self):
reactor.stop()
Φτιάχνοντας ένα echo bot σε 22 γραμμές με χρήση του Jclient
#!/usr/bin/env python
from jclient import Jclient
from twisted.words.xish import domish
from twisted.internet import reactor
class Jecho(Jclient):
def __init__(self, server, username, password, resource="Jecho", port=5222):
Jclient.__init__(self,server, username, password, resource, port)
self.connect()
def messageHandler(self, xmlstream):
"""
echoes the same message to sender
"""
(sender, receiver, id, message) = Jclient.messageHandler(self,xmlstream)
self.replyMsg(xmlstream,message)
jecho = Jecho("localhost", "server@localhost", "1")