File

mod_presence_dedup/mod_presence_dedup.lua @ 4974:807007913f67

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.
author Kim Alvefur <zash@zash.se>
date Mon, 11 Jul 2022 20:08:41 +0200
parent 3445:19924a2c4a48
line wrap: on
line source

local st = require "util.stanza";
local cache = require "util.cache";
local add_filter = require "util.filters".add_filter;

local cache_size = module:get_option_number("presence_dedup_cache_size", 100);

-- stanza equality tests
local function attr_eq(a, b)
	if a == b then return true; end -- unlikely but not impossible
	for k,v in pairs(a) do if b[k] ~= v then return false; end end
	for k,v in pairs(b) do if a[k] ~= v then return false; end end
	return true;
end

local function st_eq(a, b)
	if a == b then return true; end
	if type(b) ~= "table" then return false; end
	if getmetatable(b) ~= st.stanza_mt then return false; end
	if a.name ~= b.name then return false; end
	if #a ~= #b then return false; end
	if not attr_eq(a.attr, b.attr) then return false; end
	for i = 1, #a do if not st_eq(a[i], b[i]) then return false; end end
	return true;
end

local function dedup_presence(stanza, session)
	if session.presence_cache and session.presence
	and getmetatable(stanza) == st.stanza_mt and stanza.name == "presence"
	and stanza.attr.xmlns == nil and stanza.attr.from then
		local cached = session.presence_cache:get(stanza.attr.from);
		if st_eq(stanza, cached) then
			return nil;
		else
			session.presence_cache:set(stanza.attr.from, st.clone(stanza));
		end
	end
	return stanza;
end

module:hook("presence/initial",	function (event)
	local session = event.origin;
	session.presence_cache = cache.new(cache_size);
	add_filter(session, "stanzas/out", dedup_presence, 90);
end);