diff options
-rwxr-xr-x | setup.py | 1 | ||||
-rw-r--r-- | sleekxmpp/basexmpp.py | 1 | ||||
-rw-r--r-- | sleekxmpp/plugins/__init__.py | 1 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0071/__init__.py | 15 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0071/stanza.py | 73 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0071/xhtml_im.py | 30 | ||||
-rw-r--r-- | sleekxmpp/stanza/htmlim.py | 71 |
7 files changed, 123 insertions, 69 deletions
@@ -75,6 +75,7 @@ packages = [ 'sleekxmpp', 'sleekxmpp/plugins/xep_0060', 'sleekxmpp/plugins/xep_0060/stanza', 'sleekxmpp/plugins/xep_0066', + 'sleekxmpp/plugins/xep_0071', 'sleekxmpp/plugins/xep_0077', 'sleekxmpp/plugins/xep_0078', 'sleekxmpp/plugins/xep_0080', diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index c3ff5ba3..a54e4bb6 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -201,7 +201,6 @@ class BaseXMPP(XMLStream): # Initialize a few default stanza plugins. register_stanza_plugin(Iq, Roster) register_stanza_plugin(Message, Nick) - register_stanza_plugin(Message, HTMLIM) def start_stream_handler(self, xml): """Save the stream ID once the streams have been established. diff --git a/sleekxmpp/plugins/__init__.py b/sleekxmpp/plugins/__init__.py index 4ff53ac2..b1a73d9c 100644 --- a/sleekxmpp/plugins/__init__.py +++ b/sleekxmpp/plugins/__init__.py @@ -32,6 +32,7 @@ __all__ = [ 'xep_0059', # Result Set Management 'xep_0060', # Pubsub (Client) 'xep_0066', # Out of Band Data + 'xep_0071', # XHTML-IM 'xep_0077', # In-Band Registration # 'xep_0078', # Non-SASL auth. Don't automatically load 'xep_0080', # User Location diff --git a/sleekxmpp/plugins/xep_0071/__init__.py b/sleekxmpp/plugins/xep_0071/__init__.py new file mode 100644 index 00000000..c21e9265 --- /dev/null +++ b/sleekxmpp/plugins/xep_0071/__init__.py @@ -0,0 +1,15 @@ +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout + This file is part of SleekXMPP. + + See the file LICENSE for copying permissio +""" + +from sleekxmpp.plugins.base import register_plugin + +from sleekxmpp.plugins.xep_0071.stanza import XHTML_IM +from sleekxmpp.plugins.xep_0071.xhtml_im import XEP_0071 + + +register_plugin(XEP_0071) diff --git a/sleekxmpp/plugins/xep_0071/stanza.py b/sleekxmpp/plugins/xep_0071/stanza.py new file mode 100644 index 00000000..77957541 --- /dev/null +++ b/sleekxmpp/plugins/xep_0071/stanza.py @@ -0,0 +1,73 @@ +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2012 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +from sleekxmpp.stanza import Message +from sleekxmpp.thirdparty import OrderedDict +from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin, tostring + + +XHTML_NS = 'http://www.w3.org/1999/xhtml' + + +class XHTML_IM(ElementBase): + + namespace = 'http://jabber.org/protocol/xhtml-im' + name = 'html' + interfaces = set(['body']) + lang_interfaces = set(['body']) + plugin_attrib = name + + def set_body(self, content, lang=None): + if lang is None: + lang = self.get_lang() + self.del_body(lang) + content = str(content) + header = '<body xmlns="%s"' % XHTML_NS + if lang: + header = '%s xml:lang="%s"' % (header, lang) + content = '%s>%s</body>' % (header, content) + xhtml = ET.fromstring(content) + self.xml.append(xhtml) + + def get_body(self, lang=None): + """Return the contents of the HTML body.""" + if lang is None: + lang = self.get_lang() + + bodies = self.xml.findall('{%s}body' % XHTML_NS) + + if lang == '*': + result = OrderedDict() + for body in bodies: + body_lang = body.attrib.get('{%s}lang' % self.xml_ns, '') + body_result = [] + body_result.append(body.text if body.text else '') + for child in body: + body_result.append(tostring(child, xmlns=XHTML_NS)) + body_result.append(body.tail if body.tail else '') + result[body_lang] = ''.join(body_result) + return result + else: + for body in bodies: + if body.attrib.get('{%s}lang' % self.xml_ns, self.get_lang()) == lang: + result = [] + result.append(body.text if body.text else '') + for child in body: + result.append(tostring(child, xmlns=XHTML_NS)) + result.append(body.tail if body.tail else '') + return ''.join(result) + return '' + + def del_body(self, lang): + if lang is None: + lang = self.get_lang() + bodies = self.xml.findall('{%s}body' % XHTML_NS) + for body in bodies: + if body.attrib.get('{%s}lang' % self.xml_ns, self.get_lang()) == lang: + self.xml.remove(body) + return diff --git a/sleekxmpp/plugins/xep_0071/xhtml_im.py b/sleekxmpp/plugins/xep_0071/xhtml_im.py new file mode 100644 index 00000000..096a00aa --- /dev/null +++ b/sleekxmpp/plugins/xep_0071/xhtml_im.py @@ -0,0 +1,30 @@ +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + + +from sleekxmpp.stanza import Message +from sleekxmpp.plugins import BasePlugin +from sleekxmpp.xmlstream import register_stanza_plugin +from sleekxmpp.plugins.xep_0071 import stanza, XHTML_IM + + +class XEP_0071(BasePlugin): + + name = 'xep_0071' + description = 'XEP-0071: XHTML-IM' + dependencies = set(['xep_0030']) + stanza = stanza + + def plugin_init(self): + register_stanza_plugin(Message, XHTML_IM) + + def session_bind(self, jid): + self.xmpp['xep_0030'].add_feature(feature=XHTML_IM.namespace) + + def plugin_end(self): + self.xmpp['xep_0030'].del_feature(feature=XHTML_IM.namespace) diff --git a/sleekxmpp/stanza/htmlim.py b/sleekxmpp/stanza/htmlim.py index d21a74e1..c43178f2 100644 --- a/sleekxmpp/stanza/htmlim.py +++ b/sleekxmpp/stanza/htmlim.py @@ -7,78 +7,13 @@ """ from sleekxmpp.stanza import Message -from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin - - -class HTMLIM(ElementBase): - - """ - XEP-0071: XHTML-IM defines a method for embedding XHTML content - within a <message> stanza so that lightweight markup can be used - to format the message contents and to create links. - - Only a subset of XHTML is recommended for use with XHTML-IM. - See the full spec at 'http://xmpp.org/extensions/xep-0071.html' - for more information. - - Example stanza: - <message to="user@example.com"> - <body>Non-html message content.</body> - <html xmlns="http://jabber.org/protocol/xhtml-im"> - <body xmlns="http://www.w3.org/1999/xhtml"> - <p><b>HTML!</b></p> - </body> - </html> - </message> - - Stanza Interface: - body -- The contents of the HTML body tag. - - Methods: - 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' - name = 'html' - interfaces = set(('body',)) - plugin_attrib = name - - def set_body(self, html): - """ - Set the contents of the HTML body. - - Arguments: - html -- Either a string or XML object. If the top level - element is not <body> with a namespace of - 'http://www.w3.org/1999/xhtml', it will be wrapped. - """ - if isinstance(html, str): - html = ET.XML(html) - if html.tag != '{http://www.w3.org/1999/xhtml}body': - body = ET.Element('{http://www.w3.org/1999/xhtml}body') - body.append(html) - self.xml.append(body) - else: - self.xml.append(html) - - 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 del_body(self): - """Remove the HTML body contents.""" - if self.parent is not None: - self.parent().xml.remove(self.xml) +from sleekxmpp.xmlstream import register_stanza_plugin +from sleekxmpp.plugins.xep_0071 import XHTML_IM as HTMLIM register_stanza_plugin(Message, HTMLIM) + # To comply with PEP8, method names now use underscores. # Deprecated method names are re-mapped for backwards compatibility. HTMLIM.setBody = HTMLIM.set_body |