comparison src/plugins/plugin_misc_groupblog.py @ 708:6aa71c853bf5

plugin group blog: management of extra data/rich text for blog comments
author Goffi <goffi@goffi.org>
date Fri, 15 Nov 2013 15:27:03 +0100
parents 890fbf2d7fdd
children ade9997fabfa
comparison
equal deleted inserted replaced
707:890fbf2d7fdd 708:6aa71c853bf5
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from logging import debug, info, warning, error 20 from logging import debug, info, warning, error
21 from twisted.internet import defer 21 from twisted.internet import defer
22 from twisted.words.protocols.jabber import jid 22 from twisted.words.protocols.jabber import jid
23 23 from sat.core import exceptions
24 from wokkel import disco, data_form, iwokkel 24 from wokkel import disco, data_form, iwokkel
25
26 from zope.interface import implements 25 from zope.interface import implements
27 26
28 import uuid 27 import uuid
29 import urllib 28 import urllib
30 29
86 85
87 host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sassa{ss}s', out_sign='', 86 host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sassa{ss}s', out_sign='',
88 method=self.sendGroupBlog, 87 method=self.sendGroupBlog,
89 async=True) 88 async=True)
90 89
91 host.bridge.addMethod("sendGroupBlogComment", ".plugin", in_sign='sss', out_sign='', 90 host.bridge.addMethod("sendGroupBlogComment", ".plugin", in_sign='ssa{ss}s', out_sign='',
92 method=self.sendGroupBlogComment, 91 method=self.sendGroupBlogComment,
93 async=True) 92 async=True)
94 93
95 host.bridge.addMethod("getLastGroupBlogs", ".plugin", 94 host.bridge.addMethod("getLastGroupBlogs", ".plugin",
96 in_sign='sis', out_sign='aa{ss}', 95 in_sign='sis', out_sign='aa{ss}',
119 118
120 def getHandler(self, profile): 119 def getHandler(self, profile):
121 return GroupBlog_handler() 120 return GroupBlog_handler()
122 121
123 @defer.inlineCallbacks 122 @defer.inlineCallbacks
124 def initialise(self, profile_key): 123 def _initialise(self, profile_key):
125 """Check that this data for this profile are initialised, and do it else 124 """Check that this data for this profile are initialised, and do it else
126 @param client: client of the profile 125 @param client: client of the profile
127 @profile_key: %(doc_profile)s""" 126 @profile_key: %(doc_profile)s"""
128 profile = self.host.memory.getProfileName(profile_key) 127 profile = self.host.memory.getProfileName(profile_key)
129 if not profile: 128 if not profile:
130 error(_("Unknown profile")) 129 raise exceptions.ProfileUnknownError
131 raise Exception("Unknown profile")
132 130
133 client = self.host.getClient(profile) 131 client = self.host.getClient(profile)
134 if not client: 132 if not client:
135 error(_('No client for this profile key: %s') % profile_key) 133 error(_('No client for this profile key: %s') % profile_key)
136 raise Exception("Unknown profile") 134 raise Exception("Unknown profile")
326 list of groups or list of jids) for this item 324 list of groups or list of jids) for this item
327 @param message: microblog 325 @param message: microblog
328 @param extra: dict which option name as key, which can be: 326 @param extra: dict which option name as key, which can be:
329 - allow_comments: True to accept comments, False else (default: False) 327 - allow_comments: True to accept comments, False else (default: False)
330 - rich: if present, contain rich text in currently selected syntax 328 - rich: if present, contain rich text in currently selected syntax
331 @profile_key: %(doc_profile)s 329 @profile_key: %(doc_profile_key)s
332 """ 330 """
333 331
334 def initialised(result): 332 def initialised(result):
335 profile, client = result 333 profile, client = result
336 if access_type == "PUBLIC": 334 if access_type == "PUBLIC":
346 raise NotImplementedError 344 raise NotImplementedError
347 else: 345 else:
348 error(_("Unknown access type")) 346 error(_("Unknown access type"))
349 raise BadAccessTypeError 347 raise BadAccessTypeError
350 348
351 return self.initialise(profile_key).addCallback(initialised) 349 return self._initialise(profile_key).addCallback(initialised)
352 350
353 def sendGroupBlogComment(self, node_url, message, profile_key='@NONE@'): 351 def sendGroupBlogComment(self, node_url, message, extra, profile_key='@NONE@'):
354 """Publish a comment in the given node 352 """Publish a comment in the given node
355 @param node url: link to the comments node as specified in XEP-0277 and given in microblog data's comments key 353 @param node url: link to the comments node as specified in XEP-0277 and given in microblog data's comments key
356 @param message: comment 354 @param message: comment
355 @param extra: dict which option name as key, which can be:
356 - allow_comments: True to accept an other level of comments, False else (default: False)
357 - rich: if present, contain rich text in currently selected syntax
357 @profile_key: %(doc_profile)s 358 @profile_key: %(doc_profile)s
358 """ 359 """
359 profile = self.host.memory.getProfileName(profile_key) 360 def initialised(result):
360 if not profile: 361 profile, client = result
361 error(_("Unknown profile")) 362 service, node = self.host.plugins["XEP-0277"].parseCommentUrl(node_url)
362 raise Exception("Unknown profile") 363 mblog_data = {'content': message}
363 364 if 'rich' in extra:
364 service, node = self.host.plugins["XEP-0277"].parseCommentUrl(node_url) 365 mblog_data['rich'] = extra['rich']
365 366 if 'allow_comments' in extra:
366 mblog_data = {'content': message} 367 raise NotImplementedError # TODO
367 entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile) 368 entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile)
368 entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service, node, items=[mblog_item], profile_key=profile)) 369 entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service, node, items=[mblog_item], profile_key=profile))
369 return entry_d 370 return entry_d
371
372 return self._initialise(profile_key).addCallback(initialised)
373
370 374
371 @defer.inlineCallbacks 375 @defer.inlineCallbacks
372 def _itemsConstruction(self, items, pub_jid, client): 376 def _itemsConstruction(self, items, pub_jid, client):
373 """ Transforms items to group blog data and manage comments node 377 """ Transforms items to group blog data and manage comments node
374 @param items: iterable of items 378 @param items: iterable of items
407 d.addCallback(self._itemsConstruction, pub_jid, client) 411 d.addCallback(self._itemsConstruction, pub_jid, client)
408 d.addErrback(lambda ignore: {}) # TODO: more complete error management (log !) 412 d.addErrback(lambda ignore: {}) # TODO: more complete error management (log !)
409 return d 413 return d
410 414
411 #TODO: we need to use the server corresponding the the host of the jid 415 #TODO: we need to use the server corresponding the the host of the jid
412 return self.initialise(profile_key).addCallback(initialised) 416 return self._initialise(profile_key).addCallback(initialised)
413 417
414 def getGroupBlogComments(self, service_s, node, profile_key='@NONE@'): 418 def getGroupBlogComments(self, service_s, node, profile_key='@NONE@'):
415 """Get all comments of given node 419 """Get all comments of given node
416 @param service_s: service hosting the node 420 @param service_s: service hosting the node
417 @param node: comments node 421 @param node: comments node
427 d.addCallback(self._handleCommentsItems, service, node) 431 d.addCallback(self._handleCommentsItems, service, node)
428 d.addErrback(lambda ignore: {}) # TODO: more complete error management (log !) 432 d.addErrback(lambda ignore: {}) # TODO: more complete error management (log !)
429 return d 433 return d
430 434
431 #TODO: we need to use the server corresponding the the host of the jid 435 #TODO: we need to use the server corresponding the the host of the jid
432 return self.initialise(profile_key).addCallback(initialised) 436 return self._initialise(profile_key).addCallback(initialised)
433 437
434 def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@NONE@'): 438 def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@NONE@'):
435 """Get the last published microblogs for a list of groups or jids 439 """Get the last published microblogs for a list of groups or jids
436 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL") 440 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
437 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids) 441 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
485 #TODO: custom exception 489 #TODO: custom exception
486 if publishers_type not in ["GROUP", "JID", "ALL"]: 490 if publishers_type not in ["GROUP", "JID", "ALL"]:
487 raise Exception("Bad call, unknown publishers_type") 491 raise Exception("Bad call, unknown publishers_type")
488 if publishers_type == "ALL" and publishers: 492 if publishers_type == "ALL" and publishers:
489 raise Exception("Publishers list must be empty when getting microblogs for all contacts") 493 raise Exception("Publishers list must be empty when getting microblogs for all contacts")
490 return self.initialise(profile_key).addCallback(initialised) 494 return self._initialise(profile_key).addCallback(initialised)
491 #TODO: we need to use the server corresponding the the host of the jid 495 #TODO: we need to use the server corresponding the the host of the jid
492 496
493 def subscribeGroupBlog(self, pub_jid, profile_key='@NONE@'): 497 def subscribeGroupBlog(self, pub_jid, profile_key='@NONE@'):
494 def initialised(result): 498 def initialised(result):
495 profile, client = result 499 profile, client = result
496 d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)), 500 d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
497 profile_key=profile_key) 501 profile_key=profile_key)
498 return d 502 return d
499 503
500 #TODO: we need to use the server corresponding the the host of the jid 504 #TODO: we need to use the server corresponding the the host of the jid
501 return self.initialise(profile_key).addCallback(initialised) 505 return self._initialise(profile_key).addCallback(initialised)
502 506
503 def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@NONE@'): 507 def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@NONE@'):
504 """Subscribe microblogs for a list of groups or jids 508 """Subscribe microblogs for a list of groups or jids
505 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL") 509 @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
506 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids) 510 @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
533 #TODO: custom exception 537 #TODO: custom exception
534 if publishers_type not in ["GROUP", "JID", "ALL"]: 538 if publishers_type not in ["GROUP", "JID", "ALL"]:
535 raise Exception("Bad call, unknown publishers_type") 539 raise Exception("Bad call, unknown publishers_type")
536 if publishers_type == "ALL" and publishers: 540 if publishers_type == "ALL" and publishers:
537 raise Exception("Publishers list must be empty when getting microblogs for all contacts") 541 raise Exception("Publishers list must be empty when getting microblogs for all contacts")
538 return self.initialise(profile_key).addCallback(initialised) 542 return self._initialise(profile_key).addCallback(initialised)
539 #TODO: we need to use the server corresponding the the host of the jid 543 #TODO: we need to use the server corresponding the the host of the jid
540 544
541 545
542 class GroupBlog_handler(XMPPHandler): 546 class GroupBlog_handler(XMPPHandler):
543 implements(iwokkel.IDisco) 547 implements(iwokkel.IDisco)