Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0277.py @ 2807:0b7ce5daee9b
plugin XEP-0277: blog items data are now entirely serialised before going to bridge:
So far, and for historical reasons, blog items data where serialised using a unicode: unicode dict, which was causing trouble for many types of values (timestamps, booleans, lists).
This patch changes it by serialising the whole items before going to bridge, and deserialising it when going back. This way, complex data can be used easily in items.
This impact psEvent and serItemsData* methods which are renamed transItemsData* because there are not always serialising anymore (a new argument "serialise" allows to specify it).
When editing a blog post in jp, metadata are now more easy to manipulate, specially lists like tags.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 23 Feb 2019 18:59:00 +0100 |
parents | 85d3240a400f |
children | ab2696e34d29 |
comparison
equal
deleted
inserted
replaced
2806:2400cad2dace | 2807:0b7ce5daee9b |
---|---|
83 ) | 83 ) |
84 | 84 |
85 host.bridge.addMethod( | 85 host.bridge.addMethod( |
86 "mbSend", | 86 "mbSend", |
87 ".plugin", | 87 ".plugin", |
88 in_sign="ssa{ss}s", | 88 in_sign="ssss", |
89 out_sign="", | 89 out_sign="", |
90 method=self._mbSend, | 90 method=self._mbSend, |
91 async=True, | 91 async=True, |
92 ) | 92 ) |
93 host.bridge.addMethod( | 93 host.bridge.addMethod( |
100 ) | 100 ) |
101 host.bridge.addMethod( | 101 host.bridge.addMethod( |
102 "mbGet", | 102 "mbGet", |
103 ".plugin", | 103 ".plugin", |
104 in_sign="ssiasa{ss}s", | 104 in_sign="ssiasa{ss}s", |
105 out_sign="(aa{ss}a{ss})", | 105 out_sign="(asa{ss})", |
106 method=self._mbGet, | 106 method=self._mbGet, |
107 async=True, | 107 async=True, |
108 ) | 108 ) |
109 host.bridge.addMethod( | 109 host.bridge.addMethod( |
110 "mbSetAccess", | 110 "mbSetAccess", |
123 ) | 123 ) |
124 host.bridge.addMethod( | 124 host.bridge.addMethod( |
125 "mbGetFromManyRTResult", | 125 "mbGetFromManyRTResult", |
126 ".plugin", | 126 ".plugin", |
127 in_sign="ss", | 127 in_sign="ss", |
128 out_sign="(ua(sssaa{ss}a{ss}))", | 128 out_sign="(ua(sssasa{ss}))", |
129 method=self._mbGetFromManyRTResult, | 129 method=self._mbGetFromManyRTResult, |
130 async=True, | 130 async=True, |
131 ) | 131 ) |
132 host.bridge.addMethod( | 132 host.bridge.addMethod( |
133 "mbGetFromMany", | 133 "mbGetFromMany", |
138 ) | 138 ) |
139 host.bridge.addMethod( | 139 host.bridge.addMethod( |
140 "mbGetFromManyWithCommentsRTResult", | 140 "mbGetFromManyWithCommentsRTResult", |
141 ".plugin", | 141 ".plugin", |
142 in_sign="ss", | 142 in_sign="ss", |
143 out_sign="(ua(sssa(a{ss}a(sssaa{ss}a{ss}))a{ss}))", | 143 out_sign="(ua(sssa(sa(sssasa{ss}))a{ss}))", |
144 method=self._mbGetFromManyWithCommentsRTResult, | 144 method=self._mbGetFromManyWithCommentsRTResult, |
145 async=True, | 145 async=True, |
146 ) | 146 ) |
147 host.bridge.addMethod( | 147 host.bridge.addMethod( |
148 "mbGetFromManyWithComments", | 148 "mbGetFromManyWithComments", |
176 self.host.bridge.psEvent( | 176 self.host.bridge.psEvent( |
177 C.PS_MICROBLOG, | 177 C.PS_MICROBLOG, |
178 itemsEvent.sender.full(), | 178 itemsEvent.sender.full(), |
179 itemsEvent.nodeIdentifier, | 179 itemsEvent.nodeIdentifier, |
180 event, | 180 event, |
181 data, | 181 data_format.serialise(data), |
182 client.profile, | 182 client.profile, |
183 ) | 183 ) |
184 | 184 |
185 for item in itemsEvent.items: | 185 for item in itemsEvent.items: |
186 if item.name == C.PS_ITEM: | 186 if item.name == C.PS_ITEM: |
194 | 194 |
195 ## data/item transformation ## | 195 ## data/item transformation ## |
196 | 196 |
197 @defer.inlineCallbacks | 197 @defer.inlineCallbacks |
198 def item2mbdata(self, item_elt): | 198 def item2mbdata(self, item_elt): |
199 """Convert an XML Item to microblog data used in bridge API | 199 """Convert an XML Item to microblog data |
200 | 200 |
201 @param item_elt: domish.Element of microblog item | 201 @param item_elt: domish.Element of microblog item |
202 @return: microblog data (dictionary) | 202 @return: microblog data (dictionary) |
203 """ | 203 """ |
204 microblog_data = {} | 204 microblog_data = {} |
236 if type_ == "xhtml": | 236 if type_ == "xhtml": |
237 data_elt = elem.firstChildElement() | 237 data_elt = elem.firstChildElement() |
238 if data_elt is None: | 238 if data_elt is None: |
239 raise failure.Failure( | 239 raise failure.Failure( |
240 exceptions.DataError( | 240 exceptions.DataError( |
241 u"XHML content not wrapped in a <div/> element, this is not standard !" | 241 u"XHML content not wrapped in a <div/> element, this is not " |
242 u"standard !" | |
242 ) | 243 ) |
243 ) | 244 ) |
244 if data_elt.uri != C.NS_XHTML: | 245 if data_elt.uri != C.NS_XHTML: |
245 raise failure.Failure( | 246 raise failure.Failure( |
246 exceptions.DataError( | 247 exceptions.DataError( |
279 | 280 |
280 # atom:id | 281 # atom:id |
281 try: | 282 try: |
282 id_elt = entry_elt.elements(NS_ATOM, "id").next() | 283 id_elt = entry_elt.elements(NS_ATOM, "id").next() |
283 except StopIteration: | 284 except StopIteration: |
284 msg = u"No atom id found in the pubsub item {}, this is not standard !".format( | 285 msg = (u"No atom id found in the pubsub item {}, this is not standard !" |
285 id_ | 286 .format(id_)) |
286 ) | |
287 log.warning(msg) | 287 log.warning(msg) |
288 microblog_data[u"atom_id"] = "" | 288 microblog_data[u"atom_id"] = "" |
289 else: | 289 else: |
290 microblog_data[u"atom_id"] = unicode(id_elt) | 290 microblog_data[u"atom_id"] = unicode(id_elt) |
291 | 291 |
341 try: | 341 try: |
342 updated_elt = entry_elt.elements(NS_ATOM, "updated").next() | 342 updated_elt = entry_elt.elements(NS_ATOM, "updated").next() |
343 except StopIteration: | 343 except StopIteration: |
344 msg = u"No atom updated element found in the pubsub item {}".format(id_) | 344 msg = u"No atom updated element found in the pubsub item {}".format(id_) |
345 raise failure.Failure(exceptions.DataError(msg)) | 345 raise failure.Failure(exceptions.DataError(msg)) |
346 microblog_data[u"updated"] = unicode( | 346 microblog_data[u"updated"] = calendar.timegm( |
347 calendar.timegm(dateutil.parser.parse(unicode(updated_elt)).utctimetuple()) | 347 dateutil.parser.parse(unicode(updated_elt)).utctimetuple() |
348 ) | 348 ) |
349 try: | 349 try: |
350 published_elt = entry_elt.elements(NS_ATOM, "published").next() | 350 published_elt = entry_elt.elements(NS_ATOM, "published").next() |
351 except StopIteration: | 351 except StopIteration: |
352 microblog_data[u"published"] = microblog_data[u"updated"] | 352 microblog_data[u"published"] = microblog_data[u"updated"] |
353 else: | 353 else: |
354 microblog_data[u"published"] = unicode( | 354 microblog_data[u"published"] = calendar.timegm( |
355 calendar.timegm( | 355 dateutil.parser.parse(unicode(published_elt)).utctimetuple() |
356 dateutil.parser.parse(unicode(published_elt)).utctimetuple() | |
357 ) | |
358 ) | 356 ) |
359 | 357 |
360 # links | 358 # links |
361 for link_elt in entry_elt.elements(NS_ATOM, "link"): | 359 for link_elt in entry_elt.elements(NS_ATOM, "link"): |
362 if ( | 360 if ( |
418 item_elt.getAttribute(u"publisher") or "" | 416 item_elt.getAttribute(u"publisher") or "" |
419 ) | 417 ) |
420 | 418 |
421 if not publisher: | 419 if not publisher: |
422 log.debug(u"No publisher attribute, we can't verify author jid") | 420 log.debug(u"No publisher attribute, we can't verify author jid") |
423 microblog_data[u"author_jid_verified"] = C.BOOL_FALSE | 421 microblog_data[u"author_jid_verified"] = False |
424 elif jid.JID(publisher).userhostJID() == jid.JID(uri).userhostJID(): | 422 elif jid.JID(publisher).userhostJID() == jid.JID(uri).userhostJID(): |
425 microblog_data[u"author_jid_verified"] = C.BOOL_TRUE | 423 microblog_data[u"author_jid_verified"] = True |
426 else: | 424 else: |
427 log.warning( | 425 log.warning( |
428 u"item atom:uri differ from publisher attribute, spoofing attempt ? atom:uri = {} publisher = {}".format( | 426 u"item atom:uri differ from publisher attribute, spoofing " |
427 u"attempt ? atom:uri = {} publisher = {}".format( | |
429 uri, item_elt.getAttribute("publisher") | 428 uri, item_elt.getAttribute("publisher") |
430 ) | 429 ) |
431 ) | 430 ) |
432 microblog_data[u"author_jid_verified"] = C.BOOL_FALSE | 431 microblog_data[u"author_jid_verified"] = False |
433 # email | 432 # email |
434 try: | 433 try: |
435 email_elt = author_elt.elements(NS_ATOM, "email").next() | 434 email_elt = author_elt.elements(NS_ATOM, "email").next() |
436 except StopIteration: | 435 except StopIteration: |
437 pass | 436 pass |
438 else: | 437 else: |
439 microblog_data[u"author_email"] = unicode(email_elt) | 438 microblog_data[u"author_email"] = unicode(email_elt) |
440 | 439 |
441 # categories | 440 # categories |
442 categories = ( | 441 categories = [ |
443 category_elt.getAttribute("term", "") | 442 category_elt.getAttribute("term", "") |
444 for category_elt in entry_elt.elements(NS_ATOM, "category") | 443 for category_elt in entry_elt.elements(NS_ATOM, "category") |
445 ) | 444 ] |
446 data_format.iter2dict("tag", categories, microblog_data) | 445 microblog_data[u"tags"] = categories |
447 | 446 |
448 ## the trigger ## | 447 ## the trigger ## |
449 # if other plugins have things to add or change | 448 # if other plugins have things to add or change |
450 yield self.host.trigger.point( | 449 yield self.host.trigger.point( |
451 "XEP-0277_item2data", item_elt, entry_elt, microblog_data | 450 "XEP-0277_item2data", item_elt, entry_elt, microblog_data |
570 "published", | 569 "published", |
571 content=utils.xmpp_date(float(data.get("published", current_time))), | 570 content=utils.xmpp_date(float(data.get("published", current_time))), |
572 ) | 571 ) |
573 | 572 |
574 ## categories ## | 573 ## categories ## |
575 for tag in data_format.dict2iter("tag", data): | 574 for tag in data.get('tags', []): |
576 category_elt = entry_elt.addElement("category") | 575 category_elt = entry_elt.addElement("category") |
577 category_elt["term"] = tag | 576 category_elt["term"] = tag |
578 | 577 |
579 ## id ## | 578 ## id ## |
580 entry_id = data.get( | 579 entry_id = data.get( |
653 @param node(unicode): node of the parent item | 652 @param node(unicode): node of the parent item |
654 @param item_id(unicode): id of the parent item | 653 @param item_id(unicode): id of the parent item |
655 @param access(unicode, None): access model | 654 @param access(unicode, None): access model |
656 None to use same access model as parent item | 655 None to use same access model as parent item |
657 """ | 656 """ |
658 # FIXME: if 'comments' already exists in mb_data, it is not used to create the Node | 657 # FIXME: if 'comments' already exists in mb_data, |
659 allow_comments = C.bool(mb_data.pop("allow_comments", "false")) | 658 # it is not used to create the Node |
660 if not allow_comments: | 659 allow_comments = mb_data.pop("allow_comments", None) |
660 if allow_comments is None: | |
661 return | |
662 elif allow_comments == False: | |
661 if "comments" in mb_data: | 663 if "comments" in mb_data: |
662 log.warning( | 664 log.warning( |
663 u"comments are not allowed but there is already a comments node, it may be lost: {uri}".format( | 665 u"comments are not allowed but there is already a comments node, " |
666 u"it may be lost: {uri}".format( | |
664 uri=mb_data["comments"] | 667 uri=mb_data["comments"] |
665 ) | 668 ) |
666 ) | 669 ) |
667 del mb_data["comments"] | 670 del mb_data["comments"] |
668 return | 671 return |
735 raise exceptions.DataError( | 738 raise exceptions.DataError( |
736 u"if comments is present, it must not be empty" | 739 u"if comments is present, it must not be empty" |
737 ) | 740 ) |
738 if "comments_node" in mb_data or "comments_service" in mb_data: | 741 if "comments_node" in mb_data or "comments_service" in mb_data: |
739 raise exceptions.DataError( | 742 raise exceptions.DataError( |
740 u"You can't use comments_service/comments_node and comments at the same time" | 743 u"You can't use comments_service/comments_node and comments at the " |
744 u"same time" | |
741 ) | 745 ) |
742 else: | 746 else: |
743 mb_data["comments"] = self._p.getNodeURI(comments_service, comments_node) | 747 mb_data["comments"] = self._p.getNodeURI(comments_service, comments_node) |
744 | 748 |
745 def _mbSend(self, service, node, data, profile_key): | 749 def _mbSend(self, service, node, data, profile_key): |
746 service = jid.JID(service) if service else None | 750 service = jid.JID(service) if service else None |
747 node = node if node else NS_MICROBLOG | 751 node = node if node else NS_MICROBLOG |
748 client = self.host.getClient(profile_key) | 752 client = self.host.getClient(profile_key) |
753 data = data_format.deserialise(data) | |
749 return self.send(client, data, service, node) | 754 return self.send(client, data, service, node) |
750 | 755 |
751 @defer.inlineCallbacks | 756 @defer.inlineCallbacks |
752 def send(self, client, data, service=None, node=NS_MICROBLOG): | 757 def send(self, client, data, service=None, node=NS_MICROBLOG): |
753 """Send XEP-0277's microblog data | 758 """Send XEP-0277's microblog data |
758 None to publish on profile's PEP | 763 None to publish on profile's PEP |
759 @param node(unicode, None): PubSub node to use (defaut to microblog NS) | 764 @param node(unicode, None): PubSub node to use (defaut to microblog NS) |
760 None is equivalend as using default value | 765 None is equivalend as using default value |
761 """ | 766 """ |
762 # TODO: check that all data keys are used, this would avoid sending publicly a private message | 767 # TODO: check that all data keys are used, this would avoid sending publicly a private message |
763 # by accident (e.g. if group pluging is not loaded, and "grou*" key are not used) | 768 # by accident (e.g. if group plugin is not loaded, and "group*" key are not used) |
764 if node is None: | 769 if node is None: |
765 node = NS_MICROBLOG | 770 node = NS_MICROBLOG |
766 | 771 |
767 item_id = data.get("id") or unicode(shortuuid.uuid()) | 772 item_id = data.get("id") or unicode(shortuuid.uuid()) |
768 | 773 |
786 profile_key, | 791 profile_key, |
787 ) | 792 ) |
788 | 793 |
789 ## get ## | 794 ## get ## |
790 | 795 |
796 def _mbGetSerialise(self, data): | |
797 items, metadata = data | |
798 items = [data_format.serialise(item) for item in items] | |
799 return items, metadata | |
800 | |
791 def _mbGet(self, service="", node="", max_items=10, item_ids=None, extra_dict=None, | 801 def _mbGet(self, service="", node="", max_items=10, item_ids=None, extra_dict=None, |
792 profile_key=C.PROF_KEY_NONE): | 802 profile_key=C.PROF_KEY_NONE): |
793 """ | 803 """ |
794 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit | 804 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit |
795 @param item_ids (list[unicode]): list of item IDs | 805 @param item_ids (list[unicode]): list of item IDs |
796 """ | 806 """ |
797 client = self.host.getClient(profile_key) | 807 client = self.host.getClient(profile_key) |
798 service = jid.JID(service) if service else None | 808 service = jid.JID(service) if service else None |
799 max_items = None if max_items == C.NO_LIMIT else max_items | 809 max_items = None if max_items == C.NO_LIMIT else max_items |
800 extra = self._p.parseExtra(extra_dict) | 810 extra = self._p.parseExtra(extra_dict) |
801 return self.mbGet( | 811 d = self.mbGet(client, service, node or None, max_items, item_ids, |
802 client, | 812 extra.rsm_request, extra.extra) |
803 service, | 813 d.addCallback(self._mbGetSerialise) |
804 node or None, | 814 return d |
805 max_items, | |
806 item_ids, | |
807 extra.rsm_request, | |
808 extra.extra, | |
809 ) | |
810 | 815 |
811 @defer.inlineCallbacks | 816 @defer.inlineCallbacks |
812 def mbGet(self, client, service=None, node=None, max_items=10, item_ids=None, | 817 def mbGet(self, client, service=None, node=None, max_items=10, item_ids=None, |
813 rsm_request=None, extra=None): | 818 rsm_request=None, extra=None): |
814 """Get some microblogs | 819 """Get some microblogs |
832 max_items=max_items, | 837 max_items=max_items, |
833 item_ids=item_ids, | 838 item_ids=item_ids, |
834 rsm_request=rsm_request, | 839 rsm_request=rsm_request, |
835 extra=extra, | 840 extra=extra, |
836 ) | 841 ) |
837 serialised = yield self._p.serItemsDataD(items_data, self.item2mbdata) | 842 mb_data = yield self._p.transItemsDataD(items_data, self.item2mbdata) |
838 defer.returnValue(serialised) | 843 defer.returnValue(mb_data) |
839 | 844 |
840 def parseCommentUrl(self, node_url): | 845 def parseCommentUrl(self, node_url): |
841 """Parse a XMPP URI | 846 """Parse a XMPP URI |
842 | 847 |
843 Determine the fields comments_service and comments_node of a microblog data | 848 Determine the fields comments_service and comments_node of a microblog data |
920 | 925 |
921 @param publishers_type: type of the list of publishers, one of: | 926 @param publishers_type: type of the list of publishers, one of: |
922 C.ALL: get all jids from roster, publishers is not used | 927 C.ALL: get all jids from roster, publishers is not used |
923 C.GROUP: get jids from groups | 928 C.GROUP: get jids from groups |
924 C.JID: use publishers directly as list of jids | 929 C.JID: use publishers directly as list of jids |
925 @param publishers: list of publishers, according to "publishers_type" (None, list of groups or list of jids) | 930 @param publishers: list of publishers, according to "publishers_type" (None, |
931 list of groups or list of jids) | |
926 @param profile_key: %(doc_profile_key)s | 932 @param profile_key: %(doc_profile_key)s |
927 """ | 933 """ |
928 client = self.host.getClient(profile_key) | 934 client = self.host.getClient(profile_key) |
929 if publishers_type == C.JID: | 935 if publishers_type == C.JID: |
930 jids_set = set(publishers) | 936 jids_set = set(publishers) |
931 else: | 937 else: |
932 jids_set = client.roster.getJidsSet(publishers_type, publishers) | 938 jids_set = client.roster.getJidsSet(publishers_type, publishers) |
933 if publishers_type == C.ALL: | 939 if publishers_type == C.ALL: |
934 try: # display messages from salut-a-toi@libervia.org or other PEP services | 940 try: |
941 # display messages from salut-a-toi@libervia.org or other PEP services | |
935 services = self.host.plugins["EXTRA-PEP"].getFollowedEntities( | 942 services = self.host.plugins["EXTRA-PEP"].getFollowedEntities( |
936 profile_key | 943 profile_key |
937 ) | 944 ) |
938 except KeyError: | 945 except KeyError: |
939 pass # plugin is not loaded | 946 pass # plugin is not loaded |
985 | 992 |
986 @param publishers_type: type of the list of publishers, one of: | 993 @param publishers_type: type of the list of publishers, one of: |
987 C.ALL: get all jids from roster, publishers is not used | 994 C.ALL: get all jids from roster, publishers is not used |
988 C.GROUP: get jids from groups | 995 C.GROUP: get jids from groups |
989 C.JID: use publishers directly as list of jids | 996 C.JID: use publishers directly as list of jids |
990 @param publishers: list of publishers, according to "publishers_type" (None, list of groups or list of jids) | 997 @param publishers: list of publishers, according to "publishers_type" (None, list |
998 of groups or list of jids) | |
991 @param profile: %(doc_profile)s | 999 @param profile: %(doc_profile)s |
992 @return (str): session id | 1000 @return (str): session id |
993 """ | 1001 """ |
994 client, node_data = self._getClientAndNodeData( | 1002 client, node_data = self._getClientAndNodeData( |
995 publishers_type, publishers, profile_key | 1003 publishers_type, publishers, profile_key |
1015 @param profile_key: %(doc_profile_key)s | 1023 @param profile_key: %(doc_profile_key)s |
1016 """ | 1024 """ |
1017 | 1025 |
1018 def onSuccess(items_data): | 1026 def onSuccess(items_data): |
1019 """convert items elements to list of microblog data in items_data""" | 1027 """convert items elements to list of microblog data in items_data""" |
1020 d = self._p.serItemsDataD(items_data, self.item2mbdata) | 1028 d = self._p.transItemsDataD(items_data, self.item2mbdata, serialise=True) |
1021 d.addCallback(lambda serialised: ("", serialised)) | 1029 d.addCallback(lambda serialised: ("", serialised)) |
1022 return d | 1030 return d |
1023 | 1031 |
1024 profile = self.host.getClient(profile_key).profile | 1032 profile = self.host.getClient(profile_key).profile |
1025 d = self._p.getRTResults( | 1033 d = self._p.getRTResults( |
1039 ], | 1047 ], |
1040 ) | 1048 ) |
1041 ) | 1049 ) |
1042 return d | 1050 return d |
1043 | 1051 |
1044 def _mbGetFromMany( | 1052 def _mbGetFromMany(self, publishers_type, publishers, max_items=10, extra_dict=None, |
1045 self, | 1053 profile_key=C.PROF_KEY_NONE): |
1046 publishers_type, | |
1047 publishers, | |
1048 max_items=10, | |
1049 extra_dict=None, | |
1050 profile_key=C.PROF_KEY_NONE, | |
1051 ): | |
1052 """ | 1054 """ |
1053 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit | 1055 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit |
1054 """ | 1056 """ |
1055 max_items = None if max_items == C.NO_LIMIT else max_items | 1057 max_items = None if max_items == C.NO_LIMIT else max_items |
1056 publishers_type, publishers = self._checkPublishers(publishers_type, publishers) | 1058 publishers_type, publishers = self._checkPublishers(publishers_type, publishers) |
1062 extra.rsm_request, | 1064 extra.rsm_request, |
1063 extra.extra, | 1065 extra.extra, |
1064 profile_key, | 1066 profile_key, |
1065 ) | 1067 ) |
1066 | 1068 |
1067 def mbGetFromMany( | 1069 def mbGetFromMany(self, publishers_type, publishers, max_items=None, rsm_request=None, |
1068 self, | 1070 extra=None, profile_key=C.PROF_KEY_NONE): |
1069 publishers_type, | |
1070 publishers, | |
1071 max_items=None, | |
1072 rsm_request=None, | |
1073 extra=None, | |
1074 profile_key=C.PROF_KEY_NONE, | |
1075 ): | |
1076 """Get the published microblogs for a list of groups or jids | 1071 """Get the published microblogs for a list of groups or jids |
1077 | 1072 |
1078 @param publishers_type (str): type of the list of publishers (one of "GROUP" or "JID" or "ALL") | 1073 @param publishers_type (str): type of the list of publishers (one of "GROUP" or |
1079 @param publishers (list): list of publishers, according to publishers_type (list of groups or list of jids) | 1074 "JID" or "ALL") |
1075 @param publishers (list): list of publishers, according to publishers_type (list | |
1076 of groups or list of jids) | |
1080 @param max_items (int): optional limit on the number of retrieved items. | 1077 @param max_items (int): optional limit on the number of retrieved items. |
1081 @param rsm_request (rsm.RSMRequest): RSM request data, common to all publishers | 1078 @param rsm_request (rsm.RSMRequest): RSM request data, common to all publishers |
1082 @param extra (dict): Extra data | 1079 @param extra (dict): Extra data |
1083 @param profile_key: profile key | 1080 @param profile_key: profile key |
1084 @return (str): RT Deferred session id | 1081 @return (str): RT Deferred session id |
1091 node_data, max_items, rsm_request, profile_key=profile_key | 1088 node_data, max_items, rsm_request, profile_key=profile_key |
1092 ) | 1089 ) |
1093 | 1090 |
1094 # comments # | 1091 # comments # |
1095 | 1092 |
1096 def _mbGetFromManyWithCommentsRTResult( | 1093 def _mbGetFromManyWithCommentsRTResultSerialise(self, data): |
1097 self, session_id, profile_key=C.PROF_KEY_DEFAULT | 1094 """Serialisation of result |
1098 ): | 1095 |
1096 This is probably the longest method name of whole SàT ecosystem ^^ | |
1097 @param data(dict): data as received by rt_sessions | |
1098 @return (tuple): see [_mbGetFromManyWithCommentsRTResult] | |
1099 """ | |
1100 ret = [] | |
1101 data_iter = data[1].iteritems() | |
1102 for (service, node), (success, (failure_, (items_data, metadata))) in data_iter: | |
1103 items = [] | |
1104 for item, item_metadata in items_data: | |
1105 item = data_format.serialise(item) | |
1106 items.append((item, item_metadata)) | |
1107 ret.append(( | |
1108 service.full(), | |
1109 node, | |
1110 failure_, | |
1111 items, | |
1112 metadata)) | |
1113 | |
1114 return data[0], ret | |
1115 | |
1116 def _mbGetFromManyWithCommentsRTResult(self, session_id, | |
1117 profile_key=C.PROF_KEY_DEFAULT): | |
1099 """Get real-time results for [mbGetFromManyWithComments] session | 1118 """Get real-time results for [mbGetFromManyWithComments] session |
1100 | 1119 |
1101 @param session_id: id of the real-time deferred session | 1120 @param session_id: id of the real-time deferred session |
1102 @param return (tuple): (remaining, results) where: | 1121 @param return (tuple): (remaining, results) where: |
1103 - remaining is the number of still expected results | 1122 - remaining is the number of still expected results |
1116 - metadata(dict): original node metadata | 1135 - metadata(dict): original node metadata |
1117 @param profile_key: %(doc_profile_key)s | 1136 @param profile_key: %(doc_profile_key)s |
1118 """ | 1137 """ |
1119 profile = self.host.getClient(profile_key).profile | 1138 profile = self.host.getClient(profile_key).profile |
1120 d = self.rt_sessions.getResults(session_id, profile=profile) | 1139 d = self.rt_sessions.getResults(session_id, profile=profile) |
1121 d.addCallback( | 1140 d.addCallback(self._mbGetFromManyWithCommentsRTResultSerialise) |
1122 lambda ret: ( | |
1123 ret[0], | |
1124 [ | |
1125 (service.full(), node, failure, items, metadata) | |
1126 for (service, node), (success, (failure, (items, metadata))) in ret[ | |
1127 1 | |
1128 ].iteritems() | |
1129 ], | |
1130 ) | |
1131 ) | |
1132 return d | 1141 return d |
1133 | 1142 |
1134 def _mbGetFromManyWithComments( | 1143 def _mbGetFromManyWithComments(self, publishers_type, publishers, max_items=10, |
1135 self, | 1144 max_comments=C.NO_LIMIT, extra_dict=None, |
1136 publishers_type, | 1145 extra_comments_dict=None, profile_key=C.PROF_KEY_NONE): |
1137 publishers, | |
1138 max_items=10, | |
1139 max_comments=C.NO_LIMIT, | |
1140 extra_dict=None, | |
1141 extra_comments_dict=None, | |
1142 profile_key=C.PROF_KEY_NONE, | |
1143 ): | |
1144 """ | 1146 """ |
1145 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit | 1147 @param max_items(int): maximum number of item to get, C.NO_LIMIT for no limit |
1146 @param max_comments(int): maximum number of comments to get, C.NO_LIMIT for no limit | 1148 @param max_comments(int): maximum number of comments to get, C.NO_LIMIT for no |
1149 limit | |
1147 """ | 1150 """ |
1148 max_items = None if max_items == C.NO_LIMIT else max_items | 1151 max_items = None if max_items == C.NO_LIMIT else max_items |
1149 max_comments = None if max_comments == C.NO_LIMIT else max_comments | 1152 max_comments = None if max_comments == C.NO_LIMIT else max_comments |
1150 publishers_type, publishers = self._checkPublishers(publishers_type, publishers) | 1153 publishers_type, publishers = self._checkPublishers(publishers_type, publishers) |
1151 extra = self._p.parseExtra(extra_dict) | 1154 extra = self._p.parseExtra(extra_dict) |
1160 extra_comments.rsm_request, | 1163 extra_comments.rsm_request, |
1161 extra_comments.extra, | 1164 extra_comments.extra, |
1162 profile_key, | 1165 profile_key, |
1163 ) | 1166 ) |
1164 | 1167 |
1165 def mbGetFromManyWithComments( | 1168 def mbGetFromManyWithComments(self, publishers_type, publishers, max_items=None, |
1166 self, | 1169 max_comments=None, rsm_request=None, extra=None, |
1167 publishers_type, | 1170 rsm_comments=None, extra_comments=None, |
1168 publishers, | 1171 profile_key=C.PROF_KEY_NONE): |
1169 max_items=None, | |
1170 max_comments=None, | |
1171 rsm_request=None, | |
1172 extra=None, | |
1173 rsm_comments=None, | |
1174 extra_comments=None, | |
1175 profile_key=C.PROF_KEY_NONE, | |
1176 ): | |
1177 """Helper method to get the microblogs and their comments in one shot | 1172 """Helper method to get the microblogs and their comments in one shot |
1178 | 1173 |
1179 @param publishers_type (str): type of the list of publishers (one of "GROUP" or "JID" or "ALL") | 1174 @param publishers_type (str): type of the list of publishers (one of "GROUP" or |
1180 @param publishers (list): list of publishers, according to publishers_type (list of groups or list of jids) | 1175 "JID" or "ALL") |
1176 @param publishers (list): list of publishers, according to publishers_type (list | |
1177 of groups or list of jids) | |
1181 @param max_items (int): optional limit on the number of retrieved items. | 1178 @param max_items (int): optional limit on the number of retrieved items. |
1182 @param max_comments (int): maximum number of comments to retrieve | 1179 @param max_comments (int): maximum number of comments to retrieve |
1183 @param rsm_request (rsm.RSMRequest): RSM request for initial items only | 1180 @param rsm_request (rsm.RSMRequest): RSM request for initial items only |
1184 @param extra (dict): extra configuration for initial items only | 1181 @param extra (dict): extra configuration for initial items only |
1185 @param rsm_comments (rsm.RSMRequest): RSM request for comments only | 1182 @param rsm_comments (rsm.RSMRequest): RSM request for comments only |
1221 rsm_request=rsm_comments, | 1218 rsm_request=rsm_comments, |
1222 extra=extra_comments, | 1219 extra=extra_comments, |
1223 ) | 1220 ) |
1224 # then serialise | 1221 # then serialise |
1225 d.addCallback( | 1222 d.addCallback( |
1226 lambda items_data: self._p.serItemsDataD( | 1223 lambda items_data: self._p.transItemsDataD( |
1227 items_data, self.item2mbdata | 1224 items_data, self.item2mbdata, serialise=True |
1228 ) | 1225 ) |
1229 ) | 1226 ) |
1230 # with failure handling | 1227 # with failure handling |
1231 d.addCallback( | 1228 d.addCallback( |
1232 lambda serialised_items_data: ("",) + serialised_items_data | 1229 lambda serialised_items_data: ("",) + serialised_items_data |
1233 ) | 1230 ) |
1234 d.addErrback(lambda failure: (unicode(failure.value), [], {})) | 1231 d.addErrback(lambda failure: (unicode(failure.value), [], {})) |
1235 # and associate with service/node (needed if there are several comments nodes) | 1232 # and associate with service/node (needed if there are several |
1233 # comments nodes) | |
1236 d.addCallback( | 1234 d.addCallback( |
1237 lambda serialised, service_s=service_s, node=node: ( | 1235 lambda serialised, service_s=service_s, node=node: ( |
1238 service_s, | 1236 service_s, |
1239 node, | 1237 node, |
1240 ) | 1238 ) |
1258 for service, node in node_data: | 1256 for service, node in node_data: |
1259 d = deferreds[(service, node)] = self._p.getItems( | 1257 d = deferreds[(service, node)] = self._p.getItems( |
1260 client, service, node, max_items, rsm_request=rsm_request, extra=extra | 1258 client, service, node, max_items, rsm_request=rsm_request, extra=extra |
1261 ) | 1259 ) |
1262 d.addCallback( | 1260 d.addCallback( |
1263 lambda items_data: self._p.serItemsDataD(items_data, self.item2mbdata) | 1261 lambda items_data: self._p.transItemsDataD(items_data, self.item2mbdata) |
1264 ) | 1262 ) |
1265 d.addCallback(getComments) | 1263 d.addCallback(getComments) |
1266 d.addCallback(lambda items_comments_data: ("", items_comments_data)) | 1264 d.addCallback(lambda items_comments_data: ("", items_comments_data)) |
1267 d.addErrback(lambda failure: (unicode(failure.value), ([], {}))) | 1265 d.addErrback(lambda failure: (unicode(failure.value), ([], {}))) |
1268 | 1266 |