-# Copyright 2004 James Bunton <james@delx.cjb.net>
+# Copyright 2004-2005 James Bunton <james@delx.cjb.net>
# Licensed for distribution under the GPL version 2, check COPYING for details
import utils
-if(utils.checkTwisted()):
- from twisted.xish.domish import Element
- from twisted.words.protocols.jabber import jid
-else:
- from tlib.domish import Element
- from tlib.jabber import jid
-import debug
+from tlib.xmlw import Element, jid
+from debug import LogEvent, INFO, WARN, ERROR
+import disco
def sendMessage(pytrans, to, fro, body, mtype=None, delay=None):
""" Sends a Jabber message """
- debug.log("jabw: Sending a Jabber message \"%s\" \"%s\" \"%s\" \"%s\"" % (to, fro, utils.latin1(body), mtype))
+ LogEvent(INFO)
el = Element((None, "message"))
el.attributes["to"] = to
el.attributes["from"] = fro
if(delay):
x = el.addElement("x")
- x.attributes["xmlns"] = "jabber:x:delay"
+ x.attributes["xmlns"] = disco.XDELAY
x.attributes["from"] = fro
x.attributes["stamp"] = delay
b = el.addElement("body")
b.addContent(body)
x = el.addElement("x")
- x.attributes["xmlns"] = "jabber:x:event"
+ x.attributes["xmlns"] = disco.XEVENT
composing = x.addElement("composing")
pytrans.send(el)
-def sendPresence(pytrans, to, fro, show=None, status=None, priority=None, ptype=None):
+def sendPresence(pytrans, to, fro, show=None, status=None, priority=None, ptype=None, avatarHash=None, nickname=None, payload=[]):
# Strip the resource off any presence subscribes (as per XMPP RFC 3921 Section 5.1.6)
# Makes eJabberd behave :)
- if(ptype == "subscribe"):
- (user,host,res) = jid.parse(to)
- to = "%s@%s" % (user, host)
+ if ptype in ("subscribe", "subscribed", "unsubscribe", "unsubscribed"):
+ to = jid.intern(to).userhost()
+ fro = jid.intern(fro).userhost()
el = Element((None, "presence"))
el.attributes["to"] = to
if(priority):
s = el.addElement("priority")
s.addContent(priority)
+
+ if(not ptype):
+ x = el.addElement("x")
+ x.attributes["xmlns"] = disco.XVCARDUPDATE
+ if(avatarHash):
+ xx = el.addElement("x")
+ xx.attributes["xmlns"] = disco.XAVATAR
+ h = xx.addElement("hash")
+ h.addContent(avatarHash)
+ h = x.addElement("photo")
+ h.addContent(avatarHash)
+ if(nickname):
+ n = x.addElement("nickname")
+ n.addContent(nickname)
+
+ if(payload):
+ for p in payload:
+ el.addChild(p)
+
pytrans.send(el)
error.attributes["type"] = etype
error.attributes["code"] = str(utils.errorCodeMap[condition])
desc = error.addElement(condition)
- desc.attributes["xmlns"] = "urn:ietf:params:xml:ns:xmpp-stanzas"
+ desc.attributes["xmlns"] = disco.XMPP_STANZAS
text = error.addElement("text")
- text.attributes["xmlns"] = "urn:ietf:params:xml:ns:xmpp-stanzas"
+ text.attributes["xmlns"] = disco.XMPP_STANZAS
text.addContent(explanation)
if(body and len(body) > 0):
b = el.addElement("body")
self.typingUser = False # Whether this user can accept typing notifications
self.messageIDs = dict() # The ID of the last message the user sent to a particular contact. Indexed by contact JID
- debug.log("User: %s - JabberConnection constructed" % (self.jabberID))
+ LogEvent(INFO, self.jabberID)
def removeMe(self):
""" Cleanly deletes the object """
- debug.log("User: %s - JabberConnection removed" % (self.jabberID))
-
- def checkFrom(self, el):
- """ Checks to see that this packet was intended for this object """
- fro = el.getAttribute("from")
- froj = jid.JID(fro)
-
- return (froj.userhost() == self.jabberID) # Compare with the Jabber ID that we're looking at
+ LogEvent(INFO, self.jabberID)
def sendMessage(self, to, fro, body, mtype=None, delay=None):
""" Sends a Jabber message
For this message to have a <x xmlns="jabber:x:delay"/> you must pass a correctly formatted timestamp (See JEP0091)
"""
- debug.log("User: %s - JabberConnection sending message \"%s\" \"%s\" \"%s\" \"%s\"" % (self.jabberID, to, fro, utils.latin1(body), mtype))
+ LogEvent(INFO, self.jabberID)
sendMessage(self.pytrans, to, fro, body, mtype, delay)
def sendTypingNotification(self, to, fro, typing):
""" Sends the user the contact's current typing notification status """
if(self.typingUser):
- debug.log("jabw: Sending a Jabber typing notification message \"%s\" \"%s\" \"%s\"" % (to, fro, typing))
+ LogEvent(INFO, self.jabberID)
el = Element((None, "message"))
el.attributes["to"] = to
el.attributes["from"] = fro
x = el.addElement("x")
- x.attributes["xmlns"] = "jabber:x:event"
+ x.attributes["xmlns"] = disco.XEVENT
if(typing):
composing = x.addElement("composing")
id = x.addElement("id")
id.addContent(self.messageIDs[fro])
self.pytrans.send(el)
+ def sendVCardRequest(self, to, fro):
+ """ Requests the the vCard of 'to'
+ Returns a Deferred which fires when the vCard has been received.
+ First argument an Element object of the vCard
+ """
+ el = Element((None, "iq"))
+ el.attributes["to"] = to
+ el.attributes["from"] = fro
+ el.attributes["type"] = "get"
+ el.attributes["id"] = self.pytrans.makeMessageID()
+ vCard = el.addElement("vCard")
+ vCard.attributes["xmlns"] = "vcard-temp"
+ return self.pytrans.discovery.sendIq(el)
+
def sendErrorMessage(self, to, fro, etype, condition, explanation, body=None):
- debug.log("User: %s - JabberConnection sending error response." % (self.jabberID))
+ LogEvent(INFO, self.jabberID)
sendErrorMessage(self.pytrans, to, fro, etype, condition, explanation, body)
- def sendPresence(self, to, fro, show=None, status=None, priority=None, ptype=None):
+ def sendPresence(self, to, fro, show=None, status=None, priority=None, ptype=None, avatarHash=None, nickname=None, payload=[]):
""" Sends a Jabber presence packet """
- debug.log("User: %s - JabberConnection sending presence \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"" % (self.jabberID, to, fro, show, utils.latin1(status), priority, ptype))
- sendPresence(self.pytrans, to, fro, show, status, priority, ptype)
+ LogEvent(INFO, self.jabberID)
+ sendPresence(self.pytrans, to, fro, show, status, priority, ptype, avatarHash, nickname, payload)
def sendRosterImport(self, jid, ptype, sub, name="", groups=[]):
""" Sends a special presence packet. This will work with all clients, but clients that support roster-import will give a better user experience
el.attributes["from"] = jid
el.attributes["type"] = ptype
r = el.addElement("x")
- r.attributes["xmlns"] = "http://jabber.org/protocol/roster-subsync"
+ r.attributes["xmlns"] = disco.SUBSYNC
item = r.addElement("item")
item.attributes["subscription"] = sub
if(name):
def onMessage(self, el):
""" Handles incoming message packets """
- if(not self.checkFrom(el)): return
- debug.log("User: %s - JabberConnection received message packet" % (self.jabberID))
+ #LogEvent(INFO, self.jabberID)
fro = el.getAttribute("from")
- froj = jid.JID(fro)
to = el.getAttribute("to")
- toj = jid.JID(to)
+ try:
+ froj = jid.intern(fro)
+ toj = jid.intern(to)
+ except Exception, e:
+ LogEvent(WARN, self.jabberID)
+ return
+
mID = el.getAttribute("id")
-
mtype = el.getAttribute("type")
body = ""
- invite = ""
+ inviteTo = ""
+ inviteRoom = ""
messageEvent = False
noerror = False
composing = None
for child in el.elements():
if(child.name == "body"):
body = child.__str__()
- if(child.name == "noerror" and child.uri == "sapo:noerror"):
+ elif(child.name == "noerror" and child.uri == "sapo:noerror"):
noerror = True
- if(child.name == "x"):
- if(child.uri == "jabber:x:conference"):
- invite = child.getAttribute("jid") # The room the contact is being invited to
- if(child.uri == "jabber:x:event"):
+ elif(child.name == "x"):
+ if(child.uri == disco.XCONFERENCE):
+ inviteTo = to
+ inviteRoom = child.getAttribute("jid") # The room the contact is being invited to
+ elif(child.uri == disco.MUC_USER):
+ for child2 in child.elements():
+ if(child2.name == "invite"):
+ inviteTo = child2.getAttribute("to")
+ break
+ inviteRoom = to
+ elif(child.uri == disco.XEVENT):
messageEvent = True
composing = False
- for deepchild in child.elements():
- if(deepchild.name == "composing"):
+ for child2 in child.elements():
+ if(child2.name == "composing"):
composing = True
+ break
- if(invite):
- debug.log("User: %s - JabberConnection parsed message groupchat invite packet \"%s\" \"%s\" \"%s\" \"%s\"" % (self.jabberID, froj.userhost(), to, froj.resource, utils.latin1(invite)))
- self.inviteReceived(froj.userhost(), froj.resource, toj.userhost(), toj.resource, invite)
+ if(inviteTo and inviteRoom):
+ LogEvent(INFO, self.jabberID, "Message groupchat invite packet")
+ self.inviteReceived(source=froj.userhost(), resource=froj.resource, dest=inviteTo, destr="", roomjid=inviteRoom)
return
# Check message event stuff
elif(body and not messageEvent):
self.typingUser = False
elif(not body and messageEvent):
- debug.log("User: %s - JabberConnection parsed typing notification \"%s\" \"%s\"" % (self.jabberID, toj.userhost(), composing))
+ LogEvent(INFO, self.jabberID, "Message typing notification packet")
self.typingNotificationReceived(toj.userhost(), toj.resource, composing)
if(body):
-# body = utils.utf8(body)
# Save the message ID for later
self.messageIDs[to] = mID
- debug.log("User: %s - JabberConnection parsed message packet \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"" % (self.jabberID, froj.userhost(), to, froj.resource, mtype, utils.latin1(body)))
+ LogEvent(INFO, self.jabberID, "Message packet")
self.messageReceived(froj.userhost(), froj.resource, toj.userhost(), toj.resource, mtype, body, noerror)
def onPresence(self, el):
""" Handles incoming presence packets """
- if(not self.checkFrom(el)): return
- debug.log("User: %s - JabberConnection received presence packet" % (self.jabberID))
+ #LogEvent(INFO, self.jabberID)
fro = el.getAttribute("from")
- froj = jid.JID(fro)
+ froj = jid.intern(fro)
to = el.getAttribute("to")
- toj = jid.JID(to)
+ toj = jid.intern(to)
# Grab the contents of the <presence/> packet
ptype = el.getAttribute("type")
- if(ptype in ["subscribe", "subscribed", "unsubscribe", "unsubscribed"]):
- debug.log("User: %s - JabberConnection parsed subscription presence packet \"%s\" \"%s\"" % (self.jabberID, toj.userhost(), ptype))
+ if ptype and (ptype.startswith("subscribe") or ptype.startswith("unsubscribe")):
+ LogEvent(INFO, self.jabberID, "Parsed subscription presence packet")
self.subscriptionReceived(toj.userhost(), ptype)
else:
status = None
show = None
priority = None
+ avatarHash = ""
+ nickname = ""
for child in el.elements():
if(child.name == "status"):
status = child.__str__()
show = child.__str__()
elif(child.name == "priority"):
priority = child.__str__()
+ elif(child.uri == disco.XVCARDUPDATE):
+ avatarHash = " "
+ for child2 in child.elements():
+ if(child2.name == "photo"):
+ avatarHash = child2.__str__()
+ elif(child2.name == "nickname"):
+ nickname = child2.__str__()
+
+ if not ptype:
+ # available presence
+ if(avatarHash):
+ self.avatarHashReceived(froj.userhost(), toj.userhost(), avatarHash)
+ if(nickname):
+ self.nicknameReceived(froj.userhost(), toj.userhost(), nickname)
- debug.log("User: %s - JabberConnection parsed presence packet \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"" % (self.jabberID, froj.userhost(), froj.resource, priority, ptype, show, utils.latin1(status)))
+ LogEvent(INFO, self.jabberID, "Parsed presence packet")
self.presenceReceived(froj.userhost(), froj.resource, toj.userhost(), toj.resource, priority, ptype, show, status)
def subscriptionReceived(self, source, subtype):
""" Override this method to be notified when a subscription packet is received """
pass
-
+
+ def nicknameReceived(self, source, dest, nickname):
+ """ Override this method to be notified when a nickname has been received """
+ pass
+
+ def avatarHashReceieved(self, source, dest, avatarHash):
+ """ Override this method to be notified when an avatar hash is received """
+ pass