comparison mod_rest/jsonmap.lib.lua @ 4938:bc8832c6696b

upstream merge
author Goffi <goffi@goffi.org>
date Wed, 11 May 2022 12:44:32 +0200
parents a85efae90e21
children b171ddf1bc3e
comparison
equal deleted inserted replaced
4913:3ddab718f717 4938:bc8832c6696b
48 st2json = function (s) --> array of features 48 st2json = function (s) --> array of features
49 if s.tags[1] == nil then 49 if s.tags[1] == nil then
50 return s.attr.node or true; 50 return s.attr.node or true;
51 end 51 end
52 local identities, features, extensions = array(), array(), {}; 52 local identities, features, extensions = array(), array(), {};
53
54 -- features and identities could be done with util.datamapper
53 for tag in s:childtags() do 55 for tag in s:childtags() do
54 if tag.name == "identity" and tag.attr.category and tag.attr.type then 56 if tag.name == "identity" and tag.attr.category and tag.attr.type then
55 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name }); 57 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name });
56 elseif tag.name == "feature" and tag.attr.var then 58 elseif tag.name == "feature" and tag.attr.var then
57 features:push(tag.attr.var); 59 features:push(tag.attr.var);
58 end 60 end
59 end 61 end
62
63 -- Especially this would be hard to do with util.datamapper
60 for form in s:childtags("x", "jabber:x:data") do 64 for form in s:childtags("x", "jabber:x:data") do
61 local jform = field_mappings.formdata.st2json(form); 65 local jform = field_mappings.formdata.st2json(form);
62 local form_type = jform["FORM_TYPE"]; 66 local form_type = jform["FORM_TYPE"];
63 if jform then 67 if jform then
64 jform["FORM_TYPE"] = nil; 68 jform["FORM_TYPE"] = nil;
65 extensions[form_type] = jform; 69 extensions[form_type] = jform;
66 end 70 end
67 end 71 end
72
68 if next(extensions) == nil then extensions = nil; end 73 if next(extensions) == nil then extensions = nil; end
69 return { node = s.attr.node, identities = identities, features = features, extensions = extensions }; 74 return { node = s.attr.node, identities = identities, features = features, extensions = extensions };
70 end; 75 end;
71 json2st = function (s) 76 json2st = function (s)
72 if type(s) == "table" and s ~= json.null then 77 if type(s) == "table" and s ~= json.null then
207 json2st = function (s) 212 json2st = function (s)
208 if type(s) == "string" then 213 if type(s) == "string" then
209 return st.stanza("x", { xmlns = "jabber:x:oob" }):text_tag("url", s); 214 return st.stanza("x", { xmlns = "jabber:x:oob" }):text_tag("url", s);
210 end 215 end
211 end; 216 end;
212 };
213
214 -- XEP-0432: Simple JSON Messaging
215 payload = { type = "func", xmlns = "urn:xmpp:json-msg:0", tagname = "payload",
216 st2json = function (s)
217 local rawjson = s:get_child_text("json", "urn:xmpp:json:0");
218 if not rawjson then return nil, "missing-json-payload"; end
219 local parsed, err = json.decode(rawjson);
220 if not parsed then return nil, err; end
221 return {
222 datatype = s.attr.datatype;
223 data = parsed;
224 };
225 end;
226 json2st = function (s)
227 if type(s) == "table" then
228 return st.stanza("payload", { xmlns = "urn:xmpp:json-msg:0", datatype = s.datatype })
229 :tag("json", { xmlns = "urn:xmpp:json:0" }):text(json.encode(s.data));
230 end;
231 end
232 }; 217 };
233 218
234 -- XEP-0004: Data Forms 219 -- XEP-0004: Data Forms
235 dataform = { 220 dataform = {
236 -- Generic and complete dataforms mapping 221 -- Generic and complete dataforms mapping
448 by = error and error.attr.by or nil, 433 by = error and error.attr.by or nil,
449 }; 434 };
450 return t; 435 return t;
451 end 436 end
452 437
438 if type(t.payload) == "table" then
439 if type(t.payload.data) == "string" then
440 local data, err = json.decode(t.payload.data);
441 if err then
442 return nil, err;
443 else
444 t.payload.data = data;
445 end
446 else
447 return nil, "invalid payload.data";
448 end
449 end
450
453 for _, tag in ipairs(s.tags) do 451 for _, tag in ipairs(s.tags) do
454 local prefix = "{" .. (tag.attr.xmlns or "jabber:client") .. "}"; 452 local prefix = "{" .. (tag.attr.xmlns or "jabber:client") .. "}";
455 local mapping = byxmlname[prefix .. tag.name]; 453 local mapping = byxmlname[prefix .. tag.name];
456 if not mapping then 454 if not mapping then
457 mapping = byxmlname[prefix]; 455 mapping = byxmlname[prefix];
534 archive["before"] = nil; 532 archive["before"] = nil;
535 archive["max"] = nil; 533 archive["max"] = nil;
536 end 534 end
537 end 535 end
538 536
537 if type(t.payload) == "table" then
538 t.payload.data = json.encode(t.payload.data);
539 end
540
541 if kind == "presence" and t.join == true and t.muc == nil then
542 -- COMPAT Older boolean 'join' property used with XEP-0045
543 t.muc = {};
544 end
545
539 local s = map.unparse(schema, { [kind or "message"] = t }).tags[1]; 546 local s = map.unparse(schema, { [kind or "message"] = t }).tags[1];
540 547
541 s.attr.type = t_type; 548 s.attr.type = t_type;
542 s.attr.to = str(t.to) and jid.prep(t.to); 549 s.attr.to = str(t.to) and jid.prep(t.to);
543 s.attr.from = str(t.to) and jid.prep(t.from); 550 s.attr.from = str(t.to) and jid.prep(t.from);
550 end 557 end
551 558
552 for k, v in pairs(t) do 559 for k, v in pairs(t) do
553 local mapping = field_mappings[k]; 560 local mapping = field_mappings[k];
554 if mapping and mapping.type == "func" and mapping.json2st then 561 if mapping and mapping.type == "func" and mapping.json2st then
555 s:add_child(mapping.json2st(v)):up(); 562 s:add_child(mapping.json2st(v)):up();
556 end 563 end
557 end 564 end
558 565
559 s:reset(); 566 s:reset();
560 567
561 return s; 568 return s;