plugin XEP-0050: renamed "requestCommandsList" method to "list" + added a run command + fixes:
- XMLUI cancellation is fixed - when called from bridge, "list" (adHocList) command doesn't prepend instructions
This commit is contained in:
parent
fc08583152
commit
a68772cdeb
1 changed files with 69 additions and 21 deletions
|
|
@ -215,8 +215,11 @@ class XEP_0050(object):
|
|||
self.host = host
|
||||
self.requesting = Sessions()
|
||||
self.answering = {}
|
||||
host.bridge.addMethod("requestCommand", ".plugin", in_sign='ss', out_sign='s',
|
||||
method=self._requestCommandsList,
|
||||
host.bridge.addMethod("adHocRun", ".plugin", in_sign='sss', out_sign='s',
|
||||
method=self._run,
|
||||
async=True)
|
||||
host.bridge.addMethod("adHocList", ".plugin", in_sign='ss', out_sign='s',
|
||||
method=self._list,
|
||||
async=True)
|
||||
self.__requesting_id = host.registerCallback(self._requestingEntity, with_data=True)
|
||||
host.importMenu((D_("Service"), D_("Commands")), self._commandsMenu, security_limit=2, help_string=D_("Execute ad-hoc commands"))
|
||||
|
|
@ -233,12 +236,13 @@ class XEP_0050(object):
|
|||
except KeyError:
|
||||
pass
|
||||
|
||||
def _items2XMLUI(self, items):
|
||||
def _items2XMLUI(self, items, no_instructions):
|
||||
""" Convert discovery items to XMLUI dialog """
|
||||
# TODO: manage items on different jids
|
||||
form_ui = xml_tools.XMLUI("form", submit_id=self.__requesting_id)
|
||||
|
||||
form_ui.addText(_("Please select a command"), 'instructions')
|
||||
if not no_instructions:
|
||||
form_ui.addText(_("Please select a command"), 'instructions')
|
||||
|
||||
options = [(item.nodeIdentifier, item.name) for item in items]
|
||||
form_ui.addList("node", options)
|
||||
|
|
@ -331,6 +335,16 @@ class XEP_0050(object):
|
|||
return xml_tools.dataForm2XMLUI(form, self.__requesting_id, session_id=session_id)
|
||||
|
||||
def _requestingEntity(self, data, profile):
|
||||
def serialise(ret_data):
|
||||
if 'xmlui' in ret_data:
|
||||
ret_data['xmlui'] = ret_data['xmlui'].toXml()
|
||||
return ret_data
|
||||
|
||||
d = self.requestingEntity(data, profile)
|
||||
d.addCallback(serialise)
|
||||
return d
|
||||
|
||||
def requestingEntity(self, data, profile):
|
||||
"""
|
||||
request and entity and create XMLUI accordingly
|
||||
@param data: data returned by previous XMLUI (first one must come from self._commandsMenu)
|
||||
|
|
@ -338,25 +352,28 @@ class XEP_0050(object):
|
|||
@return: callback dict result (with "xmlui" corresponding to the answering dialog, or empty if it's finished without error)
|
||||
|
||||
"""
|
||||
if C.bool(data.get('cancelled', C.BOOL_FALSE)):
|
||||
return defer.succeed({})
|
||||
client = self.host.getClient(profile)
|
||||
# TODO: cancel, prev and next are not managed
|
||||
# TODO: managed answerer errors
|
||||
# TODO: manage nodes with a non data form payload
|
||||
if "session_id" not in data:
|
||||
# we just had the jid, we now request it for the available commands
|
||||
session_id, session_data = self.requesting.newSession(profile=profile)
|
||||
session_id, session_data = self.requesting.newSession(profile=client.profile)
|
||||
entity = jid.JID(data[xml_tools.SAT_FORM_PREFIX+'jid'])
|
||||
session_data['jid'] = entity
|
||||
d = self.requestCommandsList(entity, profile)
|
||||
d = self.list(client, entity)
|
||||
|
||||
def sendItems(xmlui):
|
||||
xmlui.session_id = session_id # we need to keep track of the session
|
||||
return {'xmlui': xmlui.toXml()}
|
||||
return {'xmlui': xmlui}
|
||||
|
||||
d.addCallback(sendItems)
|
||||
else:
|
||||
# we have started a several forms sessions
|
||||
try:
|
||||
session_data = self.requesting.profileGet(data["session_id"], profile)
|
||||
session_data = self.requesting.profileGet(data["session_id"], client.profile)
|
||||
except KeyError:
|
||||
log.warning ("session id doesn't exist, session has probably expired")
|
||||
# TODO: send error dialog
|
||||
|
|
@ -370,8 +387,6 @@ class XEP_0050(object):
|
|||
# it's the first time we know the node, we save it in session data
|
||||
session_data['node'] = data[xml_tools.SAT_FORM_PREFIX+'node']
|
||||
|
||||
client = self.host.getClient(profile)
|
||||
|
||||
# we request execute node's command
|
||||
iq_elt = compat.IQ(client.xmlstream, 'set')
|
||||
iq_elt['to'] = entity.full()
|
||||
|
|
@ -388,7 +403,7 @@ class XEP_0050(object):
|
|||
command_elt.addChild(xml_tools.XMLUIResultToElt(data)) # We add the XMLUI result to the command payload
|
||||
d = iq_elt.send()
|
||||
d.addCallback(self._commandsAnswer2XMLUI, session_id, session_data)
|
||||
d.addCallback(lambda xmlui: {'xmlui': xmlui.toXml()} if xmlui is not None else {})
|
||||
d.addCallback(lambda xmlui: {'xmlui': xmlui} if xmlui is not None else {})
|
||||
|
||||
return d
|
||||
|
||||
|
|
@ -446,24 +461,57 @@ class XEP_0050(object):
|
|||
|
||||
return (payload, status, None, note)
|
||||
|
||||
def _requestCommandsList(self, to_jid_s, profile_key):
|
||||
d = self.requestCommandsList(jid.JID(to_jid_s), profile_key)
|
||||
def _run(self, service_jid_s='', node='', profile_key=C.PROF_KEY_NONE):
|
||||
client = self.host.getClient(profile_key)
|
||||
service_jid = jid.JID(service_jid_s) if service_jid_s else None
|
||||
d = self.run(client, service_jid, node or None)
|
||||
d.addCallback(lambda xmlui: xmlui.toXml())
|
||||
return d
|
||||
|
||||
def requestCommandsList(self, to_jid, profile_key):
|
||||
""" Request available commands
|
||||
@param to_jid: the entity answering the commands
|
||||
@param profile_key: %(doc_profile)s
|
||||
@defer.inlineCallbacks
|
||||
def run(self, client, service_jid=None, node=None):
|
||||
"""run an ad-hoc command
|
||||
|
||||
@param service_jid(jid.JID, None): jid of the ad-hoc service
|
||||
None to use profile's server
|
||||
@param node(unicode, None): node of the ad-hoc commnad
|
||||
None to get initial list
|
||||
@return(unicode): command page XMLUI
|
||||
"""
|
||||
if service_jid is None:
|
||||
service_jid = jid.JID(client.jid.host)
|
||||
session_id, session_data = self.requesting.newSession(profile=client.profile)
|
||||
session_data['jid'] = service_jid
|
||||
if node is None:
|
||||
xmlui = yield self.list(client, service_jid)
|
||||
else:
|
||||
session_data['node'] = node
|
||||
cb_data = yield self.requestingEntity({'session_id': session_id}, client.profile)
|
||||
xmlui = cb_data['xmlui']
|
||||
|
||||
xmlui.session_id = session_id
|
||||
defer.returnValue(xmlui)
|
||||
|
||||
def _list(self, to_jid_s, profile_key):
|
||||
client = self.host.getClient(profile_key)
|
||||
d = client.disco.requestItems(to_jid, NS_COMMANDS)
|
||||
d.addCallback(self._items2XMLUI)
|
||||
to_jid = jid.JID(to_jid_s) if to_jid_s else None
|
||||
d = self.list(client, to_jid, no_instructions=True)
|
||||
d.addCallback(lambda xmlui: xmlui.toXml())
|
||||
return d
|
||||
|
||||
def addAdHocCommand(self, callback, label, node=None, features = None, timeout = 600, allowed_jids = None, allowed_groups = None,
|
||||
allowed_magics = None, forbidden_jids = None, forbidden_groups = None, profile_key=C.PROF_KEY_NONE):
|
||||
def list(self, client, to_jid, no_instructions=False):
|
||||
"""Request available commands
|
||||
|
||||
@param to_jid(jid.JID, None): the entity answering the commands
|
||||
None to use profile's server
|
||||
@param no_instructions(bool): if True, don't add instructions widget
|
||||
"""
|
||||
d = self.host.getDiscoItems(client, to_jid, NS_COMMANDS)
|
||||
d.addCallback(self._items2XMLUI, no_instructions)
|
||||
return d
|
||||
|
||||
def addAdHocCommand(self, callback, label, node=None, features=None, timeout=600, allowed_jids=None, allowed_groups=None,
|
||||
allowed_magics=None, forbidden_jids=None, forbidden_groups=None, profile_key=C.PROF_KEY_NONE):
|
||||
"""Add an ad-hoc command for the current profile
|
||||
|
||||
@param callback: method associated with this ad-hoc command which return the payload data (see AdHocCommand._sendAnswer), can return a deferred
|
||||
|
|
|
|||
Loading…
Reference in a new issue