comparison mod_rest/jsonmap.lib.lua @ 3953:2c6d5734ae04

mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions Example XEP-0157 payload: { "disco" : { "extensions" : { "http://jabber.org/network/serverinfo" : { "abuse-addresses" : [ "mailto:abuse@shakespeare.lit", "xmpp:abuse@shakespeare.lit" ], "admin-addresses" : [ "mailto:admin@shakespeare.lit", "xmpp:admin@shakespeare.lit" ], "feedback-addresses" : [ "http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit" ], "sales-addresses" : [ "xmpp:bard@shakespeare.lit" ], "security-addresses" : [ "xmpp:security@shakespeare.lit" ], "support-addresses" : [ "http://shakespeare.lit/support.php", "xmpp:support@shakespeare.lit" ] } } } }
author Kim Alvefur <zash@zash.se>
date Mon, 23 Mar 2020 19:03:04 +0100
parents 8b34222216f4
children 1925d63eec6b
comparison
equal deleted inserted replaced
3952:343dc9dd70dd 3953:2c6d5734ae04
73 73
74 -- XEP-0030 74 -- XEP-0030
75 disco = { 75 disco = {
76 type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query", 76 type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query",
77 st2json = function (s) --> array of features 77 st2json = function (s) --> array of features
78 local identities, features = array(), array(); 78 local identities, features, extensions = array(), array(), {};
79 for tag in s:childtags() do 79 for tag in s:childtags() do
80 if tag.name == "identity" and tag.attr.category and tag.attr.type then 80 if tag.name == "identity" and tag.attr.category and tag.attr.type then
81 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name }); 81 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name });
82 elseif tag.name == "feature" and tag.attr.var then 82 elseif tag.name == "feature" and tag.attr.var then
83 features:push(tag.attr.var); 83 features:push(tag.attr.var);
84 end 84 end
85 end 85 end
86 return { node = s.attr.node, identities = identities, features = features, }; 86 for form in s:childtags("x", "jabber:x:data") do
87 local jform = field_mappings.formdata.st2json(form);
88 local form_type = jform["FORM_TYPE"];
89 if jform then
90 jform["FORM_TYPE"] = nil;
91 extensions[form_type] = jform;
92 end
93 end
94 if next(extensions) == nil then extensions = nil; end
95 return { node = s.attr.node, identities = identities, features = features, extensions = extensions };
87 end; 96 end;
88 json2st = function (s) 97 json2st = function (s)
89 if type(s) == "table" and s ~= json.null then 98 if type(s) == "table" and s ~= json.null then
90 local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s.node }); 99 local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s.node });
91 if s.identities then 100 if s.identities then
94 end 103 end
95 end 104 end
96 if s.features then 105 if s.features then
97 for _, feature in ipairs(s.features) do 106 for _, feature in ipairs(s.features) do
98 disco:tag("feature", { var = feature }):up(); 107 disco:tag("feature", { var = feature }):up();
108 end
109 end
110 if s.extensions then
111 for form_type, extension in pairs(s.extensions) do
112 extension["FORM_TYPE"] = form_type;
113 disco:add_child(field_mappings.formdata.json2st(extension));
99 end 114 end
100 end 115 end
101 return disco; 116 return disco;
102 else 117 else
103 return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", }); 118 return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", });
322 end; 337 end;
323 }; 338 };
324 339
325 -- Simpler mapping of dataform from JSON map 340 -- Simpler mapping of dataform from JSON map
326 formdata = { type = "func", xmlns = "jabber:x:data", tagname = "", 341 formdata = { type = "func", xmlns = "jabber:x:data", tagname = "",
327 st2json = function () 342 st2json = function (s)
328 -- Tricky to do in a generic way without each form layout 343 local r = {};
329 -- In the future, some well-known layouts might be understood 344 for field in s:childtags("field") do
330 return nil, "not-implemented"; 345 if field.attr.var then
346 local values = array();
347 for value in field:childtags("value") do
348 values:push(value:get_text());
349 end
350 if field.attr.type == "list-single" or field.attr.type == "list-multi" then
351 r[field.attr.var] = values;
352 elseif field.attr.type == "text-multi" then
353 r[field.attr.var] = values:concat("\n");
354 elseif field.attr.type == "boolean" then
355 r[field.attr.var] = values[1] == "1" or values[1] == "true";
356 elseif field.attr.type then
357 r[field.attr.var] = values[1] or json.null;
358 else -- type is optional, no way to know if multiple or single value is expected
359 r[field.attr.var] = values;
360 end
361 end
362 end
363 return r;
331 end, 364 end,
332 json2st = function (s, t) 365 json2st = function (s, t)
333 local form = st.stanza("x", { xmlns = "jabber:x:data", type = t }); 366 local form = st.stanza("x", { xmlns = "jabber:x:data", type = t });
334 for k, v in pairs(s) do 367 for k, v in pairs(s) do
335 form:tag("field", { var = k }); 368 form:tag("field", { var = k });