plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
This commit is contained in:
parent
728e15c90c
commit
af953d89a9
1 changed files with 51 additions and 33 deletions
|
|
@ -31,6 +31,7 @@ from twisted.words.xish import domish
|
|||
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 @@ PLUGIN_INFO = {
|
|||
|
||||
|
||||
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 @@ class XEP_0234(object):
|
|||
# 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 @@ class XEP_0234(object):
|
|||
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 @@ class XEP_0234(object):
|
|||
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 @@ class XEP_0234(object):
|
|||
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 @@ class XEP_0234(object):
|
|||
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 @@ class XEP_0234(object):
|
|||
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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue