Mercurial > prosody-modules
comparison mod_csi_pump/mod_csi_pump.lua @ 2455:dc30ca5ce315
mod_csi_pump: Lossless CSI mode
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 22 Jan 2017 00:41:11 +0100 |
| parents | |
| children | 3ed504b944e5 |
comparison
equal
deleted
inserted
replaced
| 2454:51cf82d36a8a | 2455:dc30ca5ce315 |
|---|---|
| 1 -- Copyright (C) 2016 Kim Alvefur | |
| 2 -- | |
| 3 | |
| 4 module:depends"csi" | |
| 5 module:depends"track_muc_joins" | |
| 6 local jid = require "util.jid"; | |
| 7 local new_queue = require "util.queue".new; | |
| 8 | |
| 9 local function new_pump(output, ...) | |
| 10 -- luacheck: ignore 212/self | |
| 11 local q = new_queue(...); | |
| 12 local flush = true; | |
| 13 function q:pause() | |
| 14 flush = false; | |
| 15 end | |
| 16 function q:resume() | |
| 17 flush = true; | |
| 18 return q:flush(); | |
| 19 end | |
| 20 local push = q.push; | |
| 21 function q:push(item) | |
| 22 local ok = push(self, item); | |
| 23 if not ok then | |
| 24 q:flush(); | |
| 25 output(item, self); | |
| 26 elseif flush then | |
| 27 return q:flush(); | |
| 28 end | |
| 29 return true; | |
| 30 end | |
| 31 function q:flush() | |
| 32 local item = self:pop(); | |
| 33 while item do | |
| 34 output(item, self); | |
| 35 item = self:pop(); | |
| 36 end | |
| 37 return true; | |
| 38 end | |
| 39 return q; | |
| 40 end | |
| 41 | |
| 42 -- TODO delay stamps | |
| 43 -- local dt = require "util.datetime"; | |
| 44 | |
| 45 local function is_important(stanza, session) | |
| 46 local st_name = stanza.name; | |
| 47 if not st_name then return false; end | |
| 48 local st_type = stanza.attr.type; | |
| 49 if st_name == "presence" then | |
| 50 -- TODO check for MUC status codes? | |
| 51 return false; | |
| 52 elseif st_name == "message" then | |
| 53 if st_type == "headline" then | |
| 54 return false; | |
| 55 end | |
| 56 local body = stanza:get_child_text("body"); | |
| 57 if not body then return false; end | |
| 58 if st_type == "groupchat" then | |
| 59 if body:find(session.username, 1, true) then return true; end | |
| 60 local rooms = session.rooms_joined; | |
| 61 if not rooms then return false; end | |
| 62 local room_nick = rooms[jid.bare(stanza.attr.from)]; | |
| 63 if room_nick and body:find(room_nick, 1, true) then return true; end | |
| 64 return false; | |
| 65 end | |
| 66 return body; | |
| 67 end | |
| 68 return true; | |
| 69 end | |
| 70 | |
| 71 module:hook("csi-client-inactive", function (event) | |
| 72 local session = event.origin; | |
| 73 if session.pump then | |
| 74 session.pump:pause(); | |
| 75 else | |
| 76 session._orig_send = session.send; | |
| 77 local pump = new_pump(session.send, 100); | |
| 78 pump:pause(); | |
| 79 session.pump = pump; | |
| 80 function session.send(stanza) | |
| 81 pump:push(stanza); | |
| 82 if is_important(stanza, session) then | |
| 83 pump:flush(); | |
| 84 end | |
| 85 return true; | |
| 86 end | |
| 87 end | |
| 88 end); | |
| 89 | |
| 90 module:hook("csi-client-active", function (event) | |
| 91 local session = event.origin; | |
| 92 if session.pump then | |
| 93 session.pump:resume(); | |
| 94 end | |
| 95 end); | |
| 96 |
