Mercurial > libervia-backend
diff src/plugins/plugin_exp_pipe.py @ 538:2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
- added profile argument to askConfirmation, actionResult, actionResultExt, entityDataUpdated, confirmationAnswer, getProgress
- core, frontends: fixed calls/signals according to new bridge API
- user of proper profile namespace for progression indicators and dialogs
- memory: getParam* now return bool when param type is bool
- memory: added getStringParam* to return string instead of typed value
- core, memory, storage, quick_frontend: getHistory now manage properly multi-profiles
- plugins XEP-0047, XEP-0054, XEP-0065, XEP-0077, XEP-0096; multi-profiles proper handling
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 10 Nov 2012 16:38:16 +0100 |
parents | 2a072735e459 |
children | ca13633d3b6b |
line wrap: on
line diff
--- a/src/plugins/plugin_exp_pipe.py Sun Nov 04 23:53:26 2012 +0100 +++ b/src/plugins/plugin_exp_pipe.py Sat Nov 10 16:38:16 2012 +0100 @@ -21,16 +21,13 @@ from logging import debug, info, warning, error from twisted.words.xish import domish -from twisted.internet import protocol -from twisted.words.protocols.jabber import client, jid +from twisted.words.protocols.jabber import jid from twisted.words.protocols.jabber import error as jab_error import os, os.path from twisted.internet import reactor -import pdb +from sat.core.exceptions import ProfileNotInCacheError -from zope.interface import implements - -from wokkel import disco, iwokkel, data_form +from wokkel import data_form IQ_SET = '/iq[@type="set"]' PROFILE_NAME = "pipe-transfer" @@ -53,19 +50,23 @@ def __init__(self, host): info(_("Plugin Pipe initialization")) self.host = host - self._waiting_for_approval = {} #key = id, value = [transfer data, IdelayedCall Reactor timeout, - # current stream method, [failed stream methods], profile] self.managed_stream_m = [self.host.plugins["XEP-0065"].NAMESPACE, self.host.plugins["XEP-0047"].NAMESPACE] #Stream methods managed self.host.plugins["XEP-0095"].registerSIProfile(PROFILE_NAME, self.transferRequest) host.bridge.addMethod("pipeOut", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self.pipeOut) - def _kill_id(self, approval_id): + def profileConnected(self, profile): + client = self.host.getClient(profile) + client._pipe_waiting_for_approval = {} #key = id, value = [transfer data, IdelayedCall Reactor timeout, + # current stream method, [failed stream methods], profile] + + def _kill_id(self, approval_id, profile): """Delete a waiting_for_approval id, called after timeout - @param approval_id: id of _waiting_for_approval""" + @param approval_id: id of _pipe_waiting_for_approval""" info(_("SI Pipe Transfer: TimeOut reached for id %s") % approval_id); try: - del self._waiting_for_approval[approval_id] + client = self.host.getClient(profile) + del client._pipe_waiting_for_approval[approval_id] except KeyError: warning(_("kill id called on a non existant approval id")) @@ -79,6 +80,9 @@ @param profile: %(doc_profile)s""" info (_("EXP-PIPE file transfer requested")) debug(si_el.toXml()) + client = self.host.getClient(profile) + if not client: + raise ProfileNotInCacheError pipe_elts = filter(lambda elt: elt.name == 'pipe', si_el.elements()) feature_elts = self.host.plugins["XEP-0020"].getFeatureElt(si_el) @@ -107,17 +111,20 @@ #if we are here, the transfer can start, we just need user's agreement data={ "id": iq_id, "from":from_jid } - self._waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id), stream_method, [], profile] + client._pipe_waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id), stream_method, [], profile] - self.host.askConfirmation(si_id, "PIPE_TRANSFER", data, self.confirmationCB) + self.host.askConfirmation(si_id, "PIPE_TRANSFER", data, self.confirmationCB, profile) - def confirmationCB(self, sid, accepted, frontend_data): + def confirmationCB(self, sid, accepted, frontend_data, profile): """Called on confirmation answer @param sid: file transfer session id @param accepted: True if file transfer is accepted @param frontend_data: data sent by frontend""" - data, timeout, stream_method, failed_methods, profile = self._waiting_for_approval[sid] + client = self.host.getClient(profile) + if not client: + raise ProfileNotInCacheError + data, timeout, stream_method, failed_methods, profile = client._pipe_waiting_for_approval[sid] if accepted: if timeout.active(): timeout.cancel() @@ -125,17 +132,17 @@ dest_path = frontend_data['dest_path'] except KeyError: error(_('dest path not found in frontend_data')) - del(self._waiting_for_approval[sid]) + del(client._pipe_waiting_for_approval[sid]) return if stream_method == self.host.plugins["XEP-0065"].NAMESPACE: file_obj = open(dest_path, 'w+') - self.host.plugins["XEP-0065"].prepareToReceive(jid.JID(data['from']), sid, file_obj, None, self._transferSucceeded, self._transferFailed) + self.host.plugins["XEP-0065"].prepareToReceive(jid.JID(data['from']), sid, file_obj, None, self._transferSucceeded, self._transferFailed, profile) elif stream_method == self.host.plugins["XEP-0047"].NAMESPACE: file_obj = open(dest_path, 'w+') - self.host.plugins["XEP-0047"].prepareToReceive(jid.JID(data['from']), sid, file_obj, None, self._transferSucceeded, self._transferFailed) + self.host.plugins["XEP-0047"].prepareToReceive(jid.JID(data['from']), sid, file_obj, None, self._transferSucceeded, self._transferFailed, profile) else: error(_("Unknown stream method, this should not happen at this stage, cancelling transfer")) - del(self._waiting_for_approval[sid]) + del(client._pipe_waiting_for_approval[sid]) return #we can send the iq result @@ -146,29 +153,35 @@ else: debug (_("Transfer [%s] refused"), sid) self.host.plugins["XEP-0095"].sendRejectedError (data["id"], data['from'], profile=profile) - del(self._waiting_for_approval[sid]) + del(client._pipe_waiting_for_approval[sid]) - def _transferSucceeded(self, sid, file_obj, stream_method): + def _transferSucceeded(self, sid, file_obj, stream_method, profile): """Called by the stream method when transfer successfuly finished @param id: stream id""" + client = self.host.getClient(profile) + if not client: + raise ProfileNotInCacheError file_obj.close() info(_('Transfer %s successfuly finished') % sid) - del(self._waiting_for_approval[sid]) + del(client._pipe_waiting_for_approval[sid]) - def _transferFailed(self, sid, file_obj, stream_method, reason): + def _transferFailed(self, sid, file_obj, stream_method, reason, profile): """Called when something went wrong with the transfer @param id: stream id @param reason: can be TIMEOUT, IO_ERROR, PROTOCOL_ERROR""" - data, timeout, stream_method, failed_methods, profile = self._waiting_for_approval[sid] + client = self.host.getClient(profile) + if not client: + raise ProfileNotInCacheError + data, timeout, stream_method, failed_methods, profile = client._pipe_waiting_for_approval[sid] warning(_('Transfer %(id)s failed with stream method %(s_method)s') % { 'id': sid, 's_method': stream_method }) filepath = file_obj.name file_obj.close() #TODO: session remenber (within a time limit) when a stream method fail, and avoid that stream method with full jid for the rest of the session warning(_("All stream methods failed, can't transfer the file")) - del(self._waiting_for_approval[sid]) + del(client._pipe_waiting_for_approval[sid]) - def pipeCb(self, profile, filepath, sid, IQ): + def pipeCb(self, filepath, sid, profile, IQ): if IQ['type'] == "error": stanza_err = jab_error.exceptionFromStanza(IQ) if stanza_err.code == '403' and stanza_err.condition == 'forbidden': @@ -230,13 +243,14 @@ pipe_transfer_elts.append(pipe_elt) sid, offer = self.host.plugins["XEP-0095"].proposeStream(jid.JID(to_jid), PROFILE, feature_elt, pipe_transfer_elts, profile_key = profile) - offer.addCallback(self.pipeCb, profile, filepath, sid) + offer.addCallback(self.pipeCb, filepath, sid, profile) return sid - def sendSuccessCb(self, sid, file_obj, stream_method): + def sendSuccessCb(self, sid, file_obj, stream_method, profile): info(_('Transfer %s successfuly finished') % sid) file_obj.close() - def sendFailureCb(self, sid, file_obj, stream_method, reason): + def sendFailureCb(self, sid, file_obj, stream_method, reason, profile): file_obj.close() - warning(_('Transfer %(id)s failed with stream method %(s_method)s') % { 'id': sid, "s_method": stream_method }) + warning(_('Transfer %(id)s failed with stream method %(s_method)s %(profile)s') % { 'id': sid, "s_method": stream_method, "profile": profile }) +