Mercurial > libervia-backend
diff src/plugins/plugin_xep_0234.py @ 1571:c668081eba1c
plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 08 Nov 2015 14:48:04 +0100 |
parents | 1f7a34d499e0 |
children | babd97d80049 |
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0234.py Sun Nov 08 14:44:33 2015 +0100 +++ b/src/plugins/plugin_xep_0234.py Sun Nov 08 14:48:04 2015 +0100 @@ -31,6 +31,7 @@ from twisted.words.protocols.jabber import jid from twisted.python import failure from twisted.words.protocols.jabber.xmlstream import XMPPHandler +from twisted.internet import defer NS_JINGLE_FT = 'urn:xmpp:jingle:apps:file-transfer:4' @@ -52,6 +53,7 @@ class XEP_0234(object): + # TODO: assure everything is closed when file is sent or session terminate is received def __init__(self, host): log.info(_("plugin Jingle File Transfer initialization")) @@ -81,11 +83,12 @@ # Dialogs with user # the overwrite check is done here - def _getDestDir(self, session, content_data, profile): + def _getDestDir(self, session, content_name, content_data, profile): """Request confirmation and destination dir to user if transfer is confirmed, session is filled @param session(dict): jingle session data + @param content_name(unicode): name of the jingle content @param content_data(dict): content informations @param profile: %(doc_profile)s return (defer.Deferred): True if transfer is accepted @@ -98,23 +101,31 @@ type_=C.XMLUI_DIALOG_FILE, options={C.XMLUI_DATA_FILETYPE: C.XMLUI_DATA_FILETYPE_DIR}, profile=profile) - d.addCallback(self._gotConfirmation, session, content_data, application_data, profile) + d.addCallback(self._gotConfirmation, session, content_name, content_data, application_data, profile) return d - def _openFileWrite(self, content_data, file_path, file_data, profile): + def _openFileWrite(self, session, content_name, content_data, file_path, file_data, profile): assert 'file_obj' not in content_data - content_data['file_obj'] = self._f.File( + file_obj = content_data['file_obj'] = self._f.File( self.host, file_path, 'w', size=file_data['size'], profile=profile, ) + finished_d = content_data['finished_d'] = defer.Deferred() + args = [file_obj, session, content_name, content_data, profile] + finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args) - def _gotConfirmation(self, data, session, content_data, application_data, profile): + def _gotConfirmation(self, data, session, content_name, content_data, application_data, profile): """Called when the permission and dest path have been received @param data(dict): xmlui data received from file dialog + @param session(dict): jingle session data + @param content_name(unicode): name of the jingle content + @param content_data(dict): content session_data + @param content_data(dict): application session data + @param profile: %(doc_profile)s return (bool): True if copy is wanted and OK False if user wants to cancel if fill exists ask confirmation and call again self._getDestDir if needed @@ -130,10 +141,10 @@ if os.path.exists(file_path): def check_overwrite(overwrite): if overwrite: - self._openFileWrite(content_data, file_path, file_data, profile) + self._openFileWrite(session, content_name, content_data, file_path, file_data, profile) return True else: - return self._getDestDir(session, content_data, profile) + return self._getDestDir(session, content_name, content_data, profile) exists_d = xml_tools.deferConfirm( self.host, @@ -143,7 +154,7 @@ exists_d.addCallback(check_overwrite) return exists_d - self._openFileWrite(content_data, file_path, file_data, profile) + self._openFileWrite(session, content_name, content_data, file_path, file_data, profile) return True # jingle callbacks @@ -203,7 +214,7 @@ content_data['application_data']['file_data'] = file_data # now we actualy request permission to user - return self._getDestDir(session, content_data, profile) + return self._getDestDir(session, content_name, content_data, profile) def jingleHandler(self, action, session, content_name, desc_elt, profile): @@ -228,11 +239,26 @@ size=size, profile=profile ) - file_obj.eof.addCallback(lambda dummy: file_obj.close()) + finished_d = content_data['finished_d'] = defer.Deferred() + args = [file_obj, session, content_name, content_data, profile] + finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args) else: log.warning(u"FIXME: unmanaged action {}".format(action)) return desc_elt + def _finishedCb(self, dummy, file_obj, session, content_name, content_data, profile): + log.debug(u"File transfer completed successfuly") + if content_data['senders'] != session['role']: + # we terminate the session only if we are the received, + # as recommanded in XEP-0234 ยง2 (after example 6) + self._j.contentTerminate(session, content_name, profile=profile) + file_obj.close() + + def _finishedEb(self, failure, file_obj, session, content_name, content_data, profile): + log.warning(u"Error while streaming through s5b: {}".format(failure)) + file_obj.close() + self._j.contentTerminate(session, content_name, reason=self._j.REASON_FAILED_TRANSPORT, profile=profile) + class XEP_0234_handler(XMPPHandler): implements(iwokkel.IDisco)