summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream
diff options
context:
space:
mode:
authorNathan Fritz <fritzy@netflint.net>2009-12-17 01:54:22 +0000
committerNathan Fritz <fritzy@netflint.net>2009-12-17 01:54:22 +0000
commit07018c0afa7485b06424bf6787d242e7ee523d34 (patch)
tree5de2ae3309eb439b96d4dc5ce62abf00597f75f3 /sleekxmpp/xmlstream
parent6897a0b57c299cff9e32fde4dcb4209e70fb4bcb (diff)
downloadslixmpp-07018c0afa7485b06424bf6787d242e7ee523d34.tar.gz
slixmpp-07018c0afa7485b06424bf6787d242e7ee523d34.tar.bz2
slixmpp-07018c0afa7485b06424bf6787d242e7ee523d34.tar.xz
slixmpp-07018c0afa7485b06424bf6787d242e7ee523d34.zip
* fixed many stanza bugs
* added stanza unhandled (unhandled iqs now reply with feature-not-implemented) * added stanza exceptions (stanzas may now reply with exceptions when their handler raises an exception)
Diffstat (limited to 'sleekxmpp/xmlstream')
-rw-r--r--sleekxmpp/xmlstream/handler/waiter.py2
-rw-r--r--sleekxmpp/xmlstream/matcher/id.py6
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py37
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py16
4 files changed, 46 insertions, 15 deletions
diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/sleekxmpp/xmlstream/handler/waiter.py
index 140ce443..ba296386 100644
--- a/sleekxmpp/xmlstream/handler/waiter.py
+++ b/sleekxmpp/xmlstream/handler/waiter.py
@@ -20,7 +20,7 @@ class Waiter(base.BaseHandler):
return self._payload.get(True, timeout)
except queue.Empty:
logging.warning("Timed out waiting for %s" % self.name)
- return StanzaBase(stype='error')
+ return False
def checkDelete(self):
return True
diff --git a/sleekxmpp/xmlstream/matcher/id.py b/sleekxmpp/xmlstream/matcher/id.py
new file mode 100644
index 00000000..ec7597d4
--- /dev/null
+++ b/sleekxmpp/xmlstream/matcher/id.py
@@ -0,0 +1,6 @@
+from . import base
+
+class MatcherId(base.MatcherBase):
+
+ def match(self, xml):
+ return xml.get('id') == self._criteria
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 5403c69f..49ddc305 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -1,4 +1,5 @@
from xml.etree import cElementTree as ET
+import logging
class JID(object):
def __init__(self, jid):
@@ -45,7 +46,12 @@ class ElementBase(object):
if self.xml is None:
self.xml = xml
if self.xml is None:
- self.xml = ET.Element("{%(namespace)s}%(name)s" % {'name': self.name, 'namespace': self.namespace})
+ for ename in self.name.split('/'):
+ new = ET.Element("{%(namespace)s}%(name)s" % {'name': self.name, 'namespace': self.namespace})
+ if self.xml is None:
+ self.xml = new
+ else:
+ self.xml.append(new)
if self.parent is not None:
self.parent.xml.append(self.xml)
return True #had to generate XML
@@ -70,7 +76,7 @@ class ElementBase(object):
else:
return self._getAttr(attrib)
elif attrib in self.plugin_attrib_map:
- self.initPlugin(attrib)
+ if attrib not in self.plugins: self.initPlugin(attrib)
return self.plugins[attrib]
else:
return ''
@@ -87,9 +93,10 @@ class ElementBase(object):
self._setAttr(attrib, value)
else:
self.__delitem__(attrib)
- elif attrib in self.plugin_map:
+ elif attrib in self.plugin_attrib_map:
+ if attrib not in self.plugins: self.initPlugin(attrib)
self.initPlugin(attrib)
- self.plugins[attrib].setValues(value)
+ self.plugins[attrib][attrib] = value
return self
def __delitem__(self, attrib):
@@ -101,7 +108,7 @@ class ElementBase(object):
return self._delSub(attrib)
else:
self._delAttr(attrib)
- elif attrib in self.plugin_map:
+ elif attrib in self.plugin_attrib_map:
if attrib in self.plugins:
del self.plugins[attrib]
return self
@@ -114,7 +121,10 @@ class ElementBase(object):
return True
def _setAttr(self, name, value):
- self.xml.attrib[name] = value
+ if value is None or value == '':
+ self.__delitem__(name)
+ else:
+ self.xml.attrib[name] = value
def _delAttr(self, name):
if name in self.xml.attrib:
@@ -131,12 +141,14 @@ class ElementBase(object):
return stanza.text
def _setSubText(self, name, attrib={}, text=None):
+ if text is None or text == '':
+ return self.__delitem__(name)
stanza = self.xml.find("{%s}%s" % (self.namespace, name))
if stanza is None:
- self.xml.append(ET.Element("{%s}%s" % (self.namespace, name), attrib))
- stanza = self.xml.find("{%s}%s" % (self.namespace, name))
- if text is not None:
- stanza.text = text
+ #self.xml.append(ET.Element("{%s}%s" % (self.namespace, name), attrib))
+ stanza = ET.Element("{%s}%s" % (self.namespace, name))
+ self.xml.append(stanza)
+ stanza.text = text
return stanza
def _delSub(self, name):
@@ -228,6 +240,9 @@ class StanzaBase(ElementBase):
def unhandled(self):
pass
+ def exception(self, text):
+ logging.error(text)
+
def send(self):
self.stream.sendRaw(str(self))
@@ -285,7 +300,7 @@ class StanzaBase(ElementBase):
text[cc] = '&gt;'
elif c == "'":
text[cc] = '&apos;'
- elif self.escape_quotes:
+ else:
text[cc] = '&quot;'
cc += 1
return ''.join(text)
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index e6107642..73729031 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -262,6 +262,8 @@ class XMLStream(object):
handler.prerun(stanza)
self.eventqueue.put(('stanza', handler, stanza))
if handler.checkDelete(): self.__handlers.pop(self.__handlers.index(handler))
+ else:
+ stanza.unhandled()
#loop through handlers and test match
#spawn threads as necessary, call handlers, sending Stanza
@@ -274,10 +276,18 @@ class XMLStream(object):
except queue.Empty:
event = None
if event is not None:
- etype, handler, stanza = event
+ etype, handler, *args = event
if etype == 'stanza':
- handler.run(stanza)
- if etype == 'quit':
+ try:
+ handler.run(args[0])
+ except:
+ args[0].exception(traceback.format_exc())
+ elif etype == 'sched':
+ try:
+ handler.run(*args)
+ except:
+ logging.error(traceback.format_exc())
+ elif etype == 'quit':
logging.debug("Quitting eventRunner thread")
return False