Mercurial > prosody-hg
comparison plugins/muc/occupant.lib.lua @ 6233:f400a4cdf352
Merge with daurnimator
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sat, 17 May 2014 18:17:34 +0100 |
| parents | e9d62fff82a8 |
| children | 41a5e5205fd9 |
comparison
equal
deleted
inserted
replaced
| 6178:e12b13a46878 | 6233:f400a4cdf352 |
|---|---|
| 1 local next = next; | |
| 2 local pairs = pairs; | |
| 3 local setmetatable = setmetatable; | |
| 4 local st = require "util.stanza"; | |
| 5 | |
| 6 local get_filtered_presence do | |
| 7 local presence_filters = { | |
| 8 ["http://jabber.org/protocol/muc"] = true; | |
| 9 ["http://jabber.org/protocol/muc#user"] = true; | |
| 10 } | |
| 11 local function presence_filter(tag) | |
| 12 if presence_filters[tag.attr.xmlns] then | |
| 13 return nil; | |
| 14 end | |
| 15 return tag; | |
| 16 end | |
| 17 function get_filtered_presence(stanza) | |
| 18 return st.clone(stanza):maptags(presence_filter); | |
| 19 end | |
| 20 end | |
| 21 | |
| 22 local occupant_mt = {}; | |
| 23 occupant_mt.__index = occupant_mt; | |
| 24 | |
| 25 local function new_occupant(bare_real_jid, nick) | |
| 26 return setmetatable({ | |
| 27 bare_jid = bare_real_jid; | |
| 28 nick = nick; -- in-room jid | |
| 29 sessions = {}; -- hash from real_jid to presence stanzas. stanzas should not be modified | |
| 30 role = nil; | |
| 31 jid = nil; -- Primary session | |
| 32 }, occupant_mt); | |
| 33 end | |
| 34 | |
| 35 -- Deep copy an occupant | |
| 36 local function copy_occupant(occupant) | |
| 37 local sessions = {}; | |
| 38 for full_jid, presence_stanza in pairs(occupant.sessions) do | |
| 39 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session | |
| 40 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then | |
| 41 sessions[full_jid] = presence_stanza; | |
| 42 end | |
| 43 end | |
| 44 return setmetatable({ | |
| 45 bare_jid = occupant.bare_jid; | |
| 46 nick = occupant.nick; | |
| 47 sessions = sessions; | |
| 48 role = occupant.role; | |
| 49 jid = occupant.jid; | |
| 50 }, occupant_mt); | |
| 51 end | |
| 52 | |
| 53 -- finds another session to be the primary (there might not be one) | |
| 54 function occupant_mt:choose_new_primary() | |
| 55 for jid, pr in self:each_session() do | |
| 56 if pr.attr.type ~= "unavailable" then | |
| 57 return jid; | |
| 58 end | |
| 59 end | |
| 60 return nil; | |
| 61 end | |
| 62 | |
| 63 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) | |
| 64 local pr = get_filtered_presence(presence_stanza); | |
| 65 pr.attr.from = self.nick; | |
| 66 pr.attr.to = real_jid; | |
| 67 | |
| 68 self.sessions[real_jid] = pr; | |
| 69 if replace_primary then | |
| 70 self.jid = real_jid; | |
| 71 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then | |
| 72 -- Only leave an unavailable presence as primary when there are no other options | |
| 73 self.jid = self:choose_new_primary() or real_jid; | |
| 74 end | |
| 75 end | |
| 76 | |
| 77 function occupant_mt:remove_session(real_jid) | |
| 78 -- Delete original session | |
| 79 self.sessions[real_jid] = nil; | |
| 80 if self.jid == real_jid then | |
| 81 self.jid = self:choose_new_primary(); | |
| 82 end | |
| 83 end | |
| 84 | |
| 85 function occupant_mt:each_session() | |
| 86 return pairs(self.sessions) | |
| 87 end | |
| 88 | |
| 89 function occupant_mt:get_presence(real_jid) | |
| 90 return self.sessions[real_jid or self.jid] | |
| 91 end | |
| 92 | |
| 93 return { | |
| 94 new = new_occupant; | |
| 95 copy = copy_occupant; | |
| 96 mt = occupant_mt; | |
| 97 } |
