Mercurial > prosody-hg
view plugins/muc/occupant.lib.lua @ 13946:f5e8ab42c708
mod_http_file_share: Check that files are still there with correct size
Failed uploads can leave behind unused slots. Files shouldn't change
size after they have been successfully uploaded, but might as well
double check it.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 04 Dec 2021 18:56:51 +0100 |
| parents | 4af7d00a2966 |
| children |
line wrap: on
line source
local pairs = pairs; local setmetatable = setmetatable; local st = require "prosody.util.stanza"; local util = module:require "muc/util"; local function get_filtered_presence(stanza) return util.filter_muc_x(st.clone(stanza)); end local occupant_mt = {}; occupant_mt.__index = occupant_mt; local function new_occupant(bare_real_jid, nick) return setmetatable({ bare_jid = bare_real_jid; nick = nick; -- in-room jid sessions = {}; -- hash from real_jid to presence stanzas. stanzas should not be modified role = nil; jid = nil; -- Primary session }, occupant_mt); end -- Deep copy an occupant local function copy_occupant(occupant) local sessions = {}; for full_jid, session in pairs(occupant.sessions) do local presence_stanza = session.presence; -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then sessions[full_jid] = session; end end return setmetatable({ bare_jid = occupant.bare_jid; nick = occupant.nick; sessions = sessions; role = occupant.role; jid = occupant.jid; }, occupant_mt); end -- finds another session to be the primary (there might not be one) function occupant_mt:choose_new_primary() for jid, pr in self:each_session() do if pr.attr.type == nil then return jid; end end return nil; end function occupant_mt:get_session(real_jid) return self.sessions[real_jid]; end function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) local pr = get_filtered_presence(presence_stanza); pr.attr.from = self.nick; pr.attr.to = real_jid; self.sessions[real_jid] = { presence = pr }; if replace_primary then self.jid = real_jid; elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then -- Only leave an unavailable presence as primary when there are no other options self.jid = self:choose_new_primary() or real_jid; end end function occupant_mt:remove_session(real_jid) -- Delete original session self.sessions[real_jid] = nil; if self.jid == real_jid then self.jid = self:choose_new_primary(); end end -- An iterator over self.sessions that returns (jid, presence, session) local function _session_iter(s, var) local k = next(s, var); if k then local v = s[k]; return k, v.presence, v; end end function occupant_mt:each_session() return _session_iter, self.sessions; end function occupant_mt:get_presence(real_jid) local session = self.sessions[real_jid or self.jid]; if not session then return; end return session.presence; end return { new = new_occupant; copy = copy_occupant; mt = occupant_mt; }
