Mercurial > prosody-modules
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 }); |
