mod_csi_simple: Import modified version of mod_csi_pump from prosody-modules 0.11
authorKim Alvefur <zash@zash.se>
Mon, 29 Oct 2018 21:15:38 +0100
branch0.11
changeset 9592 aeb054ee88c5
parent 9591 6a3f06a5dff9
child 9593 6d4da1b4b6f4
mod_csi_simple: Import modified version of mod_csi_pump from prosody-modules
CHANGES
plugins/mod_csi_simple.lua
--- a/CHANGES	Mon Oct 29 21:04:32 2018 +0100
+++ b/CHANGES	Mon Oct 29 21:15:38 2018 +0100
@@ -22,7 +22,7 @@
 -   mod\_muc\_mam (XEP-0313 in groupchats)
 -   mod\_vcard\_legacy (XEP-0398)
 -   mod\_vcard4 (XEP-0292)
--   mod\_csi (XEP-0352)
+-   mod\_csi, mod\_csi\_simple (XEP-0352)
 -   New experimental network backend "epoll"
 
 0.10.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/mod_csi_simple.lua	Mon Oct 29 21:15:38 2018 +0100
@@ -0,0 +1,100 @@
+-- Copyright (C) 2016-2018 Kim Alvefur
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+module:depends"csi"
+
+local jid = require "util.jid";
+local st = require "util.stanza";
+local dt = require "util.datetime";
+local new_queue = require "util.queue".new;
+
+local function new_pump(output, ...)
+	-- luacheck: ignore 212/self
+	local q = new_queue(...);
+	local flush = true;
+	function q:pause()
+		flush = false;
+	end
+	function q:resume()
+		flush = true;
+		return q:flush();
+	end
+	local push = q.push;
+	function q:push(item)
+		local ok = push(self, item);
+		if not ok then
+			q:flush();
+			output(item, self);
+		elseif flush then
+			return q:flush();
+		end
+		return true;
+	end
+	function q:flush()
+		local item = self:pop();
+		while item do
+			output(item, self);
+			item = self:pop();
+		end
+		return true;
+	end
+	return q;
+end
+
+local queue_size = module:get_option_number("csi_queue_size", 256);
+
+module:hook("csi-is-stanza-important", function (event)
+	local stanza = event.stanza;
+	local st_name = stanza.name;
+	if not st_name then return false; end
+	local st_type = stanza.attr.type;
+	if st_name == "presence" then
+		if st_type == nil or st_type == "unavailable" then
+			return false;
+		end
+		return true;
+	elseif st_name == "message" then
+		if st_type == "headline" then
+			return false;
+		end
+		local body = stanza:get_child_text("body");
+		return body;
+	end
+	return true;
+end, -1);
+
+module:hook("csi-client-inactive", function (event)
+	local session = event.origin;
+	if session.pump then
+		session.pump:pause();
+	else
+		local bare_jid = jid.join(session.username, session.host);
+		local send = session.send;
+		session._orig_send = send;
+		local pump = new_pump(session.send, queue_size);
+		pump:pause();
+		session.pump = pump;
+		function session.send(stanza)
+			if module:fire_event("csi-stanza-is-important", { stanza = stanza, session = session }) then
+				pump:flush();
+				send(stanza);
+			else
+				stanza = st.clone(stanza);
+				stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = bare_jid, stamp = dt.datetime()}));
+				pump:push(stanza);
+			end
+			return true;
+		end
+	end
+end);
+
+module:hook("csi-client-active", function (event)
+	local session = event.origin;
+	if session.pump then
+		session.pump:resume();
+	end
+end);
+