diff options
author | Lance Stout <lancestout@gmail.com> | 2010-10-17 21:38:22 -0400 |
---|---|---|
committer | Lance Stout <lancestout@gmail.com> | 2010-10-17 22:04:42 -0400 |
commit | 4375ac7d8b9e62f34a4d3754a90b3538d5e978a3 (patch) | |
tree | c7da6dddc72ecd299f16d5dd82a4d81f8b0146fa /sleekxmpp/xmlstream/stanzabase.py | |
parent | faec86b3be38756510fb3534c7615db75ecd53b7 (diff) | |
download | slixmpp-4375ac7d8b9e62f34a4d3754a90b3538d5e978a3.tar.gz slixmpp-4375ac7d8b9e62f34a4d3754a90b3538d5e978a3.tar.bz2 slixmpp-4375ac7d8b9e62f34a4d3754a90b3538d5e978a3.tar.xz slixmpp-4375ac7d8b9e62f34a4d3754a90b3538d5e978a3.zip |
Underscore names by default.
Stanza objects now accept the use of underscored names.
The CamelCase versions are still available for backwards compatibility,
but are discouraged.
The property stanza.values now maps to the old getStanzaValues and
setStanzaValues, in addition to _set_stanza_values and
_get_stanza_values.
Diffstat (limited to 'sleekxmpp/xmlstream/stanzabase.py')
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 273 |
1 files changed, 160 insertions, 113 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 6851333f..f4d66aa8 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -20,7 +20,7 @@ from sleekxmpp.xmlstream.tostring import tostring XML_TYPE = type(ET.Element('xml')) -def registerStanzaPlugin(stanza, plugin): +def register_stanza_plugin(stanza, plugin): """ Associate a stanza object as a plugin for another stanza. @@ -33,6 +33,10 @@ def registerStanzaPlugin(stanza, plugin): stanza.plugin_tag_map[tag] = plugin +# To maintain backwards compatibility for now, preserve the camel case name. +registerStanzaPlugin = register_stanza_plugin + + class ElementBase(object): """ @@ -78,9 +82,9 @@ class ElementBase(object): ... plugin_attrib = "custom" The plugin stanza class must be associated with its intended - container stanza by using registerStanzaPlugin as so: + container stanza by using register_stanza_plugin as so: - >>> registerStanzaPlugin(Message, MessagePlugin) + >>> register_stanza_plugin(Message, MessagePlugin) The plugin may then be accessed as if it were built-in to the parent stanza. @@ -115,38 +119,43 @@ class ElementBase(object): parent -- The parent stanza of this stanza. plugins -- A map of enabled plugin names with the initialized plugin stanza objects. + values -- A dictionary of the stanza's interfaces + and interface values, including plugins. Methods: - setup -- Initialize the stanza's XML contents. - enable -- Instantiate a stanza plugin. Alias for initPlugin. - initPlugin -- Instantiate a stanza plugin. - getStanzaValues -- Return a dictionary of stanza interfaces and - their values. - setStanzaValues -- Set stanza interface values given a dictionary of - interfaces and values. - __getitem__ -- Return the value of a stanza interface. - __setitem__ -- Set the value of a stanza interface. - __delitem__ -- Remove the value of a stanza interface. - _setAttr -- Set an attribute value of the main stanza element. - _delAttr -- Remove an attribute from the main stanza element. - _getAttr -- Return an attribute's value from the main - stanza element. - _getSubText -- Return the text contents of a subelement. - _setSubText -- Set the text contents of a subelement. - _delSub -- Remove a subelement. - match -- Compare the stanza against an XPath expression. - find -- Return subelement matching an XPath expression. - findall -- Return subelements matching an XPath expression. - get -- Return the value of a stanza interface, with an - optional default value. - keys -- Return the set of interface names accepted by - the stanza. - append -- Add XML content or a substanza to the stanza. - appendxml -- Add XML content to the stanza. - pop -- Remove a substanza. - next -- Return the next iterable substanza. - _fix_ns -- Apply the stanza's namespace to non-namespaced - elements in an XPath expression. + setup -- Initialize the stanza's XML contents. + enable -- Instantiate a stanza plugin. + Alias for init_plugin. + init_plugin -- Instantiate a stanza plugin. + _get_stanza_values -- Return a dictionary of stanza interfaces and + their values. + _set_stanza_values -- Set stanza interface values given a dictionary + of interfaces and values. + __getitem__ -- Return the value of a stanza interface. + __setitem__ -- Set the value of a stanza interface. + __delitem__ -- Remove the value of a stanza interface. + _set_attr -- Set an attribute value of the main + stanza element. + _del_attr -- Remove an attribute from the main + stanza element. + _get_attr -- Return an attribute's value from the main + stanza element. + _get_sub_text -- Return the text contents of a subelement. + _set_sub_ext -- Set the text contents of a subelement. + _del_sub -- Remove a subelement. + match -- Compare the stanza against an XPath expression. + find -- Return subelement matching an XPath expression. + findall -- Return subelements matching an XPath expression. + get -- Return the value of a stanza interface, with an + optional default value. + keys -- Return the set of interface names accepted by + the stanza. + append -- Add XML content or a substanza to the stanza. + appendxml -- Add XML content to the stanza. + pop -- Remove a substanza. + next -- Return the next iterable substanza. + _fix_ns -- Apply the stanza's namespace to non-namespaced + elements in an XPath expression. """ name = 'stanza' @@ -167,6 +176,18 @@ class ElementBase(object): xml -- Initialize the stanza with optional existing XML. parent -- Optional stanza object that contains this stanza. """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.initPlugin = self.init_plugin + self._getAttr = self._get_attr + self._setAttr = self._set_attr + self._delAttr = self._del_attr + self._getSubText = self._get_sub_text + self._setSubText = self._set_sub_text + self._delSub = self._del_sub + self.getStanzaValues = self._get_stanza_values + self.setStanzaValues = self._set_stanza_values + self.xml = xml self.plugins = {} self.iterables = [] @@ -176,6 +197,9 @@ class ElementBase(object): else: self.parent = weakref.ref(parent) + ElementBase.values = property(ElementBase._get_stanza_values, + ElementBase._set_stanza_values) + if self.setup(xml): # If we generated our own XML, then everything is ready. return @@ -227,14 +251,14 @@ class ElementBase(object): """ Enable and initialize a stanza plugin. - Alias for initPlugin. + Alias for init_plugin. Arguments: attrib -- The stanza interface for the plugin. """ - return self.initPlugin(attrib) + return self.init_plugin(attrib) - def initPlugin(self, attrib): + def init_plugin(self, attrib): """ Enable and initialize a stanza plugin. @@ -246,7 +270,7 @@ class ElementBase(object): self.plugins[attrib] = plugin_class(parent=self) return self - def getStanzaValues(self): + def _get_stanza_values(self): """ Return a dictionary of the stanza's interface values. @@ -256,18 +280,18 @@ class ElementBase(object): for interface in self.interfaces: values[interface] = self[interface] for plugin, stanza in self.plugins.items(): - values[plugin] = stanza.getStanzaValues() + values[plugin] = stanza._get_stanza_values() if self.iterables: iterables = [] for stanza in self.iterables: - iterables.append(stanza.getStanzaValues()) + iterables.append(stanza._get_stanza_values()) iterables[-1].update({ '__childtag__': "{%s}%s" % (stanza.namespace, stanza.name)}) values['substanzas'] = iterables return values - def setStanzaValues(self, values): + def _set_stanza_values(self, values): """ Set multiple stanza interface values using a dictionary. @@ -287,15 +311,15 @@ class ElementBase(object): subclass.name) if subdict['__childtag__'] == child_tag: sub = subclass(parent=self) - sub.setStanzaValues(subdict) + sub._set_stanza_values(subdict) self.iterables.append(sub) break elif interface in self.interfaces: self[interface] = value elif interface in self.plugin_attrib_map: if interface not in self.plugins: - self.initPlugin(interface) - self.plugins[interface].setStanzaValues(value) + self.init_plugin(interface) + self.plugins[interface]._set_stanza_values(value) return self def __getitem__(self, attrib): @@ -307,17 +331,18 @@ class ElementBase(object): 'Message contents' Stanza interfaces are typically mapped directly to the underlying XML - object, but can be overridden by the presence of a getAttrib method - (or getFoo where the interface is named foo, etc). + object, but can be overridden by the presence of a get_attrib method + (or get_foo where the interface is named foo, etc). The search order for interface value retrieval for an interface named 'foo' is: 1. The list of substanzas. - 2. The result of calling getFoo. - 3. The contents of the foo subelement, if foo is a sub interface. - 4. The value of the foo attribute of the XML object. - 5. The plugin named 'foo' - 6. An empty string. + 2. The result of calling get_foo. + 3. The result of calling getFoo. + 4. The contents of the foo subelement, if foo is a sub interface. + 5. The value of the foo attribute of the XML object. + 6. The plugin named 'foo' + 7. An empty string. Arguments: attrib -- The name of the requested stanza interface. @@ -325,17 +350,20 @@ class ElementBase(object): if attrib == 'substanzas': return self.iterables elif attrib in self.interfaces: - get_method = "get%s" % attrib.title() + get_method = "get_%s" % attrib.lower() + get_method2 = "get%s" % attrib.title() if hasattr(self, get_method): return getattr(self, get_method)() + elif hasattr(self, get_method2): + return getattr(self, get_method2)() else: if attrib in self.sub_interfaces: - return self._getSubText(attrib) + return self._get_sub_text(attrib) else: - return self._getAttr(attrib) + return self._get_attr(attrib) elif attrib in self.plugin_attrib_map: if attrib not in self.plugins: - self.initPlugin(attrib) + self.init_plugin(attrib) return self.plugins[attrib] else: return '' @@ -350,18 +378,19 @@ class ElementBase(object): 'Hi!' Stanza interfaces are typically mapped directly to the underlying XML - object, but can be overridden by the presence of a setAttrib method - (or setFoo where the interface is named foo, etc). + object, but can be overridden by the presence of a set_attrib method + (or set_foo where the interface is named foo, etc). The effect of interface value assignment for an interface named 'foo' will be one of: 1. Delete the interface's contents if the value is None. - 2. Call setFoo, if it exists. - 3. Set the text of a foo element, if foo is in sub_interfaces. - 4. Set the value of a top level XML attribute name foo. - 5. Attempt to pass value to a plugin named foo using the plugin's + 2. Call set_foo, if it exists. + 3. Call setFoo, if it exists. + 4. Set the text of a foo element, if foo is in sub_interfaces. + 5. Set the value of a top level XML attribute name foo. + 6. Attempt to pass value to a plugin named foo using the plugin's foo interface. - 6. Do nothing. + 7. Do nothing. Arguments: attrib -- The name of the stanza interface to modify. @@ -369,19 +398,22 @@ class ElementBase(object): """ if attrib in self.interfaces: if value is not None: - set_method = "set%s" % attrib.title() + set_method = "set_%s" % attrib.lower() + set_method2 = "set%s" % attrib.title() if hasattr(self, set_method): getattr(self, set_method)(value,) + elif hasattr(self, set_method2): + getattr(self, set_method2)(value,) else: if attrib in self.sub_interfaces: - return self._setSubText(attrib, text=value) + return self._set_sub_text(attrib, text=value) else: - self._setAttr(attrib, value) + self._set_attr(attrib, value) else: self.__delitem__(attrib) elif attrib in self.plugin_attrib_map: if attrib not in self.plugins: - self.initPlugin(attrib) + self.init_plugin(attrib) self.plugins[attrib][attrib] = value return self @@ -398,29 +430,33 @@ class ElementBase(object): '' Stanza interfaces are typically mapped directly to the underlyig XML - object, but can be overridden by the presence of a delAttrib method - (or delFoo where the interface is named foo, etc). + object, but can be overridden by the presence of a del_attrib method + (or del_foo where the interface is named foo, etc). The effect of deleting a stanza interface value named foo will be one of: - 1. Call delFoo, if it exists. - 2. Delete foo element, if foo is in sub_interfaces. - 3. Delete top level XML attribute named foo. - 4. Remove the foo plugin, if it was loaded. - 5. Do nothing. + 1. Call del_foo, if it exists. + 2. Call delFoo, if it exists. + 3. Delete foo element, if foo is in sub_interfaces. + 4. Delete top level XML attribute named foo. + 5. Remove the foo plugin, if it was loaded. + 6. Do nothing. Arguments: attrib -- The name of the affected stanza interface. """ if attrib in self.interfaces: - del_method = "del%s" % attrib.title() + del_method = "del_%s" % attrib.lower() + del_method2 = "del%s" % attrib.title() if hasattr(self, del_method): getattr(self, del_method)() + elif hasattr(self, del_method2): + getattr(self, del_method2)() else: if attrib in self.sub_interfaces: - return self._delSub(attrib) + return self._del_sub(attrib) else: - self._delAttr(attrib) + self._del_attr(attrib) elif attrib in self.plugin_attrib_map: if attrib in self.plugins: xml = self.plugins[attrib].xml @@ -428,7 +464,7 @@ class ElementBase(object): self.xml.remove(xml) return self - def _setAttr(self, name, value): + def _set_attr(self, name, value): """ Set the value of a top level attribute of the underlying XML object. @@ -445,7 +481,7 @@ class ElementBase(object): else: self.xml.attrib[name] = value - def _delAttr(self, name): + def _del_attr(self, name): """ Remove a top level attribute of the underlying XML object. @@ -455,7 +491,7 @@ class ElementBase(object): if name in self.xml.attrib: del self.xml.attrib[name] - def _getAttr(self, name, default=''): + def _get_attr(self, name, default=''): """ Return the value of a top level attribute of the underlying XML object. @@ -471,7 +507,7 @@ class ElementBase(object): """ return self.xml.attrib.get(name, default) - def _getSubText(self, name, default=''): + def _get_sub_text(self, name, default=''): """ Return the text contents of a sub element. @@ -491,7 +527,7 @@ class ElementBase(object): else: return stanza.text - def _setSubText(self, name, text=None, keep=False): + def _set_sub_text(self, name, text=None, keep=False): """ Set the text contents of a sub element. @@ -513,7 +549,7 @@ class ElementBase(object): element = self.xml.find(name) if not text and not keep: - return self._delSub(name) + return self._del_sub(name) if element is None: # We need to add the element. If the provided name was @@ -534,7 +570,7 @@ class ElementBase(object): element.text = text return element - def _delSub(self, name, all=False): + def _del_sub(self, name, all=False): """ Remove sub elements that match the given name or XPath. @@ -819,13 +855,13 @@ class ElementBase(object): return False # Check that this stanza is a superset of the other stanza. - values = self.getStanzaValues() + values = self._get_stanza_values() for key in other.keys(): if key not in values or values[key] != other[key]: return False # Check that the other stanza is a superset of this stanza. - values = other.getStanzaValues() + values = other._get_stanza_values() for key in self.keys(): if key not in values or values[key] != self[key]: return False @@ -932,23 +968,23 @@ class StanzaBase(ElementBase): tag -- The namespaced version of the stanza's name. Methods: - setType -- Set the type of the stanza. - getTo -- Return the stanza recipients JID. - setTo -- Set the stanza recipient's JID. - getFrom -- Return the stanza sender's JID. - setFrom -- Set the stanza sender's JID. - getPayload -- Return the stanza's XML contents. - setPayload -- Append to the stanza's XML contents. - delPayload -- Remove the stanza's XML contents. - clear -- Reset the stanza's XML contents. - reply -- Reset the stanza and modify the 'to' and 'from' - attributes to prepare for sending a reply. - error -- Set the stanza's type to 'error'. - unhandled -- Callback for when the stanza is not handled by a - stream handler. - exception -- Callback for if an exception is raised while - handling the stanza. - send -- Send the stanza using the stanza's stream. + set_type -- Set the type of the stanza. + get_to -- Return the stanza recipients JID. + set_to -- Set the stanza recipient's JID. + get_from -- Return the stanza sender's JID. + set_from -- Set the stanza sender's JID. + get_payload -- Return the stanza's XML contents. + set_payload -- Append to the stanza's XML contents. + del_payload -- Remove the stanza's XML contents. + clear -- Reset the stanza's XML contents. + reply -- Reset the stanza and modify the 'to' and 'from' + attributes to prepare for sending a reply. + error -- Set the stanza's type to 'error'. + unhandled -- Callback for when the stanza is not handled by a + stream handler. + exception -- Callback for if an exception is raised while + handling the stanza. + send -- Send the stanza using the stanza's stream. """ name = 'stanza' @@ -970,6 +1006,17 @@ class StanzaBase(ElementBase): sfrom -- Optional string or JID object of the sender's JID. sid -- Optional ID value for the stanza. """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setType = self.set_type + self.getTo = self.get_to + self.setTo = self.set_to + self.getFrom = self.get_from + self.setFrom = self.set_from + self.getPayload = self.get_payload + self.setPayload = self.set_payload + self.delPayload = self.del_payload + self.stream = stream if stream is not None: self.namespace = stream.default_ns @@ -982,7 +1029,7 @@ class StanzaBase(ElementBase): self['from'] = sfrom self.tag = "{%s}%s" % (self.namespace, self.name) - def setType(self, value): + def set_type(self, value): """ Set the stanza's 'type' attribute. @@ -995,37 +1042,37 @@ class StanzaBase(ElementBase): self.xml.attrib['type'] = value return self - def getTo(self): + def get_to(self): """Return the value of the stanza's 'to' attribute.""" - return JID(self._getAttr('to')) + return JID(self._get_attr('to')) - def setTo(self, value): + def set_to(self, value): """ Set the 'to' attribute of the stanza. Arguments: value -- A string or JID object representing the recipient's JID. """ - return self._setAttr('to', str(value)) + return self._set_attr('to', str(value)) - def getFrom(self): + def get_from(self): """Return the value of the stanza's 'from' attribute.""" - return JID(self._getAttr('from')) + return JID(self._get_attr('from')) - def setFrom(self, value): + def set_from(self, value): """ Set the 'from' attribute of the stanza. Arguments: from -- A string or JID object representing the sender's JID. """ - return self._setAttr('from', str(value)) + return self._set_attr('from', str(value)) - def getPayload(self): + def get_payload(self): """Return a list of XML objects contained in the stanza.""" return self.xml.getchildren() - def setPayload(self, value): + def set_payload(self, value): """ Add XML content to the stanza. @@ -1039,7 +1086,7 @@ class StanzaBase(ElementBase): self.append(val) return self - def delPayload(self): + def del_payload(self): """Remove the XML contents of the stanza.""" self.clear() return self |