diff options
Diffstat (limited to 'sleekxmpp/xmlstream/stanzabase.py')
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 4180f038..766bdb01 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -45,7 +45,7 @@ def register_stanza_plugin(stanza, plugin, iterable=False, overrides=False): substanzas for the parent, using ``parent['substanzas']``. If the attribute ``plugin_multi_attrib`` was defined for the plugin, then the substanza set can be filtered to only instances of the plugin - class. For example, given a plugin class ``Foo`` with + class. For example, given a plugin class ``Foo`` with ``plugin_multi_attrib = 'foos'`` then:: parent['foos'] @@ -99,6 +99,14 @@ def multifactory(stanza, plugin_attrib): """ Returns a ElementBase class for handling reoccuring child stanzas """ + + def plugin_filter(self): + return lambda x: isinstance(x, self._multistanza) + + def plugin_lang_filter(self, lang): + return lambda x: isinstance(x, self._multistanza) and \ + x['lang'] == lang + class Multi(ElementBase): """ Template class for multifactory @@ -109,9 +117,9 @@ def multifactory(stanza, plugin_attrib): def get_multi(self, lang=None): parent = self.parent() if not lang or lang == '*': - res = filter(lambda sub: isinstance(sub, self._multistanza), parent) + res = filter(plugin_filter(self), parent) else: - res = filter(lambda sub: isinstance(sub, self._multistanza) and sub['lang'] == lang, parent) + res = filter(plugin_filter(self, lang), parent) return list(res) def set_multi(self, val, lang=None): @@ -124,9 +132,9 @@ def multifactory(stanza, plugin_attrib): def del_multi(self, lang=None): parent = self.parent() if not lang or lang == '*': - res = filter(lambda sub: isinstance(sub, self._multistanza), parent) + res = filter(plugin_filter(self), parent) else: - res = filter(lambda sub: isinstance(sub, self._multistanza) and sub['lang'] == lang, parent) + res = filter(plugin_filter(self, lang), parent) res = list(res) if not res: del parent.plugins[(plugin_attrib, None)] @@ -253,8 +261,10 @@ class ElementBase(object): directly from the parent stanza, as shown below, but retrieving information will require all interfaces to be used, as so:: - >>> message['custom'] = 'bar' # Same as using message['custom']['custom'] - >>> message['custom']['custom'] # Must use all interfaces + >>> # Same as using message['custom']['custom'] + >>> message['custom'] = 'bar' + >>> # Must use all interfaces + >>> message['custom']['custom'] 'bar' If the plugin sets :attr:`is_extension` to ``True``, then both setting @@ -272,8 +282,8 @@ class ElementBase(object): """ #: The XML tag name of the element, not including any namespace - #: prefixes. For example, an :class:`ElementBase` object for ``<message />`` - #: would use ``name = 'message'``. + #: prefixes. For example, an :class:`ElementBase` object for + #: ``<message />`` would use ``name = 'message'``. name = 'stanza' #: The XML namespace for the element. Given ``<foo xmlns="bar" />``, @@ -522,8 +532,10 @@ class ElementBase(object): if existing_xml is None: existing_xml = self.xml.find(plugin_class.tag_name()) - if existing_xml is not None and existing_xml.attrib.get('{%s}lang' % XML_NS, '') != lang: - existing_xml = None + + if existing_xml is not None: + if existing_xml.attrib.get('{%s}lang' % XML_NS, '') != lang: + existing_xml = None plugin = plugin_class(parent=self, xml=existing_xml) @@ -761,13 +773,20 @@ class ElementBase(object): else: if attrib in self.sub_interfaces: if lang == '*': - return self._set_all_sub_text(attrib, value, lang='*') - return self._set_sub_text(attrib, text=value, lang=lang) + return self._set_all_sub_text(attrib, + value, + lang='*') + return self._set_sub_text(attrib, text=value, + lang=lang) elif attrib in self.bool_interfaces: if value: - return self._set_sub_text(attrib, '', keep=True, lang=lang) + return self._set_sub_text(attrib, '', + keep=True, + lang=lang) else: - return self._set_sub_text(attrib, '', keep=False, lang=lang) + return self._set_sub_text(attrib, '', + keep=False, + lang=lang) else: self._set_attr(attrib, value) else: @@ -932,7 +951,8 @@ class ElementBase(object): stanzas = self.xml.findall(name) if stanzas: for stanza in stanzas: - stanza_lang = stanza.attrib.get('{%s}lang' % XML_NS, default_lang) + stanza_lang = stanza.attrib.get('{%s}lang' % XML_NS, + default_lang) if not lang or lang == '*' or stanza_lang == lang: results[stanza_lang] = stanza.text return results @@ -996,7 +1016,9 @@ class ElementBase(object): self._del_sub(name, lang) for value_lang, value in values.items(): if not lang or lang == '*' or value_lang == lang: - self._set_sub_text(name, text=value, keep=keep, lang=value_lang) + self._set_sub_text(name, text=value, + keep=keep, + lang=value_lang) def _del_sub(self, name, all=False, lang=None): """Remove sub elements that match the given name or XPath. @@ -1032,7 +1054,9 @@ class ElementBase(object): not element.getchildren(): # Only delete the originally requested elements, and # any parent elements that have become empty. - if lang == '*' or element.attrib.get('{%s}lang' % XML_NS, default_lang) == lang: + elem_lang = element.attrib.get('{%s}lang' % XML_NS, + default_lang) + if lang == '*' or elem_lang == lang: parent.remove(element) if not all: # If we don't want to delete elements up the tree, stop @@ -1272,8 +1296,8 @@ class ElementBase(object): return self def _fix_ns(self, xpath, split=False, propagate_ns=True): - return fix_ns(xpath, split=split, - propagate_ns=propagate_ns, + return fix_ns(xpath, split=split, + propagate_ns=propagate_ns, default_ns=self.namespace) def __eq__(self, other): |