# HG changeset patch # User Matthew Wild # Date 1284057049 -3600 # Node ID e2600454fd543970559304aeb60f13580d7bfb58 # Parent 9b31ac5a37ea6a60dba624eab9264fa5fe9ba5df plugins.adhoc: Support for querying for and executing commands diff -r 9b31ac5a37ea -r e2600454fd54 plugins/adhoc.lua --- a/plugins/adhoc.lua Thu Sep 09 19:27:46 2010 +0100 +++ b/plugins/adhoc.lua Thu Sep 09 19:30:49 2010 +0100 @@ -1,15 +1,44 @@ local adhoc = require "lib.adhoc"; local xmlns_commands = "http://jabber.org/protocol/commands"; +local xmlns_data = "jabber:x:data"; +local command_mt = {}; +command_mt.__index = command_mt; + +-- Table of commands we provide local commands = {}; function verse.plugins.adhoc(stream) stream:add_disco_feature(xmlns_commands); + function stream:query_commands(jid, callback) + stream:disco_items(jid, xmlns_commands, function (items) + stream:debug("adhoc list returned") + local command_list = {}; + for _, item in ipairs(items) do + command_list[item.node] = item.name; + end + stream:debug("adhoc calling callback") + return callback(command_list); + end); + end + + function stream:execute_command(jid, command, callback) + local cmd = setmetatable({ + stream = stream, jid = jid, + command = command, callback = callback + }, command_mt); + return cmd:execute(); + end + + -- ACL checker for commands we provide local function has_affiliation(jid, aff) if not(aff) or aff == "user" then return true; end - -- TODO: Support 'roster', and callback etc. + if type(aff) == "function" then + return aff(jid); + end + -- TODO: Support 'roster', etc. end function stream:add_adhoc_command(name, node, handler, permission) @@ -44,3 +73,41 @@ end end); end + +function command_mt:_process_response(result) + if result.type == "error" then + self.status = "canceled"; + self.callback(self, {}); + end + local command = result:get_child("command", xmlns_commands); + self.status = command.attr.status; + self.sessionid = command.attr.sessionid; + self.form = command:get_child("x", xmlns_data); + self.callback(self); +end + +-- Initial execution of a command +function command_mt:execute() + io.write(":execute()\n"); + local iq = verse.iq({ to = self.jid, type = "set" }) + :tag("command", { xmlns = xmlns_commands, node = self.command }); + self.stream:send_iq(iq, function (result) + io.write(":send_iq() response\n"); + self:_process_response(result); + end); +end + +function command_mt:next(form) + local iq = verse.iq({ to = self.jid, type = "set" }) + :tag("command", { + xmlns = xmlns_commands, + node = self.command, + sessionid = self.sessionid + }); + + if form then iq:add_child(form); end + + self.stream:send_iq(iq, function (result) + self:_process_response(result); + end); +end