Mercurial > libervia-backend
annotate src/plugins/plugin_xep_0071.py @ 2160:e67e8cd24141
core (tools/common): data objects first draft:
this module aims is to help manipulate complex data from bridge, mainly for the template system.
It is in common and not only in frontends as it may be used in some case by backend, if it needs to use template system in the future.
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 21 Feb 2017 21:01:40 +0100 |
parents | 33c8c4973743 |
children | 8b37a62336c3 |
rev | line source |
---|---|
1934
2daf7b4c6756
use of /usr/bin/env instead of /usr/bin/python in shebang
Goffi <goffi@goffi.org>
parents:
1813
diff
changeset
|
1 #!/usr/bin/env python2 |
668 | 2 # -*- coding: utf-8 -*- |
3 | |
4 # SAT plugin for Publish-Subscribe (xep-0071) | |
1766 | 5 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) |
668 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
771 | 20 from sat.core.i18n import _ |
1963
a2bc5089c2eb
backend, frontends: message refactoring (huge commit):
Goffi <goffi@goffi.org>
parents:
1955
diff
changeset
|
21 from sat.core.constants import Const as C |
832
c4b22aedb7d7
plugin groupblog, XEP-0071, XEP-0277, text_syntaxes: manage raw/rich/xhtml data for content/title:
souliane <souliane@mailoo.org>
parents:
811
diff
changeset
|
22 from sat.core import exceptions |
993
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
922
diff
changeset
|
23 from sat.core.log import getLogger |
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
922
diff
changeset
|
24 log = getLogger(__name__) |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
25 from sat.tools.common import data_format |
668 | 26 |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
27 from twisted.internet import defer |
993
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
922
diff
changeset
|
28 from wokkel import disco, iwokkel |
668 | 29 from zope.interface import implements |
30 # from lxml import etree | |
1542
94901070478e
plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
31 try: |
94901070478e
plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
32 from lxml import html |
94901070478e
plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
33 except ImportError: |
94901070478e
plugins: added new MissingModule exceptions to plugins using third party modules
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
34 raise exceptions.MissingModule(u"Missing module lxml, please download/install it from http://lxml.de/") |
668 | 35 try: |
36 from twisted.words.protocols.xmlstream import XMPPHandler | |
37 except ImportError: | |
38 from wokkel.subprotocols import XMPPHandler | |
39 | |
40 NS_XHTML_IM = 'http://jabber.org/protocol/xhtml-im' | |
41 NS_XHTML = 'http://www.w3.org/1999/xhtml' | |
42 | |
43 PLUGIN_INFO = { | |
2145
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
44 C.PI_NAME: "XHTML-IM Plugin", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
45 C.PI_IMPORT_NAME: "XEP-0071", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
46 C.PI_TYPE: "XEP", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
47 C.PI_PROTOCOLS: ["XEP-0071"], |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
48 C.PI_DEPENDENCIES: ["TEXT-SYNTAXES"], |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
49 C.PI_MAIN: "XEP_0071", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
50 C.PI_HANDLER: "yes", |
33c8c4973743
core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents:
2144
diff
changeset
|
51 C.PI_DESCRIPTION: _("""Implementation of XHTML-IM""") |
668 | 52 } |
53 | |
54 allowed = { | |
55 "a": set(["href", "style", "type"]), | |
56 "blockquote": set(["style"]), | |
57 "body": set(["style"]), | |
58 "br": set([]), | |
59 "cite": set(["style"]), | |
60 "em": set([]), | |
61 "img": set(["alt", "height", "src", "style", "width"]), | |
62 "li": set(["style"]), | |
63 "ol": set(["style"]), | |
64 "p": set(["style"]), | |
65 "span": set(["style"]), | |
66 "strong": set([]), | |
67 "ul": set(["style"]), | |
68 } | |
69 | |
70 styles_allowed = ["background-color", "color", "font-family", "font-size", "font-style", "font-weight", "margin-left", "margin-right", "text-align", "text-decoration"] | |
71 | |
72 blacklist = ['script'] # tag that we have to kill (we don't keep content) | |
73 | |
74 | |
75 class XEP_0071(object): | |
76 SYNTAX_XHTML_IM = "XHTML-IM" | |
77 | |
78 def __init__(self, host): | |
993
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
922
diff
changeset
|
79 log.info(_("XHTML-IM plugin initialization")) |
668 | 80 self.host = host |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
81 self._s = self.host.plugins["TEXT-SYNTAXES"] |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
82 self._s.addSyntax(self.SYNTAX_XHTML_IM, lambda xhtml: xhtml, self.XHTML2XHTML_IM, [self._s.OPT_HIDDEN]) |
668 | 83 host.trigger.add("MessageReceived", self.messageReceivedTrigger) |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
84 host.trigger.add("sendMessage", self.sendMessageTrigger) |
668 | 85 |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
86 def getHandler(self, client): |
668 | 87 return XEP_0071_handler(self) |
88 | |
2110
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
89 def _messagePostTreat(self, data, message_elt, body_elts, client): |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
90 """Callback which manage the post treatment of the message in case of XHTML-IM found |
2110
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
91 |
668 | 92 @param data: data send by MessageReceived trigger through post_treat deferred |
2110
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
93 @param message_elt: whole <message> stanza |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
94 @param body_elts: XHTML-IM body elements found |
668 | 95 @return: the data with the extra parameter updated |
96 """ | |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
97 # TODO: check if text only body is empty, then try to convert XHTML-IM to pure text and show a warning message |
1963
a2bc5089c2eb
backend, frontends: message refactoring (huge commit):
Goffi <goffi@goffi.org>
parents:
1955
diff
changeset
|
98 def converted(xhtml, lang): |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
99 if lang: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
100 data['extra']['xhtml_{}'.format(lang)] = xhtml |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
101 else: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
102 data['extra']['xhtml'] = xhtml |
668 | 103 |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
104 defers = [] |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
105 for body_elt in body_elts: |
1963
a2bc5089c2eb
backend, frontends: message refactoring (huge commit):
Goffi <goffi@goffi.org>
parents:
1955
diff
changeset
|
106 lang = body_elt.getAttribute((C.NS_XML, 'lang'), '') |
2110
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
107 treat_d = defer.succeed(None) # deferred used for treatments |
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
108 if self.host.trigger.point("xhtml_post_treat", client, message_elt, body_elt, lang, treat_d): |
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
109 continue |
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
110 treat_d.addCallback(lambda dummy: self._s.convert(body_elt.toXml(), self.SYNTAX_XHTML_IM, safe=True)) |
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
111 treat_d.addCallback(converted, lang) |
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
112 defers.append(treat_d) |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
113 |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
114 d_list = defer.DeferredList(defers) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
115 d_list.addCallback(lambda dummy: data) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
116 return d_list |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
117 |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
118 def _fill_body_text(self, text, data, lang): |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
119 data['message'][lang or ''] = text |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
120 message_elt = data['xml'] |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
121 body_elt = message_elt.addElement("body", content=text) |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
122 if lang: |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
123 body_elt[(C.NS_XML, 'lang')] = lang |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
124 |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
125 def _check_body_text(self, data, lang, markup, syntax, defers): |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
126 """check if simple text message exists, and fill if needed""" |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
127 if not (lang or '') in data['message']: |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
128 d = self._s.convert(markup, syntax, self._s.SYNTAX_TEXT) |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
129 d.addCallback(self._fill_body_text, data, lang) |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
130 defers.append(d) |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
131 |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
132 def _sendMessageAddRich(self, data, client): |
702
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
133 """ Construct XHTML-IM node and add it XML element |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
134 |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
135 @param data: message data as sended by sendMessage callback |
702
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
136 """ |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
137 # at this point, either ['extra']['rich'] or ['extra']['xhtml'] exists |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
138 # but both can't exist at the same time |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
139 message_elt = data['xml'] |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
140 html_elt = message_elt.addElement((NS_XHTML_IM, 'html')) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
141 |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
142 def syntax_converted(xhtml_im, lang): |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
143 body_elt = html_elt.addElement((NS_XHTML, 'body')) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
144 if lang: |
1963
a2bc5089c2eb
backend, frontends: message refactoring (huge commit):
Goffi <goffi@goffi.org>
parents:
1955
diff
changeset
|
145 body_elt[(C.NS_XML, 'lang')] = lang |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
146 data['extra']['xhtml_{}'.format(lang)] = xhtml_im |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
147 else: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
148 data['extra']['xhtml'] = xhtml_im |
702
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
149 body_elt.addRawXml(xhtml_im) |
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
150 |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
151 syntax = self._s.getCurrentSyntax(client.profile) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
152 defers = [] |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
153 if u'xhtml' in data['extra']: |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
154 # we have directly XHTML |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
155 for lang, xhtml in data_format.getSubDict('xhtml', data['extra']): |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
156 self._check_body_text(data, lang, xhtml, self._s.SYNTAX_XHTML, defers) |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
157 d = self._s.convert(xhtml, self._s.SYNTAX_XHTML, self.SYNTAX_XHTML_IM) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
158 d.addCallback(syntax_converted, lang) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
159 defers.append(d) |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
160 elif u'rich' in data['extra']: |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
161 # we have rich syntax to convert |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
162 for lang, rich_data in data_format.getSubDict('rich', data['extra']): |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
163 self._check_body_text(data, lang, rich_data, syntax, defers) |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
164 d = self._s.convert(rich_data, syntax, self.SYNTAX_XHTML_IM) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
165 d.addCallback(syntax_converted, lang) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
166 defers.append(d) |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
167 else: |
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
168 exceptions.InternalError(u"xhtml or rich should be present at this point") |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
169 d_list = defer.DeferredList(defers) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
170 d_list.addCallback(lambda dummy: data) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
171 return d_list |
702
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
172 |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
173 def messageReceivedTrigger(self, client, message, post_treat): |
668 | 174 """ Check presence of XHTML-IM in message |
175 """ | |
176 try: | |
177 html_elt = message.elements(NS_XHTML_IM, 'html').next() | |
178 except StopIteration: | |
179 # No XHTML-IM | |
180 pass | |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
181 else: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
182 body_elts = html_elt.elements(NS_XHTML, 'body') |
2110
2d633b3c923d
plugin XEP-0231: Bits of Binary first draft:
Goffi <goffi@goffi.org>
parents:
2080
diff
changeset
|
183 post_treat.addCallback(self._messagePostTreat, message, body_elts, client) |
668 | 184 return True |
185 | |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
186 def sendMessageTrigger(self, client, data, pre_xml_treatments, post_xml_treatments): |
2080
3626b2813158
plugin XEP-0071: fixed rich and xhtml sending + add simple text body if not present
Goffi <goffi@goffi.org>
parents:
1963
diff
changeset
|
187 """ Check presence of rich text in extra """ |
1955
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
188 rich = {} |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
189 xhtml = {} |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
190 for key, value in data['extra'].iteritems(): |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
191 if key.startswith('rich'): |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
192 rich[key[5:]] = value |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
193 elif key.startswith('xhtml'): |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
194 xhtml[key[6:]] = value |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
195 if rich and xhtml: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
196 raise exceptions.DataError(_(u"Can't have XHTML and rich content at the same time")) |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
197 if rich or xhtml: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
198 if rich: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
199 data['rich'] = rich |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
200 else: |
633b5c21aefd
backend, frontend: messages refactoring (huge commit, not finished):
Goffi <goffi@goffi.org>
parents:
1934
diff
changeset
|
201 data['xhtml'] = xhtml |
2144
1d3f73e065e1
core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents:
2110
diff
changeset
|
202 post_xml_treatments.addCallback(self._sendMessageAddRich, client) |
702
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
203 return True |
a25db3fe3959
plugin XEP-0071: rich messages management for sendMessage
Goffi <goffi@goffi.org>
parents:
701
diff
changeset
|
204 |
668 | 205 def _purgeStyle(self, styles_raw): |
206 """ Remove unauthorised styles according to the XEP-0071 | |
207 @param styles_raw: raw styles (value of the style attribute) | |
208 """ | |
209 purged = [] | |
210 | |
211 styles = [style.strip().split(':') for style in styles_raw.split(';')] | |
212 | |
213 for style_tuple in styles: | |
214 if len(style_tuple) != 2: | |
215 continue | |
216 name, value = style_tuple | |
217 name = name.strip() | |
218 if name not in styles_allowed: | |
219 continue | |
220 purged.append((name, value.strip())) | |
221 | |
222 return u'; '.join([u"%s: %s" % data for data in purged]) | |
223 | |
224 def XHTML2XHTML_IM(self, xhtml): | |
225 """ Convert XHTML document to XHTML_IM subset | |
226 @param xhtml: raw xhtml to convert | |
227 """ | |
228 # TODO: more clever tag replacement (replace forbidden tags with equivalents when possible) | |
229 | |
230 parser = html.HTMLParser(remove_comments=True, encoding='utf-8') | |
231 root = html.fromstring(xhtml, parser=parser) | |
232 body_elt = root.find('body') | |
233 if body_elt is None: | |
234 # we use the whole XML as body if no body element is found | |
235 body_elt = html.Element('body') | |
236 body_elt.append(root) | |
237 else: | |
238 body_elt.attrib.clear() | |
239 | |
240 allowed_tags = allowed.keys() | |
241 to_strip = [] | |
242 for elem in body_elt.iter(): | |
243 if elem.tag not in allowed_tags: | |
244 to_strip.append(elem) | |
245 else: | |
246 # we remove unallowed attributes | |
247 attrib = elem.attrib | |
248 att_to_remove = set(attrib).difference(allowed[elem.tag]) | |
249 for att in att_to_remove: | |
250 del(attrib[att]) | |
251 if "style" in attrib: | |
252 attrib["style"] = self._purgeStyle(attrib["style"]) | |
253 | |
254 for elem in to_strip: | |
255 if elem.tag in blacklist: | |
256 #we need to remove the element and all descendants | |
993
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
922
diff
changeset
|
257 log.debug(u"removing black listed tag: %s" % (elem.tag)) |
668 | 258 elem.drop_tree() |
259 else: | |
260 elem.drop_tag() | |
701
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
261 if len(body_elt) !=1: |
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
262 root_elt = body_elt |
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
263 body_elt.tag = "p" |
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
264 else: |
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
265 root_elt = body_elt[0] |
668 | 266 |
701
98b2400e17d6
plugin XEP-0071: XHTML2XHTML_IM don't return the <body> root tag anymore.
Goffi <goffi@goffi.org>
parents:
668
diff
changeset
|
267 return html.tostring(root_elt, encoding='unicode', method='xml') |
668 | 268 |
269 class XEP_0071_handler(XMPPHandler): | |
270 implements(iwokkel.IDisco) | |
271 | |
272 def __init__(self, plugin_parent): | |
273 self.plugin_parent = plugin_parent | |
274 self.host = plugin_parent.host | |
275 | |
276 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): | |
277 return [disco.DiscoFeature(NS_XHTML_IM)] | |
278 | |
279 def getDiscoItems(self, requestor, target, nodeIdentifier=''): | |
280 return [] |