Comparison

mod_mam/mod_mam.lua @ 903:8a1beff848c1

mod_mam: Implemented an empty <before/>, to request the last n items in the archive.
author Thijs Alkemade <thijsalkemade@gmail.com>
date Sun, 27 Jan 2013 17:34:16 +0100
parent 808:ba2e207e1fb7
child 982:ce8bb0386d08
comparison
equal deleted inserted replaced
902:490cb9161c81 903:8a1beff848c1
21 local rm_load_roster = require "core.rostermanager".load_roster; 21 local rm_load_roster = require "core.rostermanager".load_roster;
22 22
23 local tostring = tostring; 23 local tostring = tostring;
24 local time_now = os.time; 24 local time_now = os.time;
25 local m_min = math.min; 25 local m_min = math.min;
26 local t_insert = table.insert;
26 local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse; 27 local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse;
27 local uuid = require "util.uuid".generate; 28 local uuid = require "util.uuid".generate;
28 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); 29 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50);
29 local global_default_policy = module:get_option("default_archive_policy", false); 30 local global_default_policy = module:get_option("default_archive_policy", false);
30 -- TODO Should be possible to enforce it too 31 -- TODO Should be possible to enforce it too
163 local qmax = m_min(qset and qset.max or default_max_items, max_max_items); 164 local qmax = m_min(qset and qset.max or default_max_items, max_max_items);
164 local qset_matches = not (qset and qset.after); 165 local qset_matches = not (qset and qset.after);
165 local first, last, index; 166 local first, last, index;
166 local n = 0; 167 local n = 0;
167 local start = qset and qset.index or 1; 168 local start = qset and qset.index or 1;
169 local results = {};
170 -- An empty <before/> means: give the last n items. So we loop backwards.
171 local reverse = qset and qset.before or false;
168 172
169 module:log("debug", "Loaded %d items, about to filter", #data); 173 module:log("debug", "Loaded %d items, about to filter", #data);
170 for i=start,#data do 174 for i=(reverse and #data or start),(reverse and start or #data),(reverse and -1 or 1) do
171 local item = data[i]; 175 local item = data[i];
172 local when, with, resource = item.when, item.with, item.resource; 176 local when, with, resource = item.when, item.with, item.resource;
173 local id = item.id; 177 local id = item.id;
174 --module:log("debug", "id is %s", id); 178 --module:log("debug", "id is %s", id);
175 179
193 :tag("forwarded", { xmlns = xmlns_forward }) 197 :tag("forwarded", { xmlns = xmlns_forward })
194 :tag("delay", { xmlns = xmlns_delay, stamp = timestamp(when) }):up(); 198 :tag("delay", { xmlns = xmlns_delay, stamp = timestamp(when) }):up();
195 local orig_stanza = st.deserialize(item.stanza); 199 local orig_stanza = st.deserialize(item.stanza);
196 orig_stanza.attr.xmlns = "jabber:client"; 200 orig_stanza.attr.xmlns = "jabber:client";
197 fwd_st:add_child(orig_stanza); 201 fwd_st:add_child(orig_stanza);
198 origin.send(fwd_st); 202 if reverse then
203 t_insert(results, 1, fwd_st);
204 else
205 results[#results + 1] = fwd_st;
206 end
199 if not first then 207 if not first then
200 index = i; 208 index = i;
201 first = id; 209 first = id;
202 end 210 end
203 last = id; 211 last = id;
217 if n >= qmax then 225 if n >= qmax then
218 module:log("debug", "Max number of items matched"); 226 module:log("debug", "Max number of items matched");
219 break 227 break
220 end 228 end
221 end 229 end
230 for _,v in pairs(results) do
231 origin.send(v);
232 end
222 -- That's all folks! 233 -- That's all folks!
223 module:log("debug", "Archive query %s completed", tostring(qid)); 234 module:log("debug", "Archive query %s completed", tostring(qid));
224 235
225 local reply = st.reply(stanza); 236 local reply = st.reply(stanza);
226 if last then 237 if last then
227 -- This is a bit redundant, isn't it? 238 -- This is a bit redundant, isn't it?
228 reply:query(xmlns_mam):add_child(rsm.generate{first = first, last = last, count = n}); 239 reply:query(xmlns_mam):add_child(rsm.generate{first = (reverse and last or first), last = (reverse and first or last), count = n});
229 end 240 end
230 origin.send(reply); 241 origin.send(reply);
231 return true 242 return true
232 end 243 end
233 end); 244 end);