mod_message_logging/mod_message_logging.lua
author Kim Alvefur <zash@zash.se>
Mon, 11 Jul 2022 20:08:41 +0200
changeset 4978 807007913f67
parent 1505 ba71d0ad5564
child 1593 3e4d15ae2133
permissions -rw-r--r--
mod_log_json: Prefer native Lua table.pack over Prosody util.table one Prosody is removing support for Lua 5.1, which was the reason for util.table.pack to exist in the first place, since Lua 5.2+ provides table.pack. In prosody rev 5eaf77114fdb everything was switched over to use table.pack, opening the door for removing util.table.pack at some point. This change here is to prepare for that future eventuality.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local jid_bare = require "util.jid".bare;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local jid_split = require "util.jid".split;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local stat, mkdir = require "lfs".attributes, require "lfs".mkdir;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
-- Get a filesystem-safe string
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
local function fsencode_char(c)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
	return ("%%%02x"):format(c:byte());
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local function fsencode(s)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	return (s:gsub("[^%w._-@]", fsencode_char):gsub("^%.", "_"));
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
local log_base_path = module:get_option("message_logging_dir", prosody.paths.data.."/message_logs");
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
mkdir(log_base_path);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
local function get_host_path(host)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	return log_base_path.."/"..fsencode(host);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
local function get_user_path(jid)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
	local username, host = jid_split(jid);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
	local base = get_host_path(host)..os.date("/%Y-%m-%d");
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	if not stat(base) then
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
		mkdir(base);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	return base.."/"..fsencode(username)..".msglog";
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
local open_files_mt = { __index = function (open_files, jid)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	local f, err = io.open(get_user_path(jid), "a+");
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	if not f then
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
		module:log("error", "Failed to open message log for writing [%s]: %s", jid, err);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	rawset(open_files, jid, f);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	return f;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
end };
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
-- [user@host] = filehandle
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
local open_files = setmetatable({}, open_files_mt);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
function close_open_files()
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
	module:log("debug", "Closing all open files");
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
	for jid, filehandle in pairs(open_files) do
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
		filehandle:close();
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
		open_files[jid] = nil;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
	end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
module:hook_global("logging-reloaded", close_open_files);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    53
local function write_to_log(log_jid, jid, prefix, body)
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    54
	if not body then return; end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    55
	local f = open_files[log_jid];
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    56
	if not f then return; end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    57
	body = body:gsub("\n", "\n    "); -- Indent newlines
1501
4b55110b0aa8 mod_message_logging: Add timestamp to logs
Matthew Wild <mwild1@gmail.com>
parents: 1500
diff changeset
    58
	f:write(os.date("%H:%M:%S "), prefix or "", prefix and ": " or "", jid, ": ", body, "\n");
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    59
	f:flush();
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    60
end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    61
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
local function handle_incoming_message(event)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
	local origin, stanza = event.origin, event.stanza;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	local message_type = stanza.attr.type;
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1007
diff changeset
    65
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	if message_type == "error" then return; end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1007
diff changeset
    67
1377
92f3b4d81b52 mod_message_logging: Treat messages with no 'to' as directed to the sender
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
    68
	local from, to = jid_bare(stanza.attr.from), jid_bare(stanza.attr.to or stanza.attr.from);
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	if message_type == "groupchat" then
1505
ba71d0ad5564 mod_message_logging/mod_message_logging.lua: Fix missing 'or'
daurnimator <quae@daurnimator.com>
parents: 1501
diff changeset
    70
		from = from.." <"..(select(3, jid_split(stanza.attr.from)) or "")..">";
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	end
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    72
	write_to_log(to, from, "RECV", stanza:get_child_text("body"));
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
local function handle_outgoing_message(event)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
	local origin, stanza = event.origin, event.stanza;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
	local message_type = stanza.attr.type;
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1007
diff changeset
    78
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    79
	if message_type == "error" then return; end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1007
diff changeset
    80
1377
92f3b4d81b52 mod_message_logging: Treat messages with no 'to' as directed to the sender
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
    81
	local from, to = jid_bare(stanza.attr.from), jid_bare(stanza.attr.to or origin.full_jid);
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    82
	write_to_log(from, to, "SEND", stanza:get_child_text("body"));
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    85
local function handle_muc_message(event)
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    86
	local stanza = event.stanza;
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    87
	if stanza.attr.type ~= "groupchat" then return; end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    88
	local room = event.room or hosts[select(2, jid_split(stanza.attr.to))].modules.muc.rooms[stanza.attr.to];
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    89
	if not room then return; end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    90
	local nick = select(3, jid_split(room._jid_nick[stanza.attr.from]));
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    91
	if not nick then return; end
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    92
	write_to_log(room.jid, jid_bare(stanza.attr.from).." <"..nick..">", "MESG", stanza:get_child_text("body"));
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
    93
end
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
function module.add_host(module)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
	local host_base_path = get_host_path(module.host);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	if not stat(host_base_path) then
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
		mkdir(host_base_path);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
	end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
1500
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   101
	if hosts[module.host].modules.muc then
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   102
		module:hook("message/bare", handle_muc_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   103
	else
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   104
		module:hook("message/bare", handle_incoming_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   105
		module:hook("message/full", handle_incoming_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   106
	
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   107
		module:hook("pre-message/bare", handle_outgoing_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   108
		module:hook("pre-message/full", handle_outgoing_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   109
		module:hook("pre-message/host", handle_outgoing_message, 1);
045720a5fccd mod_message_logging: Improve logging when loaded onto a MUC host
Matthew Wild <mwild1@gmail.com>
parents: 1377
diff changeset
   110
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1007
diff changeset
   111
1007
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
function module.command(arg)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   115
	local command = table.remove(arg, 1);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   116
	if command == "path" then
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
		print(get_user_path(arg[1]));
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
	else
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
		io.stderr:write("Unrecognised command: ", command);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
		return 1;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
	end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   122
	return 0;
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   123
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   125
function module.save()
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   126
	return { open_files = open_files };
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   127
end
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   128
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
function module.restore(saved)
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
	open_files = setmetatable(saved.open_files or {}, open_files_mt);
ba220790a59c mod_message_logging: New module to log user conversations to text files
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   131
end