Comparison

plugins/adhoc.lua @ 122:e2600454fd54

plugins.adhoc: Support for querying for and executing commands
author Matthew Wild <mwild1@gmail.com>
date Thu, 09 Sep 2010 19:30:49 +0100
parent 116:151c8cc776df
child 145:96efa9ee8f18
comparison
equal deleted inserted replaced
121:9b31ac5a37ea 122:e2600454fd54
1 local adhoc = require "lib.adhoc"; 1 local adhoc = require "lib.adhoc";
2 2
3 local xmlns_commands = "http://jabber.org/protocol/commands"; 3 local xmlns_commands = "http://jabber.org/protocol/commands";
4 local xmlns_data = "jabber:x:data";
4 5
6 local command_mt = {};
7 command_mt.__index = command_mt;
8
9 -- Table of commands we provide
5 local commands = {}; 10 local commands = {};
6 11
7 function verse.plugins.adhoc(stream) 12 function verse.plugins.adhoc(stream)
8 stream:add_disco_feature(xmlns_commands); 13 stream:add_disco_feature(xmlns_commands);
9 14
15 function stream:query_commands(jid, callback)
16 stream:disco_items(jid, xmlns_commands, function (items)
17 stream:debug("adhoc list returned")
18 local command_list = {};
19 for _, item in ipairs(items) do
20 command_list[item.node] = item.name;
21 end
22 stream:debug("adhoc calling callback")
23 return callback(command_list);
24 end);
25 end
26
27 function stream:execute_command(jid, command, callback)
28 local cmd = setmetatable({
29 stream = stream, jid = jid,
30 command = command, callback = callback
31 }, command_mt);
32 return cmd:execute();
33 end
34
35 -- ACL checker for commands we provide
10 local function has_affiliation(jid, aff) 36 local function has_affiliation(jid, aff)
11 if not(aff) or aff == "user" then return true; end 37 if not(aff) or aff == "user" then return true; end
12 -- TODO: Support 'roster', and callback etc. 38 if type(aff) == "function" then
39 return aff(jid);
40 end
41 -- TODO: Support 'roster', etc.
13 end 42 end
14 43
15 function stream:add_adhoc_command(name, node, handler, permission) 44 function stream:add_adhoc_command(name, node, handler, permission)
16 commands[node] = adhoc.new(name, node, handler, permission); 45 commands[node] = adhoc.new(name, node, handler, permission);
17 stream:add_disco_item({ jid = stream.jid, node = node, name = name }, xmlns_commands); 46 stream:add_disco_item({ jid = stream.jid, node = node, name = name }, xmlns_commands);
42 if type == "set" and name == "command" then 71 if type == "set" and name == "command" then
43 return handle_command(stanza); 72 return handle_command(stanza);
44 end 73 end
45 end); 74 end);
46 end 75 end
76
77 function command_mt:_process_response(result)
78 if result.type == "error" then
79 self.status = "canceled";
80 self.callback(self, {});
81 end
82 local command = result:get_child("command", xmlns_commands);
83 self.status = command.attr.status;
84 self.sessionid = command.attr.sessionid;
85 self.form = command:get_child("x", xmlns_data);
86 self.callback(self);
87 end
88
89 -- Initial execution of a command
90 function command_mt:execute()
91 io.write(":execute()\n");
92 local iq = verse.iq({ to = self.jid, type = "set" })
93 :tag("command", { xmlns = xmlns_commands, node = self.command });
94 self.stream:send_iq(iq, function (result)
95 io.write(":send_iq() response\n");
96 self:_process_response(result);
97 end);
98 end
99
100 function command_mt:next(form)
101 local iq = verse.iq({ to = self.jid, type = "set" })
102 :tag("command", {
103 xmlns = xmlns_commands,
104 node = self.command,
105 sessionid = self.sessionid
106 });
107
108 if form then iq:add_child(form); end
109
110 self.stream:send_iq(iq, function (result)
111 self:_process_response(result);
112 end);
113 end