util.encodings: Spell out all IDNA 2008 options ICU has
[prosody.git] / plugins / adhoc / adhoc.lib.lua
blob0b910299c4e413a351ec9b6ff5e2324d353f5adf
1 -- Copyright (C) 2009-2010 Florian Zeitz
2 --
3 -- This file is MIT/X11 licensed. Please see the
4 -- COPYING file in the source package for more information.
5 --
7 local st, uuid = require "util.stanza", require "util.uuid";
9 local xmlns_cmd = "http://jabber.org/protocol/commands";
11 local states = {}
13 local _M = {};
15 local function _cmdtag(desc, status, sessionid, action)
16 local cmd = st.stanza("command", { xmlns = xmlns_cmd, node = desc.node, status = status });
17 if sessionid then cmd.attr.sessionid = sessionid; end
18 if action then cmd.attr.action = action; end
20 return cmd;
21 end
23 function _M.new(name, node, handler, permission)
24 return { name = name, node = node, handler = handler, cmdtag = _cmdtag, permission = (permission or "user") };
25 end
27 function _M.handle_cmd(command, origin, stanza)
28 local cmdtag = stanza.tags[1]
29 local sessionid = cmdtag.attr.sessionid or uuid.generate();
30 local dataIn = {
31 to = stanza.attr.to;
32 from = stanza.attr.from;
33 action = cmdtag.attr.action or "execute";
34 form = cmdtag:get_child("x", "jabber:x:data");
37 local data, state = command:handler(dataIn, states[sessionid]);
38 states[sessionid] = state;
39 local cmdreply;
40 if data.status == "completed" then
41 states[sessionid] = nil;
42 cmdreply = command:cmdtag("completed", sessionid);
43 elseif data.status == "canceled" then
44 states[sessionid] = nil;
45 cmdreply = command:cmdtag("canceled", sessionid);
46 elseif data.status == "error" then
47 states[sessionid] = nil;
48 local reply = st.error_reply(stanza, data.error.type, data.error.condition, data.error.message);
49 origin.send(reply);
50 return true;
51 else
52 cmdreply = command:cmdtag("executing", sessionid);
53 data.actions = data.actions or { "complete" };
54 end
56 for name, content in pairs(data) do
57 if name == "info" then
58 cmdreply:tag("note", {type="info"}):text(content):up();
59 elseif name == "warn" then
60 cmdreply:tag("note", {type="warn"}):text(content):up();
61 elseif name == "error" then
62 cmdreply:tag("note", {type="error"}):text(content.message):up();
63 elseif name == "actions" then
64 local actions = st.stanza("actions", { execute = content.default });
65 for _, action in ipairs(content) do
66 if (action == "prev") or (action == "next") or (action == "complete") then
67 actions:tag(action):up();
68 else
69 module:log("error", "Command %q at node %q provided an invalid action %q",
70 command.name, command.node, action);
71 end
72 end
73 cmdreply:add_child(actions);
74 elseif name == "form" then
75 cmdreply:add_child((content.layout or content):form(content.values));
76 elseif name == "result" then
77 cmdreply:add_child((content.layout or content):form(content.values, "result"));
78 elseif name == "other" then
79 cmdreply:add_child(content);
80 end
81 end
82 local reply = st.reply(stanza);
83 reply:add_child(cmdreply);
84 origin.send(reply);
86 return true;
87 end
89 return _M;