plugins.adhoc: Support for querying for and executing commands

Thu, 09 Sep 2010 19:30:49 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 09 Sep 2010 19:30:49 +0100
changeset 122
e2600454fd54
parent 121
9b31ac5a37ea
child 123
8a079aa70b84

plugins.adhoc: Support for querying for and executing commands

plugins/adhoc.lua file | annotate | diff | comparison | revisions
--- 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

mercurial