Changeset

3507:5c37d759b1e2

mod_csi_grace_period: Server-side grace period logic for CSI
author Kim Alvefur <zash@zash.se>
date Sun, 31 Mar 2019 04:49:56 +0200 (2019-03-31)
parents 3506:7b1eede1a840
children 3508:a98a3922bc01
files mod_csi_grace_period/README.markdown mod_csi_grace_period/mod_csi_grace_period.lua
diffstat 2 files changed, 51 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_csi_grace_period/README.markdown	Sun Mar 31 04:49:56 2019 +0200
@@ -0,0 +1,7 @@
+This module helps reduces power usage of inactive mobile clients while
+another client is actively used. E.g. in the case of chatting on a
+desktop computer, instantly pushing messages to a phone in someones
+pocket is not the best use of radio time.
+
+Works with [mod_csi_simple][doc:modules:mod_csi_simple] which is
+included with Prosody since 0.11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_csi_grace_period/mod_csi_grace_period.lua	Sun Mar 31 04:49:56 2019 +0200
@@ -0,0 +1,44 @@
+-- Copyright (c) 2019 Kim Alvefur
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+-- Yes, this module touches stores data in user sessions
+-- luacheck: ignore 122
+
+local grace_period = module:get_option_number("grace_period", 30);
+
+local user_sessions = prosody.hosts[module.host].sessions;
+
+module:hook("csi-is-stanza-important", function (event)
+	if event.stanza.name ~= "message" then return end
+	local session = event.session;
+	if not session then return; end
+
+	local user_session = user_sessions[session.username];
+	if not user_session then return; end
+
+	if user_sessions.grace_time_start then
+		if user_sessions.last_active == session.resource then
+			return;
+		end
+		if (os.time() - user_sessions.grace_time_start) < grace_period then
+			session.log("debug", "Within grace period, probably seen");
+			return false;
+		end
+	end
+end, 1);
+
+local function on_activity(event)
+	local stanza, origin = event.stanza, event.origin;
+	local user_session = user_sessions[origin.username];
+	if not user_session then return; end
+
+	if stanza:get_child("body") or stanza:get_child("active", "http://jabber.org/protocol/chatstates") then
+		user_sessions.last_active = origin.resource;
+		user_sessions.grace_time_start = os.time();
+	end
+end
+module:hook("pre-message/full", on_activity);
+module:hook("pre-message/bare", on_activity);
+module:hook("pre-message/host", on_activity);