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 |