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'])); |