Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0060.py @ 3308:384283adcce1
plugins XEP-0059, XEP-0060, XEP-0277, XEP-0313: better serialisation:
`data_format.serialise` is now used for `mbGet`, and RSM/MAM values are not transtyped to
strings anymore. A serialised dict is now used, items are put in the `items` key.
Comments handling has been refactored to use a list for the potentially multiple comments
nodes.
`rsm` data are now in a `rsm` key of the dict, and `mam` data are merged with other
metadata.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 16 Jul 2020 09:07:20 +0200 |
parents | 4c98f4972db5 |
children | 77177b13ff54 |
comparison
equal
deleted
inserted
replaced
3307:9f0e28137cd0 | 3308:384283adcce1 |
---|---|
715 metadata = { | 715 metadata = { |
716 "service": service_jid, | 716 "service": service_jid, |
717 "node": node, | 717 "node": node, |
718 "uri": self.getNodeURI(service_jid, node), | 718 "uri": self.getNodeURI(service_jid, node), |
719 } | 719 } |
720 if mam_response is not None: | |
721 # mam_response is a dict with "complete" and "stable" keys | |
722 # we can put them directly in metadata | |
723 metadata.update(mam_response) | |
720 if rsm_request is not None and rsm_response is not None: | 724 if rsm_request is not None and rsm_response is not None: |
721 metadata.update( | 725 metadata['rsm'] = rsm_response.toDict() |
722 { | 726 if mam_response is None: |
723 "rsm_" + key: value | 727 index = rsm_response.index |
724 for key, value in rsm_response.toDict().items() | 728 count = rsm_response.count |
725 } | 729 if index is None or count is None: |
726 ) | 730 # we don't have enough information to know if the data is complete |
727 if mam_response is not None: | 731 # or not |
728 for key, value in mam_response.items(): | 732 metadata["complete"] = None |
729 metadata["mam_" + key] = value | 733 else: |
734 # normally we have a strict equality here but XEP-0059 states | |
735 # that index MAY be approximative, so just in caseā¦ | |
736 metadata["complete"] = index + len(items) >= count | |
737 | |
730 return (items, metadata) | 738 return (items, metadata) |
731 | 739 |
732 d.addCallback(addMetadata) | 740 d.addCallback(addMetadata) |
733 return d | 741 return d |
734 | 742 |
1105 | 1113 |
1106 @param service(jid.JID): PubSub service | 1114 @param service(jid.JID): PubSub service |
1107 @param node(unicode): node | 1115 @param node(unicode): node |
1108 @return (unicode): URI of the node | 1116 @return (unicode): URI of the node |
1109 """ | 1117 """ |
1118 # FIXME: deprecated, use sat.tools.common.uri instead | |
1110 assert service is not None | 1119 assert service is not None |
1111 # XXX: urllib.urlencode use "&" to separate value, while XMPP URL (cf. RFC 5122) | 1120 # XXX: urllib.urlencode use "&" to separate value, while XMPP URL (cf. RFC 5122) |
1112 # use ";" as a separator. So if more than one value is used in query_data, | 1121 # use ";" as a separator. So if more than one value is used in query_data, |
1113 # urlencode MUST NOT BE USED. | 1122 # urlencode MUST NOT BE USED. |
1114 query_data = [("node", node.encode("utf-8"))] | 1123 query_data = [("node", node.encode("utf-8"))] |
1125 def getRTResults( | 1134 def getRTResults( |
1126 self, session_id, on_success=None, on_error=None, profile=C.PROF_KEY_NONE | 1135 self, session_id, on_success=None, on_error=None, profile=C.PROF_KEY_NONE |
1127 ): | 1136 ): |
1128 return self.rt_sessions.getResults(session_id, on_success, on_error, profile) | 1137 return self.rt_sessions.getResults(session_id, on_success, on_error, profile) |
1129 | 1138 |
1130 def transItemsData(self, items_data, item_cb=lambda item: item.toXml(), | 1139 def transItemsData(self, items_data, item_cb=lambda item: item.toXml()): |
1131 serialise=False): | |
1132 """Helper method to transform result from [getItems] | 1140 """Helper method to transform result from [getItems] |
1141 | |
1142 the items_data must be a tuple(list[domish.Element], dict[unicode, unicode]) | |
1143 as returned by [getItems]. | |
1144 @param items_data(tuple): tuple returned by [getItems] | |
1145 @param item_cb(callable): method to transform each item | |
1146 @return (tuple): a serialised form ready to go throught bridge | |
1147 """ | |
1148 items, metadata = items_data | |
1149 items = [item_cb(item) for item in items] | |
1150 | |
1151 return (items, metadata) | |
1152 | |
1153 def transItemsDataD(self, items_data, item_cb): | |
1154 """Helper method to transform result from [getItems], deferred version | |
1133 | 1155 |
1134 the items_data must be a tuple(list[domish.Element], dict[unicode, unicode]) | 1156 the items_data must be a tuple(list[domish.Element], dict[unicode, unicode]) |
1135 as returned by [getItems]. metadata values are then casted to unicode and | 1157 as returned by [getItems]. metadata values are then casted to unicode and |
1136 each item is passed to items_cb then optionally serialised with | 1158 each item is passed to items_cb. |
1137 data_format.serialise. | |
1138 @param items_data(tuple): tuple returned by [getItems] | |
1139 @param item_cb(callable): method to transform each item | |
1140 @param serialise(bool): if True do a data_format.serialise | |
1141 after applying item_cb | |
1142 @return (tuple): a serialised form ready to go throught bridge | |
1143 """ | |
1144 items, metadata = items_data | |
1145 if serialise: | |
1146 items = [data_format.serialise(item_cb(item)) for item in items] | |
1147 else: | |
1148 items = [item_cb(item) for item in items] | |
1149 | |
1150 return ( | |
1151 items, | |
1152 {key: str(value) for key, value in metadata.items()}, | |
1153 ) | |
1154 | |
1155 def transItemsDataD(self, items_data, item_cb, serialise=False): | |
1156 """Helper method to transform result from [getItems], deferred version | |
1157 | |
1158 the items_data must be a tuple(list[domish.Element], dict[unicode, unicode]) | |
1159 as returned by [getItems]. metadata values are then casted to unicode and | |
1160 each item is passed to items_cb then optionally serialised with | |
1161 data_format.serialise. | |
1162 An errback is added to item_cb, and when it is fired the value is filtered from | 1159 An errback is added to item_cb, and when it is fired the value is filtered from |
1163 final items | 1160 final items |
1164 @param items_data(tuple): tuple returned by [getItems] | 1161 @param items_data(tuple): tuple returned by [getItems] |
1165 @param item_cb(callable): method to transform each item (must return a deferred) | 1162 @param item_cb(callable): method to transform each item (must return a deferred) |
1166 @param serialise(bool): if True do a data_format.serialise | 1163 @return (tuple): a deferred which fire a dict which can be serialised to go |
1167 after applying item_cb | 1164 throught bridge |
1168 @return (tuple): a deferred which fire a serialised form ready to go throught | |
1169 bridge | |
1170 """ | 1165 """ |
1171 items, metadata = items_data | 1166 items, metadata = items_data |
1172 | 1167 |
1173 def eb(failure_): | 1168 def eb(failure_): |
1174 log.warning(f"Error while serialising/parsing item: {failure_.value}") | 1169 log.warning(f"Error while parsing item: {failure_.value}") |
1175 | 1170 |
1176 d = defer.gatherResults([item_cb(item).addErrback(eb) for item in items]) | 1171 d = defer.gatherResults([item_cb(item).addErrback(eb) for item in items]) |
1177 | 1172 d.addCallback(lambda parsed_items: (parsed_items, metadata)) |
1178 def finishSerialisation(parsed_items): | |
1179 if serialise: | |
1180 items = [data_format.serialise(i) for i in parsed_items if i is not None] | |
1181 else: | |
1182 items = [i for i in parsed_items if i is not None] | |
1183 | |
1184 return ( | |
1185 items, | |
1186 {key: str(value) for key, value in metadata.items()}, | |
1187 ) | |
1188 | |
1189 d.addCallback(finishSerialisation) | |
1190 return d | 1173 return d |
1191 | 1174 |
1192 def serDList(self, results, failure_result=None): | 1175 def serDList(self, results, failure_result=None): |
1193 """Serialise a DeferredList result | 1176 """Serialise a DeferredList result |
1194 | 1177 |