Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0277.py @ 1454:4e2fab4de195
plugin XEP-0277: added mBGetFromManyWithComments to have items + comments in one method call
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 15 Aug 2015 22:24:38 +0200 |
parents | d5e72362ee91 |
children | 4c4f88d7b156 |
comparison
equal
deleted
inserted
replaced
1453:d5e72362ee91 | 1454:4e2fab4de195 |
---|---|
24 from twisted.words.protocols.jabber import jid | 24 from twisted.words.protocols.jabber import jid |
25 from twisted.internet import defer | 25 from twisted.internet import defer |
26 from twisted.python import failure | 26 from twisted.python import failure |
27 from sat.core import exceptions | 27 from sat.core import exceptions |
28 from sat.tools.xml_tools import ElementParser | 28 from sat.tools.xml_tools import ElementParser |
29 from sat.tools import sat_defer | |
29 | 30 |
30 from wokkel import pubsub | 31 from wokkel import pubsub |
31 from wokkel import rsm | 32 from wokkel import rsm |
32 from feed import atom, date | 33 from feed import atom, date |
33 import uuid | 34 import uuid |
61 | 62 |
62 def __init__(self, host): | 63 def __init__(self, host): |
63 log.info(_("Microblogging plugin initialization")) | 64 log.info(_("Microblogging plugin initialization")) |
64 self.host = host | 65 self.host = host |
65 self._p = self.host.plugins["XEP-0060"] # this facilitate the access to pubsub plugin | 66 self._p = self.host.plugins["XEP-0060"] # this facilitate the access to pubsub plugin |
67 self.rt_sessions = sat_defer.RTDeferredSessions() | |
66 self.host.plugins["XEP-0163"].addPEPEvent("MICROBLOG", NS_MICROBLOG, self.microblogCB, self.sendMicroblog, notify=False) | 68 self.host.plugins["XEP-0163"].addPEPEvent("MICROBLOG", NS_MICROBLOG, self.microblogCB, self.sendMicroblog, notify=False) |
67 host.bridge.addMethod("getLastMicroblogs", ".plugin", | 69 host.bridge.addMethod("getLastMicroblogs", ".plugin", |
68 in_sign='sis', out_sign='(aa{ss}a{ss})', | 70 in_sign='sis', out_sign='(aa{ss}a{ss})', |
69 method=self._getLastMicroblogs, | 71 method=self._getLastMicroblogs, |
70 async=True, | 72 async=True, |
80 method=self._mBSubscribeToMany) | 82 method=self._mBSubscribeToMany) |
81 host.bridge.addMethod("mBGetFromManyRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssaa{ss}a{ss}))', | 83 host.bridge.addMethod("mBGetFromManyRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssaa{ss}a{ss}))', |
82 method=self._mBGetFromManyRTResult, async=True) | 84 method=self._mBGetFromManyRTResult, async=True) |
83 host.bridge.addMethod("mBGetFromMany", ".plugin", in_sign='sasia{ss}s', out_sign='s', | 85 host.bridge.addMethod("mBGetFromMany", ".plugin", in_sign='sasia{ss}s', out_sign='s', |
84 method=self._mBGetFromMany) | 86 method=self._mBGetFromMany) |
87 host.bridge.addMethod("mBGetFromManyWithCommentsRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssa(a{ss}a(sssaa{ss}a{ss}))a{ss}))', | |
88 method=self._mBGetFromManyWithCommentsRTResult, async=True) | |
89 host.bridge.addMethod("mBGetFromManyWithComments", ".plugin", in_sign='sasiia{ss}a{ss}s', out_sign='s', method=self._mBGetFromManyWithComments) | |
85 | 90 |
86 ## plugin management methods ## | 91 ## plugin management methods ## |
87 | 92 |
88 def microblogCB(self, itemsEvent, profile): | 93 def microblogCB(self, itemsEvent, profile): |
89 """Callback to "MICROBLOG" PEP event.""" | 94 """Callback to "MICROBLOG" PEP event.""" |
563 - the microblogs data | 568 - the microblogs data |
564 - RSM response data | 569 - RSM response data |
565 """ | 570 """ |
566 client, node_data = self._getClientAndNodeData(publishers_type, publishers, profile_key) | 571 client, node_data = self._getClientAndNodeData(publishers_type, publishers, profile_key) |
567 return self._p.getFromMany(node_data, max_item, rsm_data, profile_key=profile_key) | 572 return self._p.getFromMany(node_data, max_item, rsm_data, profile_key=profile_key) |
573 | |
574 # comments # | |
575 | |
576 def _mBGetFromManyWithCommentsRTResult(self, session_id, profile_key=C.PROF_KEY_DEFAULT): | |
577 """Get real-time results for [mBGetFromManyWithComments] session | |
578 | |
579 @param session_id: id of the real-time deferred session | |
580 @param return (tuple): (remaining, results) where: | |
581 - remaining is the number of still expected results | |
582 - results is a list of tuple with | |
583 - service (unicode): pubsub service | |
584 - node (unicode): pubsub node | |
585 - success (bool): True if the getItems was successful | |
586 - failure (unicode): empty string in case of success, error message else | |
587 - items(list): list of items with: | |
588 - item(dict): item microblog data | |
589 - comments_list(list): list of comments with | |
590 - service (unicode): pubsub service where the comments node is | |
591 - node (unicode): comments node | |
592 - failure (unicode): empty in case of success, else error message | |
593 - comments(list[dict]): list of microblog data | |
594 - comments_metadata(dict): metadata of the comment node | |
595 - metadata(dict): original node metadata | |
596 @param profile_key: %(doc_profile_key)s | |
597 """ | |
598 profile = self.host.getClient(profile_key).profile | |
599 d = self.rt_sessions.getResults(session_id, profile=profile) | |
600 d.addCallback(lambda ret: (ret[0], | |
601 [(service.full(), node, failure, items, metadata) | |
602 for (service, node), (success, (failure, (items, metadata))) in ret[1].iteritems()])) | |
603 return d | |
604 | |
605 def _mBGetFromManyWithComments(self, publishers_type, publishers, max_item=10, max_comments=C.NO_LIMIT, rsm_dict=None, rsm_comments_dict=None, profile_key=C.PROF_KEY_NONE): | |
606 """ | |
607 @param max_item(int): maximum number of item to get, C.NO_LIMIT for no limit | |
608 @param max_comments(int): maximum number of comments to get, C.NO_LIMIT for no limit | |
609 """ | |
610 max_item = None if max_item == C.NO_LIMIT else max_item | |
611 max_comments = None if max_comments == C.NO_LIMIT else max_comments | |
612 publishers_type, publishers = self._checkPublishers(publishers_type, publishers) | |
613 return self.mBGetFromManyWithComments(publishers_type, publishers, max_item, max_comments, | |
614 rsm.RSMRequest(**rsm_dict) if rsm_dict else None, | |
615 rsm.RSMRequest(**rsm_comments_dict) if rsm_comments_dict else None, | |
616 profile_key) | |
617 | |
618 def mBGetFromManyWithComments(self, publishers_type, publishers, max_item=None, max_comments=None, rsm_request=None, rsm_comments=None, profile_key=C.PROF_KEY_NONE): | |
619 """Helper method to get the microblogs and their comments in one shot | |
620 | |
621 @param publishers_type (str): type of the list of publishers (one of "GROUP" or "JID" or "ALL") | |
622 @param publishers (list): list of publishers, according to publishers_type (list of groups or list of jids) | |
623 @param max_items (int): optional limit on the number of retrieved items. | |
624 @param max_comments (int): maximum number of comments to retrieve | |
625 @param rsm_request (rsm.RSMRequest): RSM request for initial items only | |
626 @param rsm_comments (rsm.RSMRequest): RSM request for comments only | |
627 @param profile_key: profile key | |
628 @return: a deferred dict with: | |
629 - key: publisher (unicode) | |
630 - value: couple (list[dict], dict) with: | |
631 - the microblogs data | |
632 - RSM response data | |
633 """ | |
634 # XXX: this method seems complicated because it do a couple of treatments | |
635 # to serialise and associate the data, but it make life in frontends side | |
636 # a lot easier | |
637 | |
638 def getComments(items_data): | |
639 """Retrieve comments and add them to the items_data | |
640 | |
641 @param items_data: serialised items data | |
642 @return (defer.Deferred): list of items where each item is associated | |
643 with a list of comments data (service, node, list of items, metadata) | |
644 """ | |
645 items, metadata = items_data | |
646 items_dlist = [] # deferred list for items | |
647 for item in items: | |
648 dlist = [] # deferred list for comments | |
649 for key, value in item.iteritems(): | |
650 # we look for comments | |
651 if key.startswith('comments') and key.endswith('_service'): | |
652 prefix = key[:key.find('_')] | |
653 service_s = value | |
654 node = item["{}{}".format(prefix, "_node")] | |
655 # time to get the comments | |
656 d = self._p.getItems(jid.JID(service_s), node, max_comments, rsm_request=rsm_comments, profile_key=profile_key) | |
657 # then serialise | |
658 d.addCallback(lambda items_data: self._p.serItemsDataD(items_data, self.item2mbdata)) | |
659 # with failure handling | |
660 d.addCallback(lambda serialised_items_data: ('',) + serialised_items_data) | |
661 d.addErrback(lambda failure: (unicode(failure.value), [], {})) | |
662 # and associate with service/node (needed if there are several comments nodes) | |
663 d.addCallback(lambda serialised: (service_s, node) + serialised) | |
664 dlist.append(d) | |
665 # we get the comments | |
666 comments_d = defer.gatherResults(dlist) | |
667 # and add them to the item data | |
668 comments_d.addCallback(lambda comments_data: (item, comments_data)) | |
669 items_dlist.append(comments_d) | |
670 # we gather the items + comments in a list | |
671 items_d = defer.gatherResults(items_dlist) | |
672 # and add the metadata | |
673 items_d.addCallback(lambda items: (items, metadata)) | |
674 return items_d | |
675 | |
676 client, node_data = self._getClientAndNodeData(publishers_type, publishers, profile_key) | |
677 deferreds = {} | |
678 for service, node in node_data: | |
679 d = deferreds[(service, node)] = self._p.getItems(service, node, max_item, rsm_request=rsm_request, profile_key=profile_key) | |
680 d.addCallback(lambda items_data: self._p.serItemsDataD(items_data, self.item2mbdata)) | |
681 d.addCallback(getComments) | |
682 d.addCallback(lambda items_comments_data: ('', items_comments_data)) | |
683 d.addErrback(lambda failure: (unicode(failure.value), ([],{}))) | |
684 | |
685 return self.rt_sessions.newSession(deferreds, client.profile) |