Mercurial > 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 |
| parents | |
| children | 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 |
