1 local names
= { "Romeo", "Juliet", "Mercutio", "Tybalt", "Benvolio" };
2 local devices
= { "", "phone", "laptop", "tablet", "toaster", "fridge", "shoe" };
5 local filters
= require
"util.filters";
6 local id
= require
"util.id";
7 local dt
= require
"util.datetime";
8 local dm
= require
"util.datamanager";
9 local st
= require
"util.stanza";
11 local record_id
= id
.medium():lower();
12 local record_date
= os
.date("%Y%b%d"):lower();
13 local header_file
= dm
.getpath(record_id
, "scansion", record_date
, "scs", true);
14 local record_file
= dm
.getpath(record_id
, "scansion", record_date
, "log", true);
16 local head
= io
.open(header_file
, "w");
17 local scan
= io
.open(record_file
, "w+");
19 local function record(string)
23 local function record_header(string)
27 local function record_object(class
, name
, props
)
28 head
:write(("[%s] %s\n"):format(class
, name
));
29 for k
,v
in pairs(props
) do
30 head
:write(("\t%s: %s\n"):format(k
, v
));
35 local function record_event(session
, event
)
36 record(session
.scansion_id
.." "..event
.."\n\n");
39 local function record_stanza(stanza
, session
, verb
)
40 local flattened
= tostring(stanza
):gsub("><", ">\n\t<");
41 -- TODO Proper prettyprinting with indentation
42 record(session
.scansion_id
.." "..verb
..":\n\t"..flattened
.."\n\n");
45 local function record_stanza_in(stanza
, session
)
46 if stanza
.attr
.xmlns
== nil then
47 local copy
= st
.clone(stanza
);
49 record_stanza(copy
, session
, "sends")
54 local function record_stanza_out(stanza
, session
)
55 if stanza
.attr
.xmlns
== nil then
56 if not (stanza
.name
== "iq" and stanza
:get_child("bind", "urn:ietf:params:xml:ns:xmpp-bind")) then
57 local copy
= st
.clone(stanza
);
58 if copy
.attr
.to
== session
.full_jid
then
61 record_stanza(copy
, session
, "receives");
67 module
:hook("resource-bind", function (event
)
68 local session
= event
.session
;
69 if not users
[session
.username
] then
70 users
[session
.username
] = {
71 character
= table.remove(names
, 1) or id
.short();
76 local user
= users
[session
.username
];
77 local device
= user
.devices
[session
.resource
];
79 user
.n_devices
= user
.n_devices
+ 1;
80 device
= devices
[user
.n_devices
] or ("device"..id
.short());
81 user
.devices
[session
.resource
] = device
;
83 session
.scansion_character
= user
.character
;
84 session
.scansion_device
= device
;
85 session
.scansion_id
= user
.character
..(device
~= "" and "'s "..device
or device
);
87 record_object("Client", session
.scansion_id
, {
88 jid
= session
.full_jid
,
89 password
= "password",
92 module
:log("info", "Connected: %s", session
.scansion_id
);
93 record_event(session
, "connects");
95 filters
.add_filter(session
, "stanzas/in", record_stanza_in
);
96 filters
.add_filter(session
, "stanzas/out", record_stanza_out
);
99 module
:hook("resource-unbind", function (event
)
100 local session
= event
.session
;
101 if session
.scansion_id
then
102 record_event(session
, "disconnects");
106 record_header("# mod_scansion_record on host '"..module
.host
.."' recording started "..dt
.datetime().."\n\n");
113 module
:hook_global("server-stopping", function ()
114 record("# recording ended on "..dt
.datetime().."\n");
115 module
:log("info", "Scansion recording available in %s", header_file
);
118 prosody
.events
.add_handler("server-cleanup", function ()
120 for line
in scan
:lines() do
121 head
:write(line
, "\n");
124 os
.remove(record_file
);