diff src/plugins/plugin_misc_file.py @ 2502:7ad5f2c4e34a

XEP-0065,XEP-0096,XEP-0166,XEP-0235,XEP-0300: file transfer improvments: huge patch sorry :) many things are improved by this patch, notably: - updated to last protocol changes (urn:xmpp:jingle:apps:file-transfer:5 and urn:xmpp:hashes:2) - XEP-0234: file request implementation - XEP-0234: methods to parse and generate <file> element (can be used by other plugins easily) - XEP-0234: range data is now in a namedtuple - path and namespace can be specified when sending/requesting a file (not standard, but needed for file sharing) - better error/termination handling - trigger points to handle file requests by other plugins - preparation to use file plugins with components
author Goffi <goffi@goffi.org>
date Wed, 28 Feb 2018 18:28:39 +0100
parents e2a7bb875957
children
line wrap: on
line diff
--- a/src/plugins/plugin_misc_file.py	Wed Feb 28 18:28:39 2018 +0100
+++ b/src/plugins/plugin_misc_file.py	Wed Feb 28 18:28:39 2018 +0100
@@ -34,6 +34,7 @@
     C.PI_NAME: "File Tansfer",
     C.PI_IMPORT_NAME: "FILE",
     C.PI_TYPE: C.PLUG_TYPE_MISC,
+    C.PI_MODES: C.PLUG_MODE_BOTH,
     C.PI_MAIN: "FilePlugin",
     C.PI_HANDLER: "no",
     C.PI_DESCRIPTION: _("""File Tansfer Management:
@@ -58,16 +59,16 @@
     def __init__(self, host):
         log.info(_("plugin File initialization"))
         self.host = host
-        host.bridge.addMethod("fileSend", ".plugin", in_sign='sssss', out_sign='a{ss}', method=self._fileSend, async=True)
+        host.bridge.addMethod("fileSend", ".plugin", in_sign='ssssa{ss}s', out_sign='a{ss}', method=self._fileSend, async=True)
         self._file_callbacks = []
         host.importMenu((D_("Action"), D_("send file")), self._fileSendMenu, security_limit=10, help_string=D_("Send a file"), type_=C.MENU_SINGLE)
 
-    def _fileSend(self, peer_jid_s, filepath, name="", file_desc="", profile=C.PROF_KEY_NONE):
+    def _fileSend(self, peer_jid_s, filepath, name="", file_desc="", extra=None, profile=C.PROF_KEY_NONE):
         client = self.host.getClient(profile)
-        return self.fileSend(client, jid.JID(peer_jid_s), filepath, name or None, file_desc or None)
+        return self.fileSend(client, jid.JID(peer_jid_s), filepath, name or None, file_desc or None, extra)
 
     @defer.inlineCallbacks
-    def fileSend(self, client, peer_jid, filepath, filename=None, file_desc=None):
+    def fileSend(self, client, peer_jid, filepath, filename=None, file_desc=None, extra=None):
         """Send a file using best available method
 
         @param peer_jid(jid.JID): jid of the destinee
@@ -85,7 +86,7 @@
             has_feature = yield self.host.hasFeature(client, namespace, peer_jid)
             if has_feature:
                 log.info(u"{name} method will be used to send the file".format(name=method_name))
-                progress_id = yield callback(client, peer_jid, filepath, filename, file_desc)
+                progress_id = yield callback(client, peer_jid, filepath, filename, file_desc, extra)
                 defer.returnValue({'progress': progress_id})
         msg = u"Can't find any method to send file to {jid}".format(jid=peer_jid.full())
         log.warning(msg)
@@ -143,7 +144,9 @@
     # Dialogs with user
     # the overwrite check is done here
 
-    def _openFileWrite(self, client, file_path, transfer_data, file_data, stream_object):
+    def openFileWrite(self, client, file_path, transfer_data, file_data, stream_object):
+        """create SatFile or FileStremaObject for the requested file and fill suitable data
+        """
         if stream_object:
             assert 'stream_object' not in transfer_data
             transfer_data['stream_object'] = stream.FileStreamObject(
@@ -188,7 +191,7 @@
         if os.path.exists(file_path):
             def check_overwrite(overwrite):
                 if overwrite:
-                    self._openFileWrite(client, file_path, transfer_data, file_data, stream_object)
+                    self.openFileWrite(client, file_path, transfer_data, file_data, stream_object)
                     return True
                 else:
                     return self.getDestDir(client, peer_jid, transfer_data, file_data)
@@ -206,7 +209,7 @@
             exists_d.addCallback(check_overwrite)
             return exists_d
 
-        self._openFileWrite(client, file_path, transfer_data, file_data, stream_object)
+        self.openFileWrite(client, file_path, transfer_data, file_data, stream_object)
         return True
 
     def getDestDir(self, client, peer_jid, transfer_data, file_data, stream_object=False):
@@ -236,6 +239,9 @@
             a stream.FileStreamObject will be used
         return (defer.Deferred): True if transfer is accepted
         """
+        cont,ret_value = self.host.trigger.returnPoint("FILE_getDestDir", client, peer_jid, transfer_data, file_data, stream_object)
+        if not cont:
+            return ret_value
         filename = file_data['name']
         assert filename and not '/' in filename
         assert PROGRESS_ID_KEY in file_data