aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_csi_simple.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_csi_simple.lua')
-rw-r--r--plugins/mod_csi_simple.lua120
1 files changed, 120 insertions, 0 deletions
diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua
new file mode 100644
index 00000000..da2dd953
--- /dev/null
+++ b/plugins/mod_csi_simple.lua
@@ -0,0 +1,120 @@
+-- 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;
+ if not st.is_stanza(stanza) then
+ return true;
+ end
+ 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
+ if stanza:get_child("sent", "urn:xmpp:carbons:2") then
+ return true;
+ end
+ local forwarded = stanza:find("{urn:xmpp:carbons:2}received/{urn:xmpp:forward:0}/{jabber:client}message");
+ if forwarded then
+ stanza = forwarded;
+ end
+ if stanza:get_child("body") then
+ return true;
+ end
+ if stanza:get_child("subject") then
+ return true;
+ end
+ if stanza:get_child("encryption", "urn:xmpp:eme:0") then
+ return true;
+ end
+ return false;
+ 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 session.state == "active" or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then
+ pump:flush();
+ send(stanza);
+ else
+ if st.is_stanza(stanza) and stanza.attr.xmlns == nil and stanza.name ~= "iq" then
+ stanza = st.clone(stanza);
+ stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = bare_jid, stamp = dt.datetime()}));
+ end
+ 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);
+