diff options
Diffstat (limited to 'plugins/mod_csi_simple.lua')
-rw-r--r-- | plugins/mod_csi_simple.lua | 120 |
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); + |