mod_mam/mod_mam.lua
author Kim Alvefur <zash@zash.se>
Tue, 28 Feb 2012 14:36:41 +0100
changeset 620 648e75c9d3e7
parent 619 cade7dac6159
child 621 7bdd02056e2b
permissions -rw-r--r--
mod_mam: Add missing up()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- XEP-xxxx: Message Archive Management for Prosody
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2011-2012 Kim Alvefur
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
--
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
-- This file is MIT/X11 licensed.
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
--
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
-- Based on MAM ProtoXEP Version 0.1 (2010-07-01)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
     8
local xmlns_mam     = "urn:xmpp:mam:tmp";
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
     9
local xmlns_delay   = "urn:xmpp:delay";
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    10
local xmlns_forward = "urn:xmpp:forward:0";
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    11
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local st = require "util.stanza";
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local jid_bare = require "util.jid".bare;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local jid_split = require "util.jid".split;
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    15
local host = module.host;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    16
local host_sessions = hosts[host].sessions;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    17
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    18
local dm_load = require "util.datamanager".load;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    19
local dm_store = require "util.datamanager".store;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    20
local dm_list_load = require "util.datamanager".list_load;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    21
local dm_list_append = require "util.datamanager".list_append;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    22
local rm_load_roster = require "core.rostermanager".load_roster;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    23
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
local time_now = os.time;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
local uuid = require "util.uuid".generate;
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    27
local global_default_policy = module:get_option("default_archive_policy", false);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    28
-- TODO Should be possible to enforce it too
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    30
local default_attrs = {
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    31
	always = true, [true] = "always",
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    32
	never = false, [false] = "never",
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    33
	roster = "roster",
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    34
}
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    35
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    36
do
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    37
	local prefs_format = {
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    38
		[false] = "roster",
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    39
		-- default ::= true | false | "roster"
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    40
		-- true = always, false = never, nil = global default
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    41
		["romeo@montague.net"] = true, -- always
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    42
		["montague@montague.net"] = false, -- newer
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    43
	};
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    44
end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    45
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    46
local prefs_store = "archive2_prefs";
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    47
local function get_prefs(user)
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    48
	return dm_load(user, host, prefs_store) or
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    49
		{ [false] = global_default_policy };
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    50
end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    51
local function set_prefs(user, prefs)
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    52
	return dm_store(user, host, prefs_store, prefs);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    53
end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    54
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    55
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    56
-- Handle prefs.
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
module:hook("iq/self/"..xmlns_mam..":prefs", function(event)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
	local origin, stanza = event.origin, event.stanza;
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    59
	local user = origin.username;
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
	if stanza.attr.type == "get" then
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    61
		local prefs = get_prefs(user);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    62
		local default = prefs[false];
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    63
		default = default ~= nil and default_attrs[default] or global_default_policy;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    64
		local reply = st.reply(stanza):tag("prefs", { xmlns = xmlns_mam, default = default })
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    65
		--module:log("debug", "get_prefs(%q) => %s", user, require"util.serialization".serialize(prefs));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    66
		local always = st.stanza("always");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    67
		local never = st.stanza("never");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    68
		for k,v in pairs(prefs) do
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    69
			if k then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    70
				(v and always or never):tag("jid"):text(k):up();
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    71
			end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    72
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    73
		reply:add_child(always):add_child(never);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    74
		origin.send(reply);
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		return true
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	else -- type == "set"
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    77
		local prefs = {};
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    78
		local new_prefs = stanza:get_child("prefs", xmlns_mam);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    79
		local new_default = new_prefs.attr.default;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    80
		if new_default then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    81
			prefs[false] = default_attrs[new_default];
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    82
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    83
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    84
		local always = new_prefs:get_child("always");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    85
		if always then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    86
			for rule in always:childtags("jid") do
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    87
				local jid = rule:get_text();
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    88
				prefs[jid] = true;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    89
			end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    90
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    91
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    92
		local never = new_prefs:get_child("never");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    93
		if never then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    94
			for rule in never:childtags("jid") do
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    95
				local jid = rule:get_text();
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    96
				prefs[jid] = false;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    97
			end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    98
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
    99
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   100
		--module:log("debug", "set_prefs(%q, %s)", user, require"util.serialization".serialize(prefs));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   101
		local ok, err = set_prefs(user, prefs);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   102
		if not ok then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   103
			origin.send(st.error_reply(stanza, "cancel", "internal-server-error", "Error storing preferences: "..tostring(err)));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   104
		else
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   105
			origin.send(st.reply(stanza));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   106
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   107
		return true
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
	end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
end);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   111
-- Handle archive queries
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
module:hook("iq/self/"..xmlns_mam..":query", function(event)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
	local origin, stanza = event.origin, event.stanza;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
	local query = stanza.tags[1];
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
	if stanza.attr.type == "get" then
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
		local qid = query.attr.queryid;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
		-- Search query parameters
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
		local qwith = query:get_child_text("with");
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
		local qstart = query:get_child_text("start");
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
		local qend = query:get_child_text("end");
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
		module:log("debug", "Archive query, id %s with %s from %s until %s)",
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
			tostring(qid), qwith or "anyone", qstart or "the dawn of time", qend or "now");
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   124
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
		qstart, qend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend))
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
		-- Load all the data!
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   128
		local data, err = dm_list_load(origin.username, origin.host, "archive2");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   129
		if not data then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   130
			if (not err) then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   131
				module:log("debug", "The archive was empty.");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   132
				origin.send(st.reply(stanza));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   133
			else
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   134
				origin.send(st.error_reply(stanza, "cancel", "internal-server-error", "Error loading archive: "..tostring(err)));
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   135
			end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   136
			return true
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   137
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   138
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   139
		module:log("debug", "Loaded %d items, about to filter", #data);
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
		for i=1,#data do
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
			local item = data[i];
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   142
			local when, with, with_bare = item.when, item.with, item.with_bare;
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
			local ts = item.timestamp;
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   144
			--module:log("debug", "message with %s at %s", with, when or "???");
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
			-- Apply query filter
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   146
			if (not qwith or ((qwith == with) or (qwith == with_bare)))
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
					and (not qstart or when >= qstart)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
					and (not qend or when <= qend) then
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
				-- Optimizable? Do this when archiving?
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
				--module:log("debug", "sending");
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
				local fwd_st = st.message{ to = origin.full_jid }
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
					:tag("result", { xmlns = xmlns_mam, queryid = qid }):up()
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
					:tag("forwarded", { xmlns = xmlns_forward })
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
						:tag("delay", { xmlns = xmlns_delay, stamp = ts or timestamp(when) }):up();
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
				local orig_stanza = st.deserialize(item.stanza);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
				orig_stanza.attr.xmlns = "jabber:client";
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
				fwd_st:add_child(orig_stanza);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
				origin.send(fwd_st);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
			end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
		end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
		-- That's all folks!
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
		module:log("debug", "Archive query %s completed", tostring(qid));
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
		origin.send(st.reply(stanza));
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
		return true
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
	end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
end);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   168
local function has_in_roster(user, who)
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   169
	local roster = rm_load_roster(user, host);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   170
	module:log("debug", "%s has %s in roster? %s", user, who, roster[who] and "yes" or "no");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   171
	return roster and roster[who];
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   172
end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   173
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   174
local function shall_store(user, who)
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   175
	-- TODO Cache this?
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   176
	local prefs = get_prefs(user);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   177
	local rule = prefs[who];
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   178
	module:log("debug", "%s's rule for %s is %s", user, who, tostring(rule))
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   179
	if rule ~= nil then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   180
		return rule;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   181
	else -- Below could be done by a metatable
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   182
		local default = prefs[false];
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   183
		module:log("debug", "%s's default rule is %s", user, tostring(default))
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   184
		if default == nil then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   185
			default = global_default_policy;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   186
			module:log("debug", "Using global default rule, %s", tostring(default))
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   187
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   188
		if default == "roster" then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   189
			return has_in_roster(user, who);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   190
		end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   191
		return default;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   192
	end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   193
end
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   194
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   195
-- Handle messages
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
local function message_handler(event, c2s)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
	local origin, stanza = event.origin, event.stanza;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   198
	local orig_type = stanza.attr.type or "normal";
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
	local orig_to = stanza.attr.to;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
	local orig_from = stanza.attr.from;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
	if not orig_from and c2s then
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
		orig_from = origin.full_jid;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   204
	end
619
cade7dac6159 mod_mam: Try to not bork when sending a message to your bare jid
Kim Alvefur <zash@zash.se>
parents: 559
diff changeset
   205
	orig_to = orig_to or orig_from; -- Weird corner cases
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
	-- Don't store messages of these types
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	if orig_type == "error"
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	or orig_type == "headline"
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	or orig_type == "groupchat" then
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
		return;
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
		-- TODO Maybe headlines should be configurable?
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
		-- TODO Write a mod_mam_muc for groupchat messages.
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
	end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	local store_user, store_host = jid_split(c2s and orig_from or orig_to);
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   217
	local target_jid = c2s and orig_to or orig_from;
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   218
	local target_bare = jid_bare(target_jid);
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   219
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   220
	assert(store_host == host, "This should not happen.");
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   221
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   222
	if shall_store(store_user, target_bare) then
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   223
		module:log("debug", "Archiving stanza: %s", stanza:top_tag());
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   224
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   225
		-- Stamp "We archived this" on the message
559
6be3a130c810 mod_mam: Store the message id more accessible.
Kim Alvefur <zash@zash.se>
parents: 558
diff changeset
   226
		local id = uuid();
620
648e75c9d3e7 mod_mam: Add missing up()
Kim Alvefur <zash@zash.se>
parents: 619
diff changeset
   227
		stanza:tag("archived", { xmlns = xmlns_mam, by = host, id = id }):up();
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   229
		local when = time_now();
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   230
		-- And stash it
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   231
		dm_list_append(store_user, store_host, "archive2", {
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   232
			-- WARNING This format may change.
559
6be3a130c810 mod_mam: Store the message id more accessible.
Kim Alvefur <zash@zash.se>
parents: 558
diff changeset
   233
			id = id,
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   234
			when = when, -- This might be an UNIX timestamp. Probably.
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   235
			timestamp = timestamp(when), -- Textual timestamp. But I'll assume that comparing numbers is faster and less annoying in case of timezones.
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   236
			with = target_jid,
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   237
			with_bare = target_bare, -- Optimization, to avoid loads of jid_bare() calls when filtering.
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   238
			stanza = st.preserialize(stanza)
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   239
		});
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   240
	else
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   241
		module:log("debug", "Not archiving stanza: %s", stanza:top_tag());
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   242
	end
523
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
local function c2s_message_handler(event)
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
	return message_handler(event, true);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
end
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
-- Stanzas sent by local clients
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
module:hook("pre-message/bare", c2s_message_handler, 1);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
module:hook("pre-message/full", c2s_message_handler, 1);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   252
-- Stanszas to local clients
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
module:hook("message/bare", message_handler, 1);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
module:hook("message/full", message_handler, 1);
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
eff140d53b83 mod_mam: Add experimental implementation of the Message Archive Management ProtoXEP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
module:add_feature(xmlns_mam);
558
66de25ffc8d9 mod_mam: Implement archiving preferences.
Kim Alvefur <zash@zash.se>
parents: 523
diff changeset
   257