Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0277.py @ 1419:be2df1ddea8e
plugins (groupblog, xep-0277) + tmp(rsm): improved style:
- removed external parenthesis in assertions
- added blank line after first line of docstrings
- replaced "__" prefixes by "_"
- renamed variabled named after the reserverd word "max" to "max_"
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 22 Apr 2015 18:30:28 +0200 |
parents | 3265a2639182 |
children | 16b1ba7ccaaa |
comparison
equal
deleted
inserted
replaced
1418:6adf1b0be609 | 1419:be2df1ddea8e |
---|---|
93 if not node: | 93 if not node: |
94 raise exceptions.DataError('Invalid comments link') | 94 raise exceptions.DataError('Invalid comments link') |
95 | 95 |
96 return (service, node) | 96 return (service, node) |
97 | 97 |
98 def __removeXHTMLMarkups(self, xhtml): | 98 def _removeXHTMLMarkups(self, xhtml): |
99 """ | 99 """Remove XHTML markups from the given string. |
100 Remove XHTML markups from the given string. | 100 |
101 @param xhtml: the XHTML string to be cleaned | 101 @param xhtml: the XHTML string to be cleaned |
102 @return: a Deferred instance for the cleaned string | 102 @return: a Deferred instance for the cleaned string |
103 """ | 103 """ |
104 return self.host.plugins["TEXT-SYNTAXES"].convert(xhtml, | 104 return self.host.plugins["TEXT-SYNTAXES"].convert(xhtml, |
105 self.host.plugins["TEXT-SYNTAXES"].SYNTAX_XHTML, | 105 self.host.plugins["TEXT-SYNTAXES"].SYNTAX_XHTML, |
140 | 140 |
141 microblog_data = {} | 141 microblog_data = {} |
142 | 142 |
143 for key in ['title', 'content']: # process the textual elements | 143 for key in ['title', 'content']: # process the textual elements |
144 for attr_elt in xpath(entry_elt, key): | 144 for attr_elt in xpath(entry_elt, key): |
145 attr_content = self.__getLXMLInnerContent(attr_elt) | 145 attr_content = self._getLXMLInnerContent(attr_elt) |
146 if not attr_content.strip(): | 146 if not attr_content.strip(): |
147 continue # element with empty value | 147 continue # element with empty value |
148 content_type = attr_elt.get('type', 'text').lower() | 148 content_type = attr_elt.get('type', 'text').lower() |
149 if content_type == 'xhtml': | 149 if content_type == 'xhtml': |
150 text = self.__decapsulateExtraNS(attr_content) | 150 text = self._decapsulateExtraNS(attr_content) |
151 microblog_data['%s_xhtml' % key] = yield self.host.plugins["TEXT-SYNTAXES"].clean_xhtml(text) | 151 microblog_data['%s_xhtml' % key] = yield self.host.plugins["TEXT-SYNTAXES"].clean_xhtml(text) |
152 else: | 152 else: |
153 microblog_data[key] = attr_content | 153 microblog_data[key] = attr_content |
154 if key not in microblog_data and ('%s_xhtml' % key) in microblog_data: | 154 if key not in microblog_data and ('%s_xhtml' % key) in microblog_data: |
155 microblog_data[key] = yield self.__removeXHTMLMarkups(microblog_data['%s_xhtml' % key]) | 155 microblog_data[key] = yield self._removeXHTMLMarkups(microblog_data['%s_xhtml' % key]) |
156 | 156 |
157 try: # check for mandatory elements | 157 try: # check for mandatory elements |
158 microblog_data['id'] = xpath(entry_elt, 'id')[0].text | 158 microblog_data['id'] = xpath(entry_elt, 'id')[0].text |
159 microblog_data['updated'] = date2float(entry_elt, 'updated') | 159 microblog_data['updated'] = date2float(entry_elt, 'updated') |
160 assert('title' in microblog_data) # has been processed already | 160 assert('title' in microblog_data) # has been processed already |
196 except IndexError: | 196 except IndexError: |
197 log.warning(_(u"Can't find author element in atom entry %s") % microblog_data['id']) | 197 log.warning(_(u"Can't find author element in atom entry %s") % microblog_data['id']) |
198 | 198 |
199 defer.returnValue(microblog_data) | 199 defer.returnValue(microblog_data) |
200 | 200 |
201 def __getLXMLInnerContent(self, elt): | 201 def _getLXMLInnerContent(self, elt): |
202 """Return the inner content of a lxml.etree.Element. It is not | 202 """Return the inner content of a lxml.etree.Element. It is not |
203 trivial because the lxml tostring method would return the full | 203 trivial because the lxml tostring method would return the full |
204 content including elt's tag and attributes, and elt.getchildren() | 204 content including elt's tag and attributes, and elt.getchildren() |
205 would skip a text value which is not within an element...""" | 205 would skip a text value which is not within an element...""" |
206 return self.__getDomishInnerContent(ElementParser()(etree.tostring(elt))) | 206 return self._getDomishInnerContent(ElementParser()(etree.tostring(elt))) |
207 | 207 |
208 def __getDomishInnerContent(self, elt): | 208 def _getDomishInnerContent(self, elt): |
209 """Return the inner content of a domish.Element.""" | 209 """Return the inner content of a domish.Element.""" |
210 result = '' | 210 result = '' |
211 for child in elt.children: | 211 for child in elt.children: |
212 try: | 212 try: |
213 result += child.toXml() # child id a domish.Element | 213 result += child.toXml() # child id a domish.Element |
214 except AttributeError: | 214 except AttributeError: |
215 result += child # child is unicode | 215 result += child # child is unicode |
216 return result | 216 return result |
217 | 217 |
218 def __decapsulateExtraNS(self, text): | 218 def _decapsulateExtraNS(self, text): |
219 """Check for XHTML namespace and decapsulate the content so the user | 219 """Check for XHTML namespace and decapsulate the content so the user |
220 who wants to modify an entry will see the text that he entered. Also | 220 who wants to modify an entry will see the text that he entered. Also |
221 this avoids successive encapsulation with a new <div>...</div> at | 221 this avoids successive encapsulation with a new <div>...</div> at |
222 each modification (encapsulation is done in self.data2entry)""" | 222 each modification (encapsulation is done in self.data2entry)""" |
223 elt = ElementParser()(text) | 223 elt = ElementParser()(text) |
224 if elt.uri != NS_XHTML: | 224 if elt.uri != NS_XHTML: |
225 raise exceptions.DataError(_('Content of type XHTML must declare its namespace!')) | 225 raise exceptions.DataError(_('Content of type XHTML must declare its namespace!')) |
226 return self.__getDomishInnerContent(elt) | 226 return self._getDomishInnerContent(elt) |
227 | 227 |
228 def microblogCB(self, itemsEvent, profile): | 228 def microblogCB(self, itemsEvent, profile): |
229 """Callback to "MICROBLOG" PEP event.""" | 229 """Callback to "MICROBLOG" PEP event.""" |
230 def manageItem(microblog_data): | 230 def manageItem(microblog_data): |
231 self.host.bridge.personalEvent(itemsEvent.sender.full(), "MICROBLOG", microblog_data, profile) | 231 self.host.bridge.personalEvent(itemsEvent.sender.full(), "MICROBLOG", microblog_data, profile) |
234 self.item2mbdata(item).addCallbacks(manageItem, lambda failure: None) | 234 self.item2mbdata(item).addCallbacks(manageItem, lambda failure: None) |
235 | 235 |
236 @defer.inlineCallbacks | 236 @defer.inlineCallbacks |
237 def data2entry(self, data, profile): | 237 def data2entry(self, data, profile): |
238 """Convert a data dict to en entry usable to create an item | 238 """Convert a data dict to en entry usable to create an item |
239 | |
239 @param data: data dict as given by bridge method. | 240 @param data: data dict as given by bridge method. |
240 @return: deferred which fire domish.Element""" | 241 @return: deferred which fire domish.Element |
242 """ | |
241 _uuid = unicode(uuid.uuid1()) | 243 _uuid = unicode(uuid.uuid1()) |
242 _entry = atom.Entry() | 244 _entry = atom.Entry() |
243 _entry.title = '' # reset the default value which is not empty | 245 _entry.title = '' # reset the default value which is not empty |
244 | 246 |
245 elems = {'title': atom.Title, 'content': atom.Content} | 247 elems = {'title': atom.Title, 'content': atom.Content} |
264 elem = elems[key](escape(data[attr]).encode('utf-8')) | 266 elem = elems[key](escape(data[attr]).encode('utf-8')) |
265 elem.attrs['type'] = 'text' | 267 elem.attrs['type'] = 'text' |
266 setattr(_entry, key, elem) | 268 setattr(_entry, key, elem) |
267 if not getattr(_entry, key).text: | 269 if not getattr(_entry, key).text: |
268 if hasattr(_entry, '%s_xhtml' % key): | 270 if hasattr(_entry, '%s_xhtml' % key): |
269 text = yield self.__removeXHTMLMarkups(getattr(_entry, '%s_xhtml' % key).text) | 271 text = yield self._removeXHTMLMarkups(getattr(_entry, '%s_xhtml' % key).text) |
270 setattr(_entry, key, text) | 272 setattr(_entry, key, text) |
271 if not _entry.title.text: # eventually move the data from content to title | 273 if not _entry.title.text: # eventually move the data from content to title |
272 _entry.title = _entry.content.text | 274 _entry.title = _entry.content.text |
273 _entry.title.attrs['type'] = _entry.content.attrs['type'] | 275 _entry.title.attrs['type'] = _entry.content.attrs['type'] |
274 _entry.content.text = '' | 276 _entry.content.text = '' |
296 defer.returnValue(item) | 298 defer.returnValue(item) |
297 | 299 |
298 @defer.inlineCallbacks | 300 @defer.inlineCallbacks |
299 def sendMicroblog(self, data, profile): | 301 def sendMicroblog(self, data, profile): |
300 """Send XEP-0277's microblog data | 302 """Send XEP-0277's microblog data |
303 | |
301 @param data: must include content | 304 @param data: must include content |
302 @param profile: profile which send the mood""" | 305 @param profile: profile which send the mood""" |
303 if 'content' not in data: | 306 if 'content' not in data: |
304 log.error(_("Microblog data must contain at least 'content' key")) | 307 log.error(_("Microblog data must contain at least 'content' key")) |
305 raise exceptions.DataError('no "content" key found') | 308 raise exceptions.DataError('no "content" key found') |
311 ret = yield self.host.plugins["XEP-0060"].publish(None, NS_MICROBLOG, [item], profile_key=profile) | 314 ret = yield self.host.plugins["XEP-0060"].publish(None, NS_MICROBLOG, [item], profile_key=profile) |
312 defer.returnValue(ret) | 315 defer.returnValue(ret) |
313 | 316 |
314 def getLastMicroblogs(self, pub_jid, max_items=10, profile_key=C.PROF_KEY_NONE): | 317 def getLastMicroblogs(self, pub_jid, max_items=10, profile_key=C.PROF_KEY_NONE): |
315 """Get the last published microblogs | 318 """Get the last published microblogs |
319 | |
316 @param pub_jid: jid of the publisher | 320 @param pub_jid: jid of the publisher |
317 @param max_items: how many microblogs we want to get | 321 @param max_items: how many microblogs we want to get |
318 @param profile_key: profile key | 322 @param profile_key: profile key |
319 | 323 |
320 @return: a deferred couple with the list of items and RSM information. | 324 @return: a deferred couple with the list of items and RSM information. |
324 d.addCallback(lambda res: ([value for (success, value) in res[0] if success], res[1])) | 328 d.addCallback(lambda res: ([value for (success, value) in res[0] if success], res[1])) |
325 return d | 329 return d |
326 | 330 |
327 def setMicroblogAccess(self, access="presence", profile_key=C.PROF_KEY_NONE): | 331 def setMicroblogAccess(self, access="presence", profile_key=C.PROF_KEY_NONE): |
328 """Create a microblog node on PEP with given access | 332 """Create a microblog node on PEP with given access |
333 | |
329 If the node already exists, it change options | 334 If the node already exists, it change options |
330 @param access: Node access model, according to xep-0060 #4.5 | 335 @param access: Node access model, according to xep-0060 #4.5 |
331 @param profile_key: profile key""" | 336 @param profile_key: profile key""" |
332 | 337 |
333 _jid, xmlstream = self.host.getJidNStream(profile_key) | 338 _jid, xmlstream = self.host.getJidNStream(profile_key) |