Software /
code /
prosody-modules
Changeset
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 | 3952:343dc9dd70dd |
children | 3954:7a2998e48545 |
files | mod_rest/README.markdown mod_rest/jsonmap.lib.lua |
diffstat | 2 files changed, 44 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_rest/README.markdown Sat Mar 21 18:05:22 2020 +0100 +++ b/mod_rest/README.markdown Mon Mar 23 19:03:04 2020 +0100 @@ -375,6 +375,11 @@ items list query. The response contain an array of items like `{"jid":"xmpp.address.here","name":"Description of item"}`. +`extensions` +: Map of extended feature discovery (see [XEP-0128]) data with + `FORM_DATA` fields as the keys pointing at maps with the rest of the + data. + #### Ad-Hoc Commands Used to execute arbitrary commands on supporting entities.
--- a/mod_rest/jsonmap.lib.lua Sat Mar 21 18:05:22 2020 +0100 +++ b/mod_rest/jsonmap.lib.lua Mon Mar 23 19:03:04 2020 +0100 @@ -75,7 +75,7 @@ disco = { type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query", st2json = function (s) --> array of features - local identities, features = array(), array(); + local identities, features, extensions = array(), array(), {}; for tag in s:childtags() do if tag.name == "identity" and tag.attr.category and tag.attr.type then identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name }); @@ -83,7 +83,16 @@ features:push(tag.attr.var); end end - return { node = s.attr.node, identities = identities, features = features, }; + for form in s:childtags("x", "jabber:x:data") do + local jform = field_mappings.formdata.st2json(form); + local form_type = jform["FORM_TYPE"]; + if jform then + jform["FORM_TYPE"] = nil; + extensions[form_type] = jform; + end + end + if next(extensions) == nil then extensions = nil; end + return { node = s.attr.node, identities = identities, features = features, extensions = extensions }; end; json2st = function (s) if type(s) == "table" and s ~= json.null then @@ -98,6 +107,12 @@ disco:tag("feature", { var = feature }):up(); end end + if s.extensions then + for form_type, extension in pairs(s.extensions) do + extension["FORM_TYPE"] = form_type; + disco:add_child(field_mappings.formdata.json2st(extension)); + end + end return disco; else return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", }); @@ -324,10 +339,28 @@ -- Simpler mapping of dataform from JSON map formdata = { type = "func", xmlns = "jabber:x:data", tagname = "", - st2json = function () - -- Tricky to do in a generic way without each form layout - -- In the future, some well-known layouts might be understood - return nil, "not-implemented"; + st2json = function (s) + local r = {}; + for field in s:childtags("field") do + if field.attr.var then + local values = array(); + for value in field:childtags("value") do + values:push(value:get_text()); + end + if field.attr.type == "list-single" or field.attr.type == "list-multi" then + r[field.attr.var] = values; + elseif field.attr.type == "text-multi" then + r[field.attr.var] = values:concat("\n"); + elseif field.attr.type == "boolean" then + r[field.attr.var] = values[1] == "1" or values[1] == "true"; + elseif field.attr.type then + r[field.attr.var] = values[1] or json.null; + else -- type is optional, no way to know if multiple or single value is expected + r[field.attr.var] = values; + end + end + end + return r; end, json2st = function (s, t) local form = st.stanza("x", { xmlns = "jabber:x:data", type = t });