# HG changeset patch # User Paul Boddie # Date 1247165311 -7200 # Node ID 2ed5fa92892e43caa79a90d7b0b98df3ecc05f56 # Parent 91c0764ac7c6cdff2264b5636ce940fa3bea5ab0 Changed the XMPP API, separating sending and receiving more thoroughly, adding disconnection support. Removed the internal timeout in the XMPP support. Improved the XMPP test. Updated release notes. diff -r 91c0764ac7c6 -r 2ed5fa92892e README.txt --- a/README.txt Sun Jan 18 19:23:20 2009 +0100 +++ b/README.txt Thu Jul 09 20:48:31 2009 +0200 @@ -14,6 +14,10 @@ From libxml2dom 0.5, some XML-RPC nodes employ different properties. +From libxml2dom 0.5, the send method of libxml2dom.xmpp.Session instances no +longer return responses. Such instances can also no longer be configured with +an internal timeout value. + Contact, Copyright and Licence Information ------------------------------------------ @@ -81,6 +85,9 @@ * Enabled prettyprinting support, finally. * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments from receive method + calls; added support for failure elements; removed the internal timeout + interval; added a disconnect method. New in libxml2dom 0.4.7 (Changes since libxml2dom 0.4.6) -------------------------------------------------------- diff -r 91c0764ac7c6 -r 2ed5fa92892e libxml2dom/macrolib/macrolib.py --- a/libxml2dom/macrolib/macrolib.py Sun Jan 18 19:23:20 2009 +0100 +++ b/libxml2dom/macrolib/macrolib.py Thu Jul 09 20:48:31 2009 +0200 @@ -736,7 +736,7 @@ def Parser_push(): return libxml2mod.xmlCreatePushParser(None, "", 0, None) -def Parser_configure(context, validate, remote): +def Parser_configure(context, validate=0, remote=0): libxml2mod.xmlParserSetPedantic(context, 0) #libxml2mod.xmlParserSetValidate(context, validate) libxml2mod.xmlCtxtUseOptions(context, diff -r 91c0764ac7c6 -r 2ed5fa92892e libxml2dom/xmpp.py --- a/libxml2dom/xmpp.py Sun Jan 18 19:23:20 2009 +0100 +++ b/libxml2dom/xmpp.py Thu Jul 09 20:48:31 2009 +0200 @@ -34,14 +34,16 @@ auth = s.createAuth() # provides access to the stanza auth.mechanism = "PLAIN" # choose a supported mechanism auth.setCredentials(jid, username, password) # for PLAIN authentication only -d = s.send(auth) # hopefully a success response +s.send(auth) # send the authentication request +d = s.receive() # hopefully a success response d = s.connect("host") # have to reconnect! iq = s.createIq() # make an 'iq' stanza iq.makeBind() # set up a binding operation -d = s.send(iq) # hopefully a success response +s.send(iq) # send the binding request +d = s.receive() # hopefully a success response iq = s.createIq() # make an 'iq' stanza iq.makeSession() # set up a session -d = s.send(iq) # hopefully a success response +s.send(iq) # send the session request See tests/xmpp_test.py for more details. """ @@ -129,6 +131,8 @@ elif Node_namespaceURI(_node) == XMPP_SASL_NAMESPACE: if Node_localName(_node) == "auth": return XMPPAuthElement(_node, self, context_node.ownerDocument) + elif Node_localName(_node) == "failure": + return XMPPFailureElement(_node, self, context_node.ownerDocument) # Make special stream elements. @@ -267,6 +271,21 @@ to = property(_to, _setTo, _delTo) type = property(_type, _setType, _delType) +class XMPPFailureElement(XMPPElement): + + "An XMPP failure element." + + def _reason(self): + return self.xpath("*")[0].localName + + def _setReason(self, reason_text): + for reason in self.xpath("*"): + self.removeChild(reason) + element = self.ownerDocument.createElement(reason_text) + self.appendChild(element) + + reason = property(_reason, _setReason) + class XMPPMessageElement(XMPPClientElement): "An XMPP message element." @@ -409,16 +428,14 @@ disconnect_str = """\ """ - def __init__(self, address, timeout=500, bufsize=1024, encoding="utf-8"): + def __init__(self, address, bufsize=1024, encoding="utf-8"): """ Initialise an XMPP session using the given 'address': a tuple of the - form (hostname, port). The optional 'timeout' (in milliseconds) is used - for polling the connection for new data, and the optional 'encoding' - specifies the character encoding employed in the communications. + form (hostname, port). The optional 'encoding' specifies the character + encoding employed in the communications. """ - self.timeout = timeout self.bufsize = bufsize self.encoding = encoding self.poller = select.poll() @@ -427,41 +444,29 @@ self.socket.connect(address) self.poller.register(self.socket.fileno(), select.POLLIN | select.POLLHUP | select.POLLNVAL | select.POLLERR) - def _ready(self, timeout): + def read(self, timeout=None): """ - Return whether data can be read from the server, waiting as long as the - specified 'timeout' (forever if set to None). + Read as much as possible from the server, waiting as long as the + specified 'timeout' (forever if set to None) for a message to arrive. """ - return self.poller.poll(timeout) - - def read(self): - - "Read as much as possible from the server." - context = Parser_push() Parser_configure(context) have_read = 0 - fds = self._ready(self.timeout) - try: - while fds: - for fd, status in fds: - if fd == self.socket.fileno(): - if status & (select.POLLHUP | select.POLLNVAL | select.POLLERR): - raise SessionTerminated - if status & select.POLLIN: - have_read = 1 - c = self.socket.recv(self.bufsize) - Parser_feed(context, c) - if Parser_well_formed(context): - return default_impl.adoptDocument(Parser_document(context)) + fds = self.poller.poll(timeout) - fds = self.poller.poll(self.timeout) - - except SessionTerminated: - pass + for fd, status in fds: + if fd == self.socket.fileno(): + if status & (select.POLLHUP | select.POLLNVAL | select.POLLERR): + raise SessionTerminated + if status & select.POLLIN: + have_read = 1 + c = self.socket.recv(self.bufsize) + Parser_feed(context, c) + if Parser_well_formed(context): + return default_impl.adoptDocument(Parser_document(context)) if have_read: return default_impl.adoptDocument(Parser_document(context)) @@ -477,22 +482,10 @@ def send(self, stanza): """ - Send the 'stanza' to the server, returning a response stanza if an - immediate response was provided, or None otherwise. + Send the 'stanza' to the server. """ stanza.toStream(self, encoding=self.encoding) - return self._receive() - - def _receive(self): - - "Return a stanza for data read from the server." - - doc = self.read() - if doc is None: - return doc - else: - return doc.documentElement def receive(self, timeout=None): @@ -502,10 +495,11 @@ stanza document (fragment) or None if nothing was received. """ - if self._ready(timeout): - return self._receive() + doc = self.read(timeout) + if doc is None: + return None else: - return None + return doc.documentElement # Stanza creation. @@ -532,7 +526,14 @@ # NOTE: tag. self.write(self.connect_str % host) - return self._receive() + return self.receive() + + def disconnect(self): + + # NOTE: Nasty sending of the raw text because it involves only an end + # NOTE: tag. + + self.write(self.disconnect_str) # Utility functions. diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/debian-etch/python-libxml2dom/debian/changelog --- a/packages/debian-etch/python-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/debian-etch/python-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:41:08 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:42:16 +0200 libxml2dom (0.4.7-0ubuntu1) stable; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/debian-lenny/python-libxml2dom/debian/changelog --- a/packages/debian-lenny/python-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/debian-lenny/python-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:41:08 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:42:41 +0200 libxml2dom (0.4.7-0ubuntu1) stable; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/debian-sarge/python2.3-libxml2dom/debian/changelog --- a/packages/debian-sarge/python2.3-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/debian-sarge/python2.3-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:41:36 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:42:52 +0200 libxml2dom (0.4.7-0ubuntu1) stable; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/ubuntu-feisty/python-libxml2dom/debian/changelog --- a/packages/ubuntu-feisty/python-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/ubuntu-feisty/python-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:41:59 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:43:04 +0200 libxml2dom (0.4.7-0ubuntu1) feisty; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/ubuntu-gutsy/python-libxml2dom/debian/changelog --- a/packages/ubuntu-gutsy/python-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/ubuntu-gutsy/python-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:42:07 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:43:15 +0200 libxml2dom (0.4.7-0ubuntu1) feisty; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e packages/ubuntu-hoary/python2.4-libxml2dom/debian/changelog --- a/packages/ubuntu-hoary/python2.4-libxml2dom/debian/changelog Sun Jan 18 19:23:20 2009 +0100 +++ b/packages/ubuntu-hoary/python2.4-libxml2dom/debian/changelog Thu Jul 09 20:48:31 2009 +0200 @@ -13,8 +13,12 @@ * Added the hasChildNodes method, requested by Nick Galbreath. * Fixed the Debian packaging to use python-central. + * Changed the XMPP API to only return document fragments + from receive method calls; added support for failure + elements; removed the internal timeout interval; added a + disconnect method. - -- Paul Boddie Sun, 18 Jan 2009 18:41:51 +0100 + -- Paul Boddie Thu, 09 Jul 2009 20:43:25 +0200 libxml2dom (0.4.7-0ubuntu1) hoary; urgency=low diff -r 91c0764ac7c6 -r 2ed5fa92892e tests/xmpp_test.py --- a/tests/xmpp_test.py Sun Jan 18 19:23:20 2009 +0100 +++ b/tests/xmpp_test.py Thu Jul 09 20:48:31 2009 +0200 @@ -12,22 +12,30 @@ if len(sys.argv) > 2: peer = sys.argv[2] elif sender: - peer = "paulb@jeremy/receiver" + peer = "paulb@localhost/receiver" s = libxml2dom.xmpp.Session(("localhost", 5222)) -d = s.connect("jeremy") +d = s.connect("localhost") print "---- 1 ----" print d.toString() auth = s.createAuth() auth.mechanism = "PLAIN" -auth.setCredentials("paulb@jeremy", "paulb", "jabber") -d = s.send(auth) +auth.setCredentials("paulb@localhost", "paulb", "jabber") +s.send(auth) print "---- 2 ----" +d = s.receive() +print "---- 3 ----" print d.toString() -d = s.connect("jeremy") -print "---- 3 ----" +if d.localName == "failure": + if d.reason == "not-authorized": + print "Not authorized: must register first!" + s.disconnect() + sys.exit(1) + +d = s.connect("localhost") +print "---- 4 ----" print d.toString() iq = s.createIq() @@ -36,19 +44,23 @@ iq.bind.resource = "sender" else: iq.bind.resource = "receiver" -d = s.send(iq) -print "---- 4 ----" +s.send(iq) +print "---- 5 ----" +d = s.receive() +print "---- 6 ----" print d.toString() iq = s.createIq() -iq.makeSession("jeremy") -d = s.send(iq) -print "---- 5 ----" +iq.makeSession("localhost") +s.send(iq) +print "---- 7 ----" +d = s.receive() +print "---- 8 ----" print d.toString() if sender: message = s.createMessage() - message.from_ = "paulb@jeremy/sender" + message.from_ = "paulb@localhost/sender" message.to = peer message.type = "chat" message.body = message.createBody() @@ -56,7 +68,8 @@ message.body.appendChild(text) print "Sending..." print message.toString() - d = s.send(message) + s.send(message) + d = s.receive() if receiver: while 1: @@ -87,7 +100,8 @@ presence.to = doc.from_ print "Sending..." print presence.toString() - d = s.send(presence) + s.send(presence) + d = s.receive() print # vim: tabstop=4 expandtab shiftwidth=4