diff options
Diffstat (limited to 'sleekxmpp')
-rw-r--r-- | sleekxmpp/basexmpp.py | 30 | ||||
-rw-r--r-- | sleekxmpp/clientxmpp.py | 6 | ||||
-rw-r--r-- | sleekxmpp/componentxmpp.py | 2 | ||||
-rw-r--r-- | sleekxmpp/stanza/error.py | 44 | ||||
-rw-r--r-- | sleekxmpp/stanza/htmlim.py | 35 | ||||
-rw-r--r-- | sleekxmpp/stanza/iq.py | 36 | ||||
-rw-r--r-- | sleekxmpp/stanza/message.py | 60 | ||||
-rw-r--r-- | sleekxmpp/stanza/nick.py | 37 | ||||
-rw-r--r-- | sleekxmpp/stanza/presence.py | 83 | ||||
-rw-r--r-- | sleekxmpp/stanza/rootstanza.py | 4 | ||||
-rw-r--r-- | sleekxmpp/stanza/roster.py | 36 | ||||
-rw-r--r-- | sleekxmpp/test/sleektest.py | 3 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/__init__.py | 1 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 273 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/xmlstream.py | 2 |
15 files changed, 403 insertions, 249 deletions
diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index 3db29a9a..8197f6a7 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -21,7 +21,7 @@ from sleekxmpp.stanza.nick import Nick from sleekxmpp.stanza.htmlim import HTMLIM from sleekxmpp.xmlstream import XMLStream, JID, tostring -from sleekxmpp.xmlstream.stanzabase import ET, registerStanzaPlugin +from sleekxmpp.xmlstream import ET, register_stanza_plugin from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.handler import * @@ -142,9 +142,9 @@ class BaseXMPP(XMLStream): self.registerStanza(Presence) # Initialize a few default stanza plugins. - registerStanzaPlugin(Iq, Roster) - registerStanzaPlugin(Message, Nick) - registerStanzaPlugin(Message, HTMLIM) + register_stanza_plugin(Iq, Roster) + register_stanza_plugin(Message, Nick) + register_stanza_plugin(Message, HTMLIM) def process(self, *args, **kwargs): """ @@ -256,8 +256,8 @@ class BaseXMPP(XMLStream): Defaults to 0. ifrom -- The from JID to use for this stanza. """ - return self.Iq().setStanzaValues({'id': str(id), - 'from': ifrom}) + return self.Iq()._set_stanza_values({'id': str(id), + 'from': ifrom}) def make_iq_get(self, queryxmlns=None): """ @@ -268,8 +268,8 @@ class BaseXMPP(XMLStream): Arguments: queryxmlns -- The namespace of the query to use. """ - return self.Iq().setStanzaValues({'type': 'get', - 'query': queryxmlns}) + return self.Iq()._set_stanza_values({'type': 'get', + 'query': queryxmlns}) def make_iq_result(self, id): """ @@ -278,8 +278,8 @@ class BaseXMPP(XMLStream): Arguments: id -- An ideally unique ID value. May use self.new_id(). """ - return self.Iq().setStanzaValues({'id': id, - 'type': 'result'}) + return self.Iq()._set_stanza_values({'id': id, + 'type': 'result'}) def make_iq_set(self, sub=None): """ @@ -291,7 +291,7 @@ class BaseXMPP(XMLStream): Arguments: sub -- A stanza or XML object to use as the Iq's payload. """ - iq = self.Iq().setStanzaValues({'type': 'set'}) + iq = self.Iq()._set_stanza_values({'type': 'set'}) if sub != None: iq.append(sub) return iq @@ -309,10 +309,10 @@ class BaseXMPP(XMLStream): Defaults to 'feature-not-implemented'. text -- A message describing the cause of the error. """ - iq = self.Iq().setStanzaValues({'id': id}) - iq['error'].setStanzaValues({'type': type, - 'condition': condition, - 'text': text}) + iq = self.Iq()._set_stanza_values({'id': id}) + iq['error']._set_stanza_values({'type': type, + 'condition': condition, + 'text': text}) return iq def make_iq_query(self, iq=None, xmlns=''): diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py index 1734a13c..3f0f5e26 100644 --- a/sleekxmpp/clientxmpp.py +++ b/sleekxmpp/clientxmpp.py @@ -19,9 +19,9 @@ from sleekxmpp import stanza from sleekxmpp.basexmpp import BaseXMPP from sleekxmpp.stanza import Message, Presence, Iq from sleekxmpp.xmlstream import XMLStream, RestartStream +from sleekxmpp.xmlstream import StanzaBase, ET from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.handler import * -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET # Flag indicating if DNS SRV records are available for use. SRV_SUPPORT = True @@ -203,7 +203,7 @@ class ClientXMPP(BaseXMPP): to 'remove', the entry will be deleted. groups -- The roster groups that contain this item. """ - iq = self.Iq().setStanzaValues({'type': 'set'}) + iq = self.Iq()._set_stanza_values({'type': 'set'}) iq['roster']['items'] = {jid: {'name': name, 'subscription': subscription, 'groups': groups}} @@ -222,7 +222,7 @@ class ClientXMPP(BaseXMPP): def get_roster(self): """Request the roster from the server.""" - iq = self.Iq().setStanzaValues({'type': 'get'}).enable('roster') + iq = self.Iq()._set_stanza_values({'type': 'get'}).enable('roster') iq.send() self._handle_roster(iq, request=True) diff --git a/sleekxmpp/componentxmpp.py b/sleekxmpp/componentxmpp.py index 523e75af..d0901a2e 100644 --- a/sleekxmpp/componentxmpp.py +++ b/sleekxmpp/componentxmpp.py @@ -17,9 +17,9 @@ from sleekxmpp import plugins from sleekxmpp import stanza from sleekxmpp.basexmpp import BaseXMPP, SRV_SUPPORT from sleekxmpp.xmlstream import XMLStream, RestartStream +from sleekxmpp.xmlstream import StanzaBase, ET from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.handler import * -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET class ComponentXMPP(BaseXMPP): diff --git a/sleekxmpp/stanza/error.py b/sleekxmpp/stanza/error.py index 6d18c297..09229bc6 100644 --- a/sleekxmpp/stanza/error.py +++ b/sleekxmpp/stanza/error.py @@ -6,8 +6,7 @@ See the file LICENSE for copying permission. """ -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin -from sleekxmpp.xmlstream.stanzabase import ElementBase, ET +from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin class Error(ElementBase): @@ -40,13 +39,13 @@ class Error(ElementBase): should be treated. Methods: - setup -- Overrides ElementBase.setup. - getCondition -- Retrieve the name of the condition element. - setCondition -- Add a condition element. - delCondition -- Remove the condition element. - getText -- Retrieve the contents of the <text> element. - setText -- Set the contents of the <text> element. - delText -- Remove the <text> element. + setup -- Overrides ElementBase.setup. + get_condition -- Retrieve the name of the condition element. + set_condition -- Add a condition element. + del_condition -- Remove the condition element. + get_text -- Retrieve the contents of the <text> element. + set_text -- Set the contents of the <text> element. + del_text -- Remove the <text> element. """ namespace = 'jabber:client' @@ -78,6 +77,15 @@ class Error(ElementBase): Arguments: xml -- Use an existing XML object for the stanza's values. """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.getCondition = self.get_condition + self.setCondition = self.set_condition + self.delCondition = self.del_condition + self.getText = self.get_text + self.setText = self.set_text + self.delText = self.del_text + if ElementBase.setup(self, xml): #If we had to generate XML then set default values. self['type'] = 'cancel' @@ -85,14 +93,14 @@ class Error(ElementBase): if self.parent is not None: self.parent()['type'] = 'error' - def getCondition(self): + def get_condition(self): """Return the condition element's name.""" for child in self.xml.getchildren(): if "{%s}" % self.condition_ns in child.tag: return child.tag.split('}', 1)[-1] return '' - def setCondition(self, value): + def set_condition(self, value): """ Set the tag name of the condition element. @@ -104,7 +112,7 @@ class Error(ElementBase): self.xml.append(ET.Element("{%s}%s" % (self.condition_ns, value))) return self - def delCondition(self): + def del_condition(self): """Remove the condition element.""" for child in self.xml.getchildren(): if "{%s}" % self.condition_ns in child.tag: @@ -113,21 +121,21 @@ class Error(ElementBase): self.xml.remove(child) return self - def getText(self): + def get_text(self): """Retrieve the contents of the <text> element.""" - return self._getSubText('{%s}text' % self.condition_ns) + return self._get_sub_text('{%s}text' % self.condition_ns) - def setText(self, value): + def set_text(self, value): """ Set the contents of the <text> element. Arguments: value -- The new contents for the <text> element. """ - self._setSubText('{%s}text' % self.condition_ns, text=value) + self._set_sub_text('{%s}text' % self.condition_ns, text=value) return self - def delText(self): + def del_text(self): """Remove the <text> element.""" - self._delSub('{%s}text' % self.condition_ns) + self._del_sub('{%s}text' % self.condition_ns) return self diff --git a/sleekxmpp/stanza/htmlim.py b/sleekxmpp/stanza/htmlim.py index c2f2f0c8..45868287 100644 --- a/sleekxmpp/stanza/htmlim.py +++ b/sleekxmpp/stanza/htmlim.py @@ -7,8 +7,7 @@ """ from sleekxmpp.stanza import Message -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin -from sleekxmpp.xmlstream.stanzabase import ElementBase, ET +from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin class HTMLIM(ElementBase): @@ -36,9 +35,10 @@ class HTMLIM(ElementBase): body -- The contents of the HTML body tag. Methods: - getBody -- Return the HTML body contents. - setBody -- Set the HTML body contents. - delBody -- Remove the HTML body contents. + setup -- Overrides ElementBase.setup. + get_body -- Return the HTML body contents. + set_body -- Set the HTML body contents. + del_body -- Remove the HTML body contents. """ namespace = 'http://jabber.org/protocol/xhtml-im' @@ -46,7 +46,24 @@ class HTMLIM(ElementBase): interfaces = set(('body',)) plugin_attrib = name - def setBody(self, html): + def setup(self, xml=None): + """ + Populate the stanza object using an optional XML object. + + Overrides StanzaBase.setup. + + Arguments: + xml -- Use an existing XML object for the stanza's values. + """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setBody = self.set_body + self.getBody = self.get_body + self.delBody = self.del_body + + return ElementBase.setup(self, xml) + + def set_body(self, html): """ Set the contents of the HTML body. @@ -64,17 +81,17 @@ class HTMLIM(ElementBase): else: self.xml.append(html) - def getBody(self): + def get_body(self): """Return the contents of the HTML body.""" html = self.xml.find('{http://www.w3.org/1999/xhtml}body') if html is None: return '' return html - def delBody(self): + def del_body(self): """Remove the HTML body contents.""" if self.parent is not None: self.parent().xml.remove(self.xml) -registerStanzaPlugin(Message, HTMLIM) +register_stanza_plugin(Message, HTMLIM) diff --git a/sleekxmpp/stanza/iq.py b/sleekxmpp/stanza/iq.py index c5ef8bb4..614d14f5 100644 --- a/sleekxmpp/stanza/iq.py +++ b/sleekxmpp/stanza/iq.py @@ -8,8 +8,7 @@ from sleekxmpp.stanza import Error from sleekxmpp.stanza.rootstanza import RootStanza -from sleekxmpp.xmlstream import RESPONSE_TIMEOUT -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET +from sleekxmpp.xmlstream import RESPONSE_TIMEOUT, StanzaBase, ET from sleekxmpp.xmlstream.handler import Waiter from sleekxmpp.xmlstream.matcher import MatcherId @@ -53,14 +52,14 @@ class Iq(RootStanza): types -- May be one of: get, set, result, or error. Methods: - __init__ -- Overrides StanzaBase.__init__. - unhandled -- Send error if there are no handlers. - setPayload -- Overrides StanzaBase.setPayload. - setQuery -- Add or modify a <query> element. - getQuery -- Return the namespace of the <query> element. - delQuery -- Remove the <query> element. - reply -- Overrides StanzaBase.reply - send -- Overrides StanzaBase.send + __init__ -- Overrides StanzaBase.__init__. + unhandled -- Send error if there are no handlers. + set_payload -- Overrides StanzaBase.set_payload. + set_query -- Add or modify a <query> element. + get_query -- Return the namespace of the <query> element. + del_query -- Remove the <query> element. + reply -- Overrides StanzaBase.reply + send -- Overrides StanzaBase.send """ namespace = 'jabber:client' @@ -76,6 +75,13 @@ class Iq(RootStanza): Overrides StanzaBase.__init__. """ StanzaBase.__init__(self, *args, **kwargs) + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setPayload = self.set_payload + self.getQuery = self.get_query + self.setQuery = self.set_query + self.delQuery = self.del_query + if self['id'] == '': if self.stream is not None: self['id'] = self.stream.getNewId() @@ -94,7 +100,7 @@ class Iq(RootStanza): self['error']['text'] = 'No handlers registered for this request.' self.send() - def setPayload(self, value): + def set_payload(self, value): """ Set the XML contents of the <iq> stanza. @@ -102,10 +108,10 @@ class Iq(RootStanza): value -- An XML object to use as the <iq> stanza's contents """ self.clear() - StanzaBase.setPayload(self, value) + StanzaBase.set_payload(self, value) return self - def setQuery(self, value): + def set_query(self, value): """ Add or modify a <query> element. @@ -121,7 +127,7 @@ class Iq(RootStanza): self.xml.append(query) return self - def getQuery(self): + def get_query(self): """Return the namespace of the <query> element.""" for child in self.xml.getchildren(): if child.tag.endswith('query'): @@ -131,7 +137,7 @@ class Iq(RootStanza): return ns return '' - def delQuery(self): + def del_query(self): """Remove the <query> element.""" for child in self.xml.getchildren(): if child.tag.endswith('query'): diff --git a/sleekxmpp/stanza/message.py b/sleekxmpp/stanza/message.py index 560e1d47..66c74d8a 100644 --- a/sleekxmpp/stanza/message.py +++ b/sleekxmpp/stanza/message.py @@ -8,7 +8,7 @@ from sleekxmpp.stanza import Error from sleekxmpp.stanza.rootstanza import RootStanza -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET +from sleekxmpp.xmlstream import StanzaBase, ET class Message(RootStanza): @@ -42,16 +42,17 @@ class Message(RootStanza): types -- May be one of: normal, chat, headline, groupchat, or error. Methods: - chat -- Set the message type to 'chat'. - normal -- Set the message type to 'normal'. - reply -- Overrides StanzaBase.reply - getType -- Overrides StanzaBase interface - getMucroom -- Return the name of the MUC room of the message. - setMucroom -- Dummy method to prevent assignment. - delMucroom -- Dummy method to prevent deletion. - getMucnick -- Return the MUC nickname of the message's sender. - setMucnick -- Dummy method to prevent assignment. - delMucnick -- Dummy method to prevent deletion. + setup -- Overrides StanzaBase.setup. + chat -- Set the message type to 'chat'. + normal -- Set the message type to 'normal'. + reply -- Overrides StanzaBase.reply + get_type -- Overrides StanzaBase interface + get_mucroom -- Return the name of the MUC room of the message. + set_mucroom -- Dummy method to prevent assignment. + del_mucroom -- Dummy method to prevent deletion. + get_mucnick -- Return the MUC nickname of the message's sender. + set_mucnick -- Dummy method to prevent assignment. + del_mucnick -- Dummy method to prevent deletion. """ namespace = 'jabber:client' @@ -62,7 +63,28 @@ class Message(RootStanza): plugin_attrib = name types = set((None, 'normal', 'chat', 'headline', 'error', 'groupchat')) - def getType(self): + def setup(self, xml=None): + """ + Populate the stanza object using an optional XML object. + + Overrides StanzaBase.setup. + + Arguments: + xml -- Use an existing XML object for the stanza's values. + """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.getType = self.get_type + self.getMucroom = self.get_mucroom + self.setMucroom = self.set_mucroom + self.delMucroom = self.del_mucroom + self.getMucnick = self.get_mucnick + self.setMucnick = self.set_mucnick + self.delMucnick = self.del_mucnick + + return StanzaBase.setup(self, xml) + + def get_type(self): """ Return the message type. @@ -70,7 +92,7 @@ class Message(RootStanza): Returns 'normal' if no type attribute is present. """ - return self._getAttr('type', 'normal') + return self._get_attr('type', 'normal') def chat(self): """Set the message type to 'chat'.""" @@ -104,7 +126,7 @@ class Message(RootStanza): self['body'] = body return self - def getMucroom(self): + def get_mucroom(self): """ Return the name of the MUC room where the message originated. @@ -115,7 +137,7 @@ class Message(RootStanza): else: return '' - def getMucnick(self): + def get_mucnick(self): """ Return the nickname of the MUC user that sent the message. @@ -126,18 +148,18 @@ class Message(RootStanza): else: return '' - def setMucroom(self, value): + def set_mucroom(self, value): """Dummy method to prevent modification.""" pass - def delMucroom(self): + def del_mucroom(self): """Dummy method to prevent deletion.""" pass - def setMucnick(self, value): + def set_mucnick(self, value): """Dummy method to prevent modification.""" pass - def delMucnick(self): + def del_mucnick(self): """Dummy method to prevent deletion.""" pass diff --git a/sleekxmpp/stanza/nick.py b/sleekxmpp/stanza/nick.py index de54b307..a9243d1a 100644 --- a/sleekxmpp/stanza/nick.py +++ b/sleekxmpp/stanza/nick.py @@ -7,8 +7,7 @@ """ from sleekxmpp.stanza import Message, Presence -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin -from sleekxmpp.xmlstream.stanzabase import ElementBase, ET +from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin class Nick(ElementBase): @@ -39,9 +38,10 @@ class Nick(ElementBase): nick -- A global, friendly or informal name chosen by a user. Methods: - getNick -- Return the nickname in the <nick> element. - setNick -- Add a <nick> element with the given nickname. - delNick -- Remove the <nick> element. + setup -- Overrides ElementBase.setup. + get_nick -- Return the nickname in the <nick> element. + set_nick -- Add a <nick> element with the given nickname. + del_nick -- Remove the <nick> element. """ namespace = 'http://jabber.org/nick/nick' @@ -49,7 +49,24 @@ class Nick(ElementBase): plugin_attrib = name interfaces = set(('nick',)) - def setNick(self, nick): + def setup(self, xml=None): + """ + Populate the stanza object using an optional XML object. + + Overrides StanzaBase.setup. + + Arguments: + xml -- Use an existing XML object for the stanza's values. + """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setNick = self.set_nick + self.getNick = self.get_nick + self.delNick = self.del_nick + + return ElementBase.setup(self, xml) + + def set_nick(self, nick): """ Add a <nick> element with the given nickname. @@ -58,15 +75,15 @@ class Nick(ElementBase): """ self.xml.text = nick - def getNick(self): + def get_nick(self): """Return the nickname in the <nick> element.""" return self.xml.text - def delNick(self): + def del_nick(self): """Remove the <nick> element.""" if self.parent is not None: self.parent().xml.remove(self.xml) -registerStanzaPlugin(Message, Nick) -registerStanzaPlugin(Presence, Nick) +register_stanza_plugin(Message, Nick) +register_stanza_plugin(Presence, Nick) diff --git a/sleekxmpp/stanza/presence.py b/sleekxmpp/stanza/presence.py index cb957221..964ef11a 100644 --- a/sleekxmpp/stanza/presence.py +++ b/sleekxmpp/stanza/presence.py @@ -8,7 +8,7 @@ from sleekxmpp.stanza import Error from sleekxmpp.stanza.rootstanza import RootStanza -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET +from sleekxmpp.xmlstream import StanzaBase, ET class Presence(RootStanza): @@ -52,12 +52,13 @@ class Presence(RootStanza): showtypes -- One of: away, chat, dnd, and xa. Methods: - reply -- Overrides StanzaBase.reply - setShow -- Set the value of the <show> element. - getType -- Get the value of the type attribute or <show> element. - setType -- Set the value of the type attribute or <show> element. - getPriority -- Get the value of the <priority> element. - setPriority -- Set the value of the <priority> element. + setup -- Overrides StanzaBase.setup + reply -- Overrides StanzaBase.reply + set_show -- Set the value of the <show> element. + get_type -- Get the value of the type attribute or <show> element. + set_type -- Set the value of the type attribute or <show> element. + get_priority -- Get the value of the <priority> element. + set_priority -- Set the value of the <priority> element. """ namespace = 'jabber:client' @@ -71,7 +72,27 @@ class Presence(RootStanza): 'subscribed', 'unsubscribe', 'unsubscribed')) showtypes = set(('dnd', 'chat', 'xa', 'away')) - def setShow(self, show): + def setup(self, xml=None): + """ + Populate the stanza object using an optional XML object. + + Overrides ElementBase.setup. + + Arguments: + xml -- Use an existing XML object for the stanza's values. + """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setShow = self.set_show + self.getType = self.get_type + self.setType = self.set_type + self.delType = self.get_type + self.getPriority = self.get_priority + self.setPriority = self.set_priority + + return StanzaBase.setup(self, xml) + + def set_show(self, show): """ Set the value of the <show> element. @@ -79,12 +100,24 @@ class Presence(RootStanza): show -- Must be one of: away, chat, dnd, or xa. """ if show is None: - self._delSub('show') + self._del_sub('show') elif show in self.showtypes: - self._setSubText('show', text=show) + self._set_sub_text('show', text=show) return self - def setType(self, value): + def get_type(self): + """ + Return the value of the <presence> stanza's type attribute, or + the value of the <show> element. + """ + out = self._get_attr('type') + if not out: + out = self['show'] + if not out or out is None: + out = 'available' + return out + + def set_type(self, value): """ Set the type attribute's value, and the <show> element if applicable. @@ -96,19 +129,19 @@ class Presence(RootStanza): self['show'] = None if value == 'available': value = '' - self._setAttr('type', value) + self._set_attr('type', value) elif value in self.showtypes: self['show'] = value return self - def delType(self): + def del_type(self): """ Remove both the type attribute and the <show> element. """ - self._delAttr('type') - self._delSub('show') + self._del_attr('type') + self._del_sub('show') - def setPriority(self, value): + def set_priority(self, value): """ Set the entity's priority value. Some server use priority to determine message routing behavior. @@ -119,13 +152,13 @@ class Presence(RootStanza): Arguments: value -- An integer value greater than or equal to 0. """ - self._setSubText('priority', text=str(value)) + self._set_sub_text('priority', text=str(value)) - def getPriority(self): + def get_priority(self): """ Return the value of the <presence> element as an integer. """ - p = self._getSubText('priority') + p = self._get_sub_text('priority') if not p: p = 0 try: @@ -134,18 +167,6 @@ class Presence(RootStanza): # The priority is not a number: we consider it 0 as a default return 0 - def getType(self): - """ - Return the value of the <presence> stanza's type attribute, or - the value of the <show> element. - """ - out = self._getAttr('type') - if not out: - out = self['show'] - if not out or out is None: - out = 'available' - return out - def reply(self): """ Set the appropriate presence reply type. diff --git a/sleekxmpp/stanza/rootstanza.py b/sleekxmpp/stanza/rootstanza.py index eafc79a2..2677ea91 100644 --- a/sleekxmpp/stanza/rootstanza.py +++ b/sleekxmpp/stanza/rootstanza.py @@ -12,7 +12,7 @@ import sys from sleekxmpp.exceptions import XMPPError from sleekxmpp.stanza import Error -from sleekxmpp.xmlstream.stanzabase import ET, StanzaBase, registerStanzaPlugin +from sleekxmpp.xmlstream import ET, StanzaBase, register_stanza_plugin class RootStanza(StanzaBase): @@ -63,4 +63,4 @@ class RootStanza(StanzaBase): self.send() -registerStanzaPlugin(RootStanza, Error) +register_stanza_plugin(RootStanza, Error) diff --git a/sleekxmpp/stanza/roster.py b/sleekxmpp/stanza/roster.py index 292c8956..8f154a22 100644 --- a/sleekxmpp/stanza/roster.py +++ b/sleekxmpp/stanza/roster.py @@ -8,8 +8,7 @@ from sleekxmpp.stanza import Iq from sleekxmpp.xmlstream import JID -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin -from sleekxmpp.xmlstream.stanzabase import ET, ElementBase +from sleekxmpp.xmlstream import ET, ElementBase, register_stanza_plugin class Roster(ElementBase): @@ -29,9 +28,9 @@ class Roster(ElementBase): in the stanza. Methods: - getItems -- Return a dictionary of roster entries. - setItems -- Add <item> elements. - delItems -- Remove all <item> elements. + get_items -- Return a dictionary of roster entries. + set_items -- Add <item> elements. + del_items -- Remove all <item> elements. """ namespace = 'jabber:iq:roster' @@ -39,7 +38,24 @@ class Roster(ElementBase): plugin_attrib = 'roster' interfaces = set(('items',)) - def setItems(self, items): + def setup(self, xml=None): + """ + Populate the stanza object using an optional XML object. + + Overrides StanzaBase.setup. + + Arguments: + xml -- Use an existing XML object for the stanza's values. + """ + # To comply with PEP8, method names now use underscores. + # Deprecated method names are re-mapped for backwards compatibility. + self.setItems = self.set_items + self.getItems = self.get_items + self.delItems = self.del_items + + return ElementBase.setup(self, xml) + + def set_items(self, items): """ Set the roster entries in the <roster> stanza. @@ -54,7 +70,7 @@ class Roster(ElementBase): Arguments: items -- A dictionary of roster entries. """ - self.delItems() + self.del_items() for jid in items: ijid = str(jid) item = ET.Element('{jabber:iq:roster}item', {'jid': ijid}) @@ -72,7 +88,7 @@ class Roster(ElementBase): self.xml.append(item) return self - def getItems(self): + def get_items(self): """ Return a dictionary of roster entries. @@ -98,7 +114,7 @@ class Roster(ElementBase): items[itemxml.get('jid')] = item return items - def delItems(self): + def del_items(self): """ Remove all <item> elements from the roster stanza. """ @@ -106,4 +122,4 @@ class Roster(ElementBase): self.xml.remove(child) -registerStanzaPlugin(Iq, Roster) +register_stanza_plugin(Iq, Roster) diff --git a/sleekxmpp/test/sleektest.py b/sleekxmpp/test/sleektest.py index efe81212..8a7caa00 100644 --- a/sleekxmpp/test/sleektest.py +++ b/sleekxmpp/test/sleektest.py @@ -13,8 +13,7 @@ import sleekxmpp from sleekxmpp import ClientXMPP, ComponentXMPP from sleekxmpp.stanza import Message, Iq, Presence from sleekxmpp.test import TestSocket, TestLiveSocket -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin, ET -from sleekxmpp.xmlstream.stanzabase import StanzaBase +from sleekxmpp.xmlstream import StanzaBase, ET, register_stanza_plugin from sleekxmpp.xmlstream.tostring import tostring diff --git a/sleekxmpp/xmlstream/__init__.py b/sleekxmpp/xmlstream/__init__.py index 981f052d..67b20c56 100644 --- a/sleekxmpp/xmlstream/__init__.py +++ b/sleekxmpp/xmlstream/__init__.py @@ -9,6 +9,7 @@ from sleekxmpp.xmlstream.jid import JID from sleekxmpp.xmlstream.scheduler import Scheduler from sleekxmpp.xmlstream.stanzabase import StanzaBase, ElementBase, ET +from sleekxmpp.xmlstream.stanzabase import register_stanza_plugin from sleekxmpp.xmlstream.tostring import tostring from sleekxmpp.xmlstream.xmlstream import XMLStream, RESPONSE_TIMEOUT from sleekxmpp.xmlstream.xmlstream import RestartStream 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 diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 0388c5aa..4c3dd9fe 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -383,7 +383,7 @@ class XMLStream(object): one that appears as a direct child of the stream's root element. Stanzas that appear as substanzas of a root stanza do not need to - be registered here. That is done using registerStanzaPlugin() from + be registered here. That is done using register_stanza_plugin() from sleekxmpp.xmlstream.stanzabase. Stanzas that are not registered will not be converted into |