summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sleekxmpp/plugins/xep_0004/stanza/field.py5
-rw-r--r--sleekxmpp/plugins/xep_0004/stanza/form.py12
-rw-r--r--sleekxmpp/plugins/xep_0060/pubsub.py2
-rw-r--r--sleekxmpp/plugins/xep_0060/stanza/pubsub.py40
-rw-r--r--sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py3
-rw-r--r--sleekxmpp/stanza/iq.py22
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py52
-rw-r--r--tests/test_stanza_xep_0060.py14
-rw-r--r--tox.ini2
9 files changed, 63 insertions, 89 deletions
diff --git a/sleekxmpp/plugins/xep_0004/stanza/field.py b/sleekxmpp/plugins/xep_0004/stanza/field.py
index 1e175966..51f85995 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/field.py
+++ b/sleekxmpp/plugins/xep_0004/stanza/field.py
@@ -41,10 +41,11 @@ class FormField(ElementBase):
self._type = value
def add_option(self, label='', value=''):
- if self._type in self.option_types:
- opt = FieldOption(parent=self)
+ if self._type is None or self._type in self.option_types:
+ opt = FieldOption()
opt['label'] = label
opt['value'] = value
+ self.append(opt)
else:
raise ValueError("Cannot add options to " + \
"a %s field." % self['type'])
diff --git a/sleekxmpp/plugins/xep_0004/stanza/form.py b/sleekxmpp/plugins/xep_0004/stanza/form.py
index 721ecc35..bbd8540f 100644
--- a/sleekxmpp/plugins/xep_0004/stanza/form.py
+++ b/sleekxmpp/plugins/xep_0004/stanza/form.py
@@ -65,7 +65,7 @@ class Form(ElementBase):
if kwtype is None:
kwtype = ftype
- field = FormField(parent=self)
+ field = FormField()
field['var'] = var
field['type'] = kwtype
field['value'] = value
@@ -77,6 +77,7 @@ class Form(ElementBase):
field['options'] = options
else:
del field['type']
+ self.append(field)
return field
def getXML(self, type='submit'):
@@ -144,10 +145,9 @@ class Form(ElementBase):
def get_fields(self, use_dict=False):
fields = OrderedDict()
- fieldsXML = self.xml.findall('{%s}field' % FormField.namespace)
- for fieldXML in fieldsXML:
- field = FormField(xml=fieldXML)
- fields[field['var']] = field
+ for stanza in self['substanzas']:
+ if isinstance(stanza, FormField):
+ fields[stanza['var']] = stanza
return fields
def get_instructions(self):
@@ -221,6 +221,8 @@ class Form(ElementBase):
def set_values(self, values):
fields = self['fields']
for field in values:
+ if field not in fields:
+ fields[field] = self.add_field(var=field)
fields[field]['value'] = values[field]
def merge(self, other):
diff --git a/sleekxmpp/plugins/xep_0060/pubsub.py b/sleekxmpp/plugins/xep_0060/pubsub.py
index 952cad85..bec5f565 100644
--- a/sleekxmpp/plugins/xep_0060/pubsub.py
+++ b/sleekxmpp/plugins/xep_0060/pubsub.py
@@ -423,7 +423,7 @@ class XEP_0060(BasePlugin):
callback=None, timeout=None):
iq = self.xmpp.Iq(sto=jid, sfrom=ifrom, stype='set')
iq['pubsub_owner']['configure']['node'] = node
- iq['pubsub_owner']['configure']['form'].values = config.values
+ iq['pubsub_owner']['configure'].append(config)
return iq.send(block=block, callback=callback, timeout=timeout)
def publish(self, jid, node, id=None, payload=None, options=None,
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub.py b/sleekxmpp/plugins/xep_0060/stanza/pubsub.py
index b2fe3010..c1907a13 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub.py
+++ b/sleekxmpp/plugins/xep_0060/stanza/pubsub.py
@@ -74,7 +74,12 @@ class Item(ElementBase):
def set_payload(self, value):
del self['payload']
- self.append(value)
+ if isinstance(value, ElementBase):
+ if value.tag_name() in self.plugin_tag_map:
+ self.init_plugin(value.plugin_attrib, existing_xml=value.xml)
+ self.xml.append(value.xml)
+ else:
+ self.xml.append(value)
def get_payload(self):
childs = list(self.xml)
@@ -243,39 +248,6 @@ class PublishOptions(ElementBase):
self.parent().xml.remove(self.xml)
-class PubsubState(ElementBase):
- """This is an experimental pubsub extension."""
- namespace = 'http://jabber.org/protocol/psstate'
- name = 'state'
- plugin_attrib = 'psstate'
- interfaces = set(('node', 'item', 'payload'))
-
- def set_payload(self, value):
- self.xml.append(value)
-
- def get_payload(self):
- childs = list(self.xml)
- if len(childs) > 0:
- return childs[0]
-
- def del_payload(self):
- for child in self.xml:
- self.xml.remove(child)
-
-
-class PubsubStateEvent(ElementBase):
- """This is an experimental pubsub extension."""
- namespace = 'http://jabber.org/protocol/psstate#event'
- name = 'event'
- plugin_attrib = 'psstate_event'
- intefaces = set(tuple())
-
-
-register_stanza_plugin(Iq, PubsubState)
-register_stanza_plugin(Message, PubsubStateEvent)
-register_stanza_plugin(PubsubStateEvent, PubsubState)
-
-
register_stanza_plugin(Iq, Pubsub)
register_stanza_plugin(Pubsub, Affiliations)
register_stanza_plugin(Pubsub, Configure)
diff --git a/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py b/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py
index 4a35db9d..c10ac762 100644
--- a/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py
+++ b/sleekxmpp/plugins/xep_0060/stanza/pubsub_owner.py
@@ -34,7 +34,8 @@ class DefaultConfig(ElementBase):
return self['form']
def set_config(self, value):
- self['form'].values = value.values
+ del self['from']
+ self.append(value)
return self
diff --git a/sleekxmpp/stanza/iq.py b/sleekxmpp/stanza/iq.py
index 71c0444d..ba945e08 100644
--- a/sleekxmpp/stanza/iq.py
+++ b/sleekxmpp/stanza/iq.py
@@ -115,9 +115,13 @@ class Iq(RootStanza):
"""
query = self.xml.find("{%s}query" % value)
if query is None and value:
- self.clear()
- query = ET.Element("{%s}query" % value)
- self.xml.append(query)
+ plugin = self.plugin_tag_map.get('{%s}query' % value, None)
+ if plugin:
+ self.enable(plugin.plugin_attrib)
+ else:
+ self.clear()
+ query = ET.Element("{%s}query" % value)
+ self.xml.append(query)
return self
def get_query(self):
@@ -182,8 +186,8 @@ class Iq(RootStanza):
the stanza immediately. Used during stream
initialization. Defaults to False.
timeout_callback -- Optional reference to a stream handler function.
- Will be executed when the timeout expires before a
- response has been received with the originally-sent IQ
+ Will be executed when the timeout expires before a
+ response has been received with the originally-sent IQ
stanza. Only called if there is a callback parameter
(and therefore are in async mode).
"""
@@ -194,10 +198,10 @@ class Iq(RootStanza):
if timeout_callback:
self.callback = callback
self.timeout_callback = timeout_callback
- self.stream.schedule('IqTimeout_%s' % self['id'],
- timeout,
- self._fire_timeout,
- repeat=False)
+ self.stream.schedule('IqTimeout_%s' % self['id'],
+ timeout,
+ self._fire_timeout,
+ repeat=False)
handler = Callback(handler_name,
MatcherId(self['id']),
self._handle_result,
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 120373db..97107098 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -3,7 +3,7 @@
sleekxmpp.xmlstream.stanzabase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This module implements a wrapper layer for XML objects
+ module implements a wrapper layer for XML objects
that allows them to be treated like dictionaries.
Part of SleekXMPP: The Sleek XMPP Library
@@ -141,7 +141,7 @@ def multifactory(stanza, plugin_attrib):
parent.loaded_plugins.remove(plugin_attrib)
try:
parent.xml.remove(self.xml)
- except:
+ except ValueError:
pass
else:
for stanza in list(res):
@@ -596,31 +596,39 @@ class ElementBase(object):
iterable_interfaces = [p.plugin_attrib for \
p in self.plugin_iterables]
+ if 'lang' in values:
+ self['lang'] = values['lang']
+
+ if 'substanzas' in values:
+ # Remove existing substanzas
+ for stanza in self.iterables:
+ try:
+ self.xml.remove(stanza.xml)
+ except ValueError:
+ pass
+ self.iterables = []
+
+ # Add new substanzas
+ for subdict in values['substanzas']:
+ if '__childtag__' in subdict:
+ for subclass in self.plugin_iterables:
+ child_tag = "{%s}%s" % (subclass.namespace,
+ subclass.name)
+ if subdict['__childtag__'] == child_tag:
+ sub = subclass(parent=self)
+ sub.values = subdict
+ self.iterables.append(sub)
+
for interface, value in values.items():
full_interface = interface
interface_lang = ('%s|' % interface).split('|')
interface = interface_lang[0]
lang = interface_lang[1] or self.get_lang()
- if interface == 'substanzas':
- # Remove existing substanzas
- for stanza in self.iterables:
- self.xml.remove(stanza.xml)
- self.iterables = []
-
- # Add new substanzas
- for subdict in value:
- if '__childtag__' in subdict:
- for subclass in self.plugin_iterables:
- child_tag = "{%s}%s" % (subclass.namespace,
- subclass.name)
- if subdict['__childtag__'] == child_tag:
- sub = subclass(parent=self)
- sub.values = subdict
- self.iterables.append(sub)
- break
- elif interface == 'lang':
- self[interface] = value
+ if interface == 'lang':
+ continue
+ elif interface == 'substanzas':
+ continue
elif interface in self.interfaces:
self[full_interface] = value
elif interface in self.plugin_attrib_map:
@@ -866,7 +874,7 @@ class ElementBase(object):
self.loaded_plugins.remove(attrib)
try:
self.xml.remove(plugin.xml)
- except:
+ except ValueError:
pass
return self
diff --git a/tests/test_stanza_xep_0060.py b/tests/test_stanza_xep_0060.py
index 16a7cb37..3898d0ab 100644
--- a/tests/test_stanza_xep_0060.py
+++ b/tests/test_stanza_xep_0060.py
@@ -129,20 +129,6 @@ class TestPubsubStanzas(SleekTest):
</pubsub>
</iq>""")
- def testState(self):
- "Testing iq/psstate stanzas"
- iq = self.Iq()
- iq['psstate']['node']= 'mynode'
- iq['psstate']['item']= 'myitem'
- pl = ET.Element('{http://andyet.net/protocol/pubsubqueue}claimed')
- iq['psstate']['payload'] = pl
- self.check(iq, """
- <iq id="0">
- <state xmlns="http://jabber.org/protocol/psstate" node="mynode" item="myitem">
- <claimed xmlns="http://andyet.net/protocol/pubsubqueue" />
- </state>
- </iq>""")
-
def testDefault(self):
"Testing iq/pubsub_owner/default stanzas"
iq = self.Iq()
diff --git a/tox.ini b/tox.ini
index 8576f4eb..91617941 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py26,py27,py31,py32
+envlist = py26,py27,py31,py32,py33
[testenv]
deps = nose
commands = nosetests --where=tests --exclude=live -i sleektest.py