diff sat/plugins/plugin_xep_0234.py @ 3403:404d4b29de52

plugin file, XEP-0234: registering is now done by class + use of async: - instead of registering a callback, a file sending manager now register itself and must implement some well known method (`fileSend`, `canHandleFileSend`) and optionally a `name` attribute - `utils.asDeferred` is now used for callbacks, so all type of methods including coroutines can be used. - feature checking is now handled by `canHandleFileSend` method instead of simple namespace check, this allows to use a method when namespace can't be checked (this is the case when a file is sent to a bare jid with jingle)
author Goffi <goffi@goffi.org>
date Thu, 12 Nov 2020 14:53:15 +0100
parents 3dc8835d96cc
children 26a0af6e32c1
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0234.py	Thu Nov 12 14:53:15 2020 +0100
+++ b/sat/plugins/plugin_xep_0234.py	Thu Nov 12 14:53:15 2020 +0100
@@ -16,18 +16,10 @@
 # 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
-
-log = getLogger(__name__)
-from sat.core import exceptions
-from wokkel import disco, iwokkel
+import os.path
+import mimetypes
+from collections import namedtuple
 from zope.interface import implementer
-from sat.tools import utils
-from sat.tools import stream
-from sat.tools.common import date_utils
-import os.path
 from twisted.words.xish import domish
 from twisted.words.protocols.jabber import jid
 from twisted.python import failure
@@ -35,10 +27,18 @@
 from twisted.internet import defer
 from twisted.internet import reactor
 from twisted.internet import error as internet_error
-from collections import namedtuple
+from wokkel import disco, iwokkel
+from sat.core.i18n import _, D_
+from sat.core.constants import Const as C
+from sat.core.log import getLogger
+from sat.core import exceptions
+from sat.tools import utils
+from sat.tools import stream
+from sat.tools.common import date_utils
 from sat.tools.common import regex
-import mimetypes
+
 
+log = getLogger(__name__)
 
 NS_JINGLE_FT = "urn:xmpp:jingle:apps:file-transfer:5"
 
@@ -58,10 +58,13 @@
 Range = namedtuple("Range", ("offset", "length"))
 
 
-class XEP_0234(object):
+class XEP_0234:
     # TODO: assure everything is closed when file is sent or session terminate is received
-    # TODO: call self._f.unregister when unloading order will be managing (i.e. when dependencies will be unloaded at the end)
+    # TODO: call self._f.unregister when unloading order will be managing (i.e. when
+    #   dependencies will be unloaded at the end)
     Range = Range  # we copy the class here, so it can be used by other plugins
+    name = PLUGIN_INFO[C.PI_NAME]
+    human_name = D_("file transfer")
 
     def __init__(self, host):
         log.info(_("plugin Jingle File Transfer initialization"))
@@ -70,16 +73,14 @@
         self._j = host.plugins["XEP-0166"]  # shortcut to access jingle
         self._j.registerApplication(NS_JINGLE_FT, self)
         self._f = host.plugins["FILE"]
-        self._f.register(
-            NS_JINGLE_FT, self.fileJingleSend, priority=10000, method_name="Jingle"
-        )
+        self._f.register(self, priority=10000)
         self._hash = self.host.plugins["XEP-0300"]
         host.bridge.addMethod(
             "fileJingleSend",
             ".plugin",
             in_sign="ssssa{ss}s",
             out_sign="",
-            method=self._fileJingleSend,
+            method=self._fileSend,
             async_=True,
         )
         host.bridge.addMethod(
@@ -103,6 +104,13 @@
         """
         return "{}_{}".format(session["id"], content_name)
 
+    async def canHandleFileSend(self, client, peer_jid, filepath):
+        if peer_jid.resource:
+            return await self.host.hasFeature(client, NS_JINGLE_FT, peer_jid)
+        else:
+            # if we have a bare jid, Jingle Message Initiation will be tried
+            return True
+
     # generic methods
 
     def buildFileElement(
@@ -286,7 +294,7 @@
 
     # bridge methods
 
-    def _fileJingleSend(
+    def _fileSend(
         self,
         peer_jid,
         filepath,
@@ -296,17 +304,16 @@
         profile=C.PROF_KEY_NONE,
     ):
         client = self.host.getClient(profile)
-        return self.fileJingleSend(
+        return defer.ensureDeferred(self.fileSend(
             client,
             jid.JID(peer_jid),
             filepath,
             name or None,
             file_desc or None,
             extra or None,
-        )
+        ))
 
-    @defer.inlineCallbacks
-    def fileJingleSend(
+    async def fileSend(
         self, client, peer_jid, filepath, name, file_desc=None, extra=None
     ):
         """Send a file using jingle file transfer
@@ -322,7 +329,7 @@
             extra = {}
         if file_desc is not None:
             extra["file_desc"] = file_desc
-        yield self._j.initiate(
+        await self._j.initiate(
             client,
             peer_jid,
             [
@@ -338,8 +345,7 @@
                 }
             ],
         )
-        progress_id = yield progress_id_d
-        defer.returnValue(progress_id)
+        return await progress_id_d
 
     def _fileJingleRequest(
             self, peer_jid, filepath, name="", file_hash="", hash_algo="", extra=None,