Software /
code /
prosody-modules
Comparison
mod_export_skeletons/mod_export_skeletons.lua @ 4815:9c2af2146ee2
mod_export_skeletons: Command to aid in analysis of archive contents
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 09 Dec 2021 23:48:25 +0100 |
child | 4818:d66162e850cd |
comparison
equal
deleted
inserted
replaced
4814:5f12c75fd210 | 4815:9c2af2146ee2 |
---|---|
1 | |
2 local t_insert = table.insert; | |
3 local t_sort = table.sort; | |
4 | |
5 local sm = require "core.storagemanager"; | |
6 local um = require "core.usermanager"; | |
7 | |
8 local argparse = require "util.argparse"; | |
9 local dt = require "util.datetime"; | |
10 local jid = require "util.jid"; | |
11 local st = require "util.stanza"; | |
12 | |
13 local function skeleton(s) | |
14 local o = st.stanza(s.name, { xmlns = s.attr.xmlns }); | |
15 | |
16 local children = {}; | |
17 for _, child in ipairs(s.tags) do t_insert(children, skeleton(child)) end | |
18 t_sort(children, function(a, b) | |
19 if a.attr.xmlns == b.attr.xmlns then return a.name < b.name; end | |
20 return (a.attr.xmlns or "") < (b.attr.xmlns or ""); | |
21 end); | |
22 for _, child in ipairs(children) do o:add_direct_child(child); end | |
23 return o; | |
24 end | |
25 | |
26 local function classify_jid(s) | |
27 if not s then return "" end | |
28 local u, h, r = jid.split(s); | |
29 if r then | |
30 return "full" | |
31 elseif u then | |
32 return "bare" | |
33 elseif h then | |
34 return "host" | |
35 else | |
36 return "invalid" | |
37 end | |
38 end | |
39 | |
40 function module.command(arg) | |
41 local opts = argparse.parse(arg, { value_params = { store = true; with = true; start = true; ["end"] = true } }); | |
42 local store = opts.store or "archive"; -- so you can pass 'archive2' | |
43 opts.store = nil; | |
44 local query = { with = jid.prep(opts.with); start = dt.parse(opts.start); ["end"] = dt.parse(opts["end"]) }; | |
45 local host_initialized = {}; | |
46 for _, export_jid in ipairs(arg) do | |
47 | |
48 local username, host = jid.split(export_jid); | |
49 if not host_initialized[host] then | |
50 sm.initialize_host(host); | |
51 um.initialize_host(host); | |
52 host_initialized[host] = true; | |
53 end | |
54 | |
55 local archive = module:context(host):open_store(store, "archive"); | |
56 local iter, total = assert(archive:find(username ~= "*" and username, query)) | |
57 if total then io.stderr:write(string.format("Processing %d entries\n", total)); end | |
58 for _, item in iter do | |
59 local clean = skeleton(item); | |
60 | |
61 -- Normalize top level attributes | |
62 clean.attr.type = item.attr.type; | |
63 if clean.attr.type == nil and clean.name == "message" then clean.attr.type = "normal"; end | |
64 clean.attr.id = string.rep("x", #(item.attr.id or "")); -- worth rounding to nearest power of two or so? | |
65 clean.attr.from = classify_jid(item.attr.from); | |
66 clean.attr.to = classify_jid(item.attr.to); | |
67 print(clean); | |
68 end | |
69 | |
70 end | |
71 end |