diff sat/plugins/plugin_xep_0277.py @ 3328:d49607e3a066

plugin XEP-0277: set "uri" in item2mbdata
author Goffi <goffi@goffi.org>
date Mon, 03 Aug 2020 08:45:49 +0200
parents 384283adcce1
children 13b91b7280bc
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0277.py	Sun Aug 02 20:31:06 2020 +0200
+++ b/sat/plugins/plugin_xep_0277.py	Mon Aug 03 08:45:49 2020 +0200
@@ -16,31 +16,36 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from sat.core.i18n import _
-from sat.core.constants import Const as C
-from sat.core.log import getLogger
+import shortuuid
+import time
+import dateutil
+import calendar
+import urllib.parse
+from typing import Optional
+from functools import partial
 
 from twisted.words.protocols.jabber import jid, error
 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
 from twisted.words.xish import domish
 from twisted.internet import defer
 from twisted.python import failure
+
+# XXX: sat_tmp.wokkel.pubsub is actually used instead of wokkel version
+from wokkel import pubsub
+from wokkel import disco, iwokkel
+from zope.interface import implementer
+
+from sat.core.i18n import _
+from sat.core.constants import Const as C
+from sat.core.log import getLogger
 from sat.core import exceptions
+from sat.core.xmpp import SatXMPPEntity
 from sat.tools import xml_tools
 from sat.tools import sat_defer
 from sat.tools import utils
 from sat.tools.common import data_format
 from sat.tools.common import uri as xmpp_uri
 
-# XXX: sat_tmp.wokkel.pubsub is actually used instead of wokkel version
-from wokkel import pubsub
-from wokkel import disco, iwokkel
-from zope.interface import implementer
-import shortuuid
-import time
-import dateutil
-import calendar
-import urllib.parse
 
 log = getLogger(__name__)
 
@@ -185,7 +190,8 @@
 
         for item in itemsEvent.items:
             if item.name == C.PS_ITEM:
-                self.item2mbdata(item).addCallbacks(
+                # FIXME: service and node should be used here
+                self.item2mbdata(client, item).addCallbacks(
                     manageItem, lambda failure: None, (C.PS_PUBLISH,)
                 )
             elif item.name == C.PS_RETRACT:
@@ -196,11 +202,23 @@
     ## data/item transformation ##
 
     @defer.inlineCallbacks
-    def item2mbdata(self, item_elt):
+    def item2mbdata(
+        self,
+        client: SatXMPPEntity,
+        item_elt: domish.Element,
+        service: Optional[jid.JID],
+        # FIXME: node is Optional until all calls to item2mbdata set properly service
+        #   and node. Once done, the Optional must be removed here
+        node: Optional[str]
+    ) -> dict:
         """Convert an XML Item to microblog data
 
-        @param item_elt: domish.Element of microblog item
-        @return: microblog data (dictionary)
+        @param item_elt: microblog item element
+        @param service: PubSub service where the item has been retrieved
+            profile's PEP is used when service is None
+        @param node: PubSub node where the item has been retrieved
+            if None, "uri" won't be set
+        @return: microblog data
         """
         microblog_data = {}
 
@@ -273,6 +291,16 @@
             msg = "No atom entry found in the pubsub item {}".format(id_)
             raise failure.Failure(exceptions.DataError(msg))
 
+        # uri
+        # FIXME: node should alway be set in the future, check FIXME in method signature
+        if node is not None:
+            microblog_data['uri'] = xmpp_uri.buildXMPPUri(
+                "pubsub",
+                path=service.full() if service is not None else client.jid.userhost(),
+                node=node,
+                item=id_,
+            )
+
         # language
         try:
             microblog_data["language"] = entry_elt[(C.NS_XML, "lang")].strip()
@@ -857,7 +885,7 @@
             extra=extra,
         )
         mb_data = yield self._p.transItemsDataD(
-            items_data, self.item2mbdata)
+            items_data, partial(self.item2mbdata, client, service=service, node=node))
         defer.returnValue(mb_data)
 
     def parseCommentUrl(self, node_url):
@@ -1041,18 +1069,24 @@
         @param profile_key: %(doc_profile_key)s
         """
 
+        client = self.host.getClient(profile_key)
+
         def onSuccess(items_data):
             """convert items elements to list of microblog data in items_data"""
-            d = self._p.transItemsDataD(items_data, self.item2mbdata, serialise=True)
+            d = self._p.transItemsDataD(
+                items_data,
+                # FIXME: service and node should be used here
+                partial(self.item2mbdata, client),
+                serialise=True
+            )
             d.addCallback(lambda serialised: ("", serialised))
             return d
 
-        profile = self.host.getClient(profile_key).profile
         d = self._p.getRTResults(
             session_id,
             on_success=onSuccess,
             on_error=lambda failure: (str(failure.value), ([], {})),
-            profile=profile,
+            profile=client.profile,
         )
         d.addCallback(
             lambda ret: (
@@ -1226,11 +1260,12 @@
                     if key.startswith("comments") and key.endswith("_service"):
                         prefix = key[: key.find("_")]
                         service_s = value
+                        service = jid.JID(service_s)
                         node = item["{}{}".format(prefix, "_node")]
                         # time to get the comments
                         d = self._p.getItems(
                             client,
-                            jid.JID(service_s),
+                            service,
                             node,
                             max_comments,
                             rsm_request=rsm_comments,
@@ -1239,7 +1274,11 @@
                         # then serialise
                         d.addCallback(
                             lambda items_data: self._p.transItemsDataD(
-                                items_data, self.item2mbdata, serialise=True
+                                items_data,
+                                partial(
+                                    self.item2mbdata, client, service=service, node=node
+                                ),
+                                serialise=True
                             )
                         )
                         # with failure handling
@@ -1277,7 +1316,9 @@
             )
             d.addCallback(
                 lambda items_data: self._p.transItemsDataD(
-                    items_data, self.item2mbdata)
+                    items_data,
+                    partial(self.item2mbdata, client, service=service, node=node),
+                )
             )
             d.addCallback(getComments)
             d.addCallback(lambda items_comments_data: ("", items_comments_data))