plugins/muc/muc.lib.lua
changeset 6092 16d5049fe842
parent 6004 09151d26560a
child 6093 9a7eaf0a35b6
equal deleted inserted replaced
6091:3a1c39b31497 6092:16d5049fe842
     7 --
     7 --
     8 
     8 
     9 local select = select;
     9 local select = select;
    10 local pairs, ipairs = pairs, ipairs;
    10 local pairs, ipairs = pairs, ipairs;
    11 
    11 
       
    12 local gettime = os.time;
    12 local datetime = require "util.datetime";
    13 local datetime = require "util.datetime";
    13 
    14 
    14 local dataform = require "util.dataforms";
    15 local dataform = require "util.dataforms";
    15 
    16 
    16 local jid_split = require "util.jid".split;
    17 local jid_split = require "util.jid".split;
   143 				:tag("item", {affiliation=o_data.affiliation or "none", role=o_data.role or "none"}):up();
   144 				:tag("item", {affiliation=o_data.affiliation or "none", role=o_data.role or "none"}):up();
   144 			self:_route_stanza(pres);
   145 			self:_route_stanza(pres);
   145 		end
   146 		end
   146 	end
   147 	end
   147 end
   148 end
       
   149 
       
   150 local function parse_history(stanza)
       
   151 	local x_tag = stanza:get_child("x", "http://jabber.org/protocol/muc");
       
   152 	local history_tag = x_tag and x_tag:get_child("history", "http://jabber.org/protocol/muc");
       
   153 	if not history_tag then
       
   154 		return nil, 20, nil
       
   155 	end
       
   156 
       
   157 	local maxchars = tonumber(history_tag.attr.maxchars);
       
   158 
       
   159 	local maxstanzas = tonumber(history_tag.attr.maxstanzas);
       
   160 
       
   161 	-- messages received since the UTC datetime specified
       
   162 	local since = history_tag.attr.since;
       
   163 	if since then
       
   164 		since = datetime.parse(since);
       
   165 	end
       
   166 
       
   167 	-- messages received in the last "X" seconds.
       
   168 	local seconds = tonumber(history_tag.attr.seconds);
       
   169 	if seconds then
       
   170 		seconds = gettime() - seconds
       
   171 		if since then
       
   172 			since = math.max(since, seconds);
       
   173 		else
       
   174 			since = seconds;
       
   175 		end
       
   176 	end
       
   177 
       
   178 	return maxchars, maxstanzas, since
       
   179 end
       
   180 -- Get history for 'to'
       
   181 function room_mt:get_history(to, maxchars, maxstanzas, since)
       
   182 	local history = self._data['history']; -- send discussion history
       
   183 	if not history then return end
       
   184 	local history_len = #history
       
   185 
       
   186 	maxstanzas = maxstanzas or history_len
       
   187 	local n = 0;
       
   188 	local charcount = 0;
       
   189 	for i=history_len,1,-1 do
       
   190 		local entry = history[i];
       
   191 		if maxchars then
       
   192 			if not entry.chars then
       
   193 				entry.stanza.attr.to = "";
       
   194 				entry.chars = #tostring(entry.stanza);
       
   195 			end
       
   196 			charcount = charcount + entry.chars + #to;
       
   197 			if charcount > maxchars then break; end
       
   198 		end
       
   199 		if since and since > entry.stamp then break; end
       
   200 		if n + 1 > maxstanzas then break; end
       
   201 		n = n + 1;
       
   202 	end
       
   203 
       
   204 	local i = history_len-n+1
       
   205 	return function()
       
   206 		if i > history_len then return nil end
       
   207 		local entry = history[i]
       
   208 		local msg = entry.stanza
       
   209 		msg.attr.to = to;
       
   210 		i = i + 1
       
   211 		return msg
       
   212 	end
       
   213 end
   148 function room_mt:send_history(to, stanza)
   214 function room_mt:send_history(to, stanza)
   149 	local history = self._data['history']; -- send discussion history
   215 	local maxchars, maxstanzas, since = parse_history(stanza)
   150 	if history then
   216 	for msg in self:get_history(to, maxchars, maxstanzas, since) do
   151 		local x_tag = stanza and stanza:get_child("x", "http://jabber.org/protocol/muc");
   217 		self:_route_stanza(msg);
   152 		local history_tag = x_tag and x_tag:get_child("history", "http://jabber.org/protocol/muc");
       
   153 
       
   154 		local maxchars = history_tag and tonumber(history_tag.attr.maxchars);
       
   155 		if maxchars then maxchars = math.floor(maxchars); end
       
   156 
       
   157 		local maxstanzas = math.floor(history_tag and tonumber(history_tag.attr.maxstanzas) or #history);
       
   158 		if not history_tag then maxstanzas = 20; end
       
   159 
       
   160 		local seconds = history_tag and tonumber(history_tag.attr.seconds);
       
   161 		if seconds then seconds = datetime.datetime(os.time() - math.floor(seconds)); end
       
   162 
       
   163 		local since = history_tag and history_tag.attr.since;
       
   164 		if since then since = datetime.parse(since); since = since and datetime.datetime(since); end
       
   165 		if seconds and (not since or since < seconds) then since = seconds; end
       
   166 
       
   167 		local n = 0;
       
   168 		local charcount = 0;
       
   169 
       
   170 		for i=#history,1,-1 do
       
   171 			local entry = history[i];
       
   172 			if maxchars then
       
   173 				if not entry.chars then
       
   174 					entry.stanza.attr.to = "";
       
   175 					entry.chars = #tostring(entry.stanza);
       
   176 				end
       
   177 				charcount = charcount + entry.chars + #to;
       
   178 				if charcount > maxchars then break; end
       
   179 			end
       
   180 			if since and since > entry.stamp then break; end
       
   181 			if n + 1 > maxstanzas then break; end
       
   182 			n = n + 1;
       
   183 		end
       
   184 		for i=#history-n+1,#history do
       
   185 			local msg = history[i].stanza;
       
   186 			msg.attr.to = to;
       
   187 			self:_route_stanza(msg);
       
   188 		end
       
   189 	end
   218 	end
   190 end
   219 end
   191 function room_mt:send_subject(to)
   220 function room_mt:send_subject(to)
   192 	if self._data['subject'] then
   221 	if self._data['subject'] then
   193 		self:_route_stanza(st.message({type='groupchat', from=self._data['subject_from'] or self.jid, to=to}):tag("subject"):text(self._data['subject']));
   222 		self:_route_stanza(st.message({type='groupchat', from=self._data['subject_from'] or self.jid, to=to}):tag("subject"):text(self._data['subject']));