Mercurial > prosody-modules
comparison mod_archive/mod_archive.lua @ 198:a3b5810de3e4
mod_archive: XEP-0059 Result Set Management for Retrieving a Collection is DONE
author | shinysky<shinysky1986(AT)gmail.com> |
---|---|
date | Wed, 07 Jul 2010 22:07:36 +0800 |
parents | a1c2677257da |
children | 27b8a7482149 |
comparison
equal
deleted
inserted
replaced
197:2686221255cf | 198:a3b5810de3e4 |
---|---|
10 local jid = require "util.jid"; | 10 local jid = require "util.jid"; |
11 local datetime = require "util.datetime"; | 11 local datetime = require "util.datetime"; |
12 | 12 |
13 local PREFS_DIR = "archive_prefs"; | 13 local PREFS_DIR = "archive_prefs"; |
14 local ARCHIVE_DIR = "archive"; | 14 local ARCHIVE_DIR = "archive"; |
15 local xmlns_rsm = "http://jabber.org/protocol/rsm"; | |
15 | 16 |
16 module:add_feature("urn:xmpp:archive"); | 17 module:add_feature("urn:xmpp:archive"); |
17 module:add_feature("urn:xmpp:archive:auto"); | 18 module:add_feature("urn:xmpp:archive:auto"); |
18 module:add_feature("urn:xmpp:archive:manage"); | 19 module:add_feature("urn:xmpp:archive:manage"); |
19 module:add_feature("urn:xmpp:archive:manual"); | 20 module:add_feature("urn:xmpp:archive:manual"); |
366 local reply = st.reply(stanza):tag('list', {xmlns='urn:xmpp:archive'}); | 367 local reply = st.reply(stanza):tag('list', {xmlns='urn:xmpp:archive'}); |
367 local count = table.getn(resset); | 368 local count = table.getn(resset); |
368 if count > 0 then | 369 if count > 0 then |
369 local max = elem.tags[1]:child_with_name("max"); | 370 local max = elem.tags[1]:child_with_name("max"); |
370 if max then | 371 if max then |
371 max = tonumber(max:get_text()); | 372 max = tonumber(max:get_text()) or 100; |
372 else max = 100; end | 373 else max = 100; end |
373 local after = elem.tags[1]:child_with_name("after"); | 374 local after = elem.tags[1]:child_with_name("after"); |
374 local before = elem.tags[1]:child_with_name("before"); | 375 local before = elem.tags[1]:child_with_name("before"); |
375 local index = elem.tags[1]:child_with_name("index"); | 376 local index = elem.tags[1]:child_with_name("index"); |
376 local s, e = 1, 1+max; | 377 local s, e = 1, 1+max; |
404 if e > count + 1 then e = count + 1; end | 405 if e > count + 1 then e = count + 1; end |
405 -- Assuming result set is sorted. | 406 -- Assuming result set is sorted. |
406 for i = s, e-1 do | 407 for i = s, e-1 do |
407 reply:add_child(st.stanza('chat', resset[i].attr)); | 408 reply:add_child(st.stanza('chat', resset[i].attr)); |
408 end | 409 end |
409 local set = st.stanza('set', {xmlns='http://jabber.org/protocol/rsm'}); | 410 local set = st.stanza('set', {xmlns = xmlns_rsm}); |
410 if s <= e-1 then | 411 if s <= e-1 then |
411 set:tag('first', {index=s-1}):text(gen_uid(resset[s])):up() | 412 set:tag('first', {index=s-1}):text(gen_uid(resset[s])):up() |
412 :tag('last'):text(gen_uid(resset[e-1])):up(); | 413 :tag('last'):text(gen_uid(resset[e-1])):up(); |
413 end | 414 end |
414 set:tag('count'):text(tostring(count)):up(); | 415 set:tag('count'):text(tostring(count)):up(); |
417 origin.send(reply); | 418 origin.send(reply); |
418 return true; | 419 return true; |
419 end | 420 end |
420 | 421 |
421 local function retrieve_handler(event) | 422 local function retrieve_handler(event) |
422 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); | 423 local origin, stanza = event.origin, event.stanza; |
424 local node, host = origin.username, origin.host; | |
425 local data = dm.list_load(node, host, ARCHIVE_DIR); | |
426 local elem = stanza.tags[1]; | |
427 local collection = nil; | |
428 if data then | |
429 for k, v in ipairs(data) do | |
430 local c = st.deserialize(v); | |
431 if c.attr["with"] == elem.attr["with"] | |
432 and c.attr["start"] == elem.attr["start"] then | |
433 collection = c; | |
434 break; | |
435 end | |
436 end | |
437 end | |
438 if not collection then | |
439 -- TODO code=404 | |
440 origin.send(st.error_reply(stanza, "cancel", "item-not-found")); | |
441 return true; | |
442 end | |
443 local resset = {} | |
444 for i, e in ipairs(collection) do | |
445 if e.name == "from" or e.name == "to" then | |
446 table.insert(resset, e); | |
447 end | |
448 end | |
449 collection.attr['xmlns'] = 'urn:xmpp:archive'; | |
450 local reply = st.reply(stanza):tag('chat', collection.attr); | |
451 local count = table.getn(resset); | |
452 if count > 0 then | |
453 local max = elem.tags[1]:child_with_name("max"); | |
454 if max then | |
455 max = tonumber(max:get_text()) or 100; | |
456 else max = 100; end | |
457 local after = elem.tags[1]:child_with_name("after"); | |
458 local before = elem.tags[1]:child_with_name("before"); | |
459 local index = elem.tags[1]:child_with_name("index"); | |
460 local s, e = 1, 1+max; | |
461 if after then | |
462 after = tonumber(after:get_text()); | |
463 if not after or after < 1 or after > count then -- not found | |
464 origin.send(st.error_reply(stanza, "cancel", "item-not-found")); | |
465 return true; | |
466 end | |
467 s = after + 1; | |
468 e = s + max; | |
469 elseif before then | |
470 before = tonumber(before:get_text()); | |
471 if not before then -- the last page | |
472 e = count + 1; | |
473 s = e - max; | |
474 elseif before < 1 or before > count then | |
475 origin.send(st.error_reply(stanza, "cancel", "item-not-found")); | |
476 return true; | |
477 else | |
478 e = before; | |
479 s = e - max; | |
480 end | |
481 elseif index then | |
482 s = tonumber(index:get_text()) + 1; -- 0-based | |
483 e = s + max; | |
484 end | |
485 if s < 1 then s = 1; end | |
486 if e > count + 1 then e = count + 1; end | |
487 -- Assuming result set is sorted. | |
488 for i = s, e-1 do | |
489 reply:add_child(resset[i]); | |
490 end | |
491 local set = st.stanza('set', {xmlns = xmlns_rsm}); | |
492 if s <= e-1 then | |
493 set:tag('first', {index=s-1}):text(tostring(s)):up() | |
494 :tag('last'):text(tostring(e-1)):up(); | |
495 end | |
496 set:tag('count'):text(tostring(count)):up(); | |
497 reply:add_child(set); | |
498 end | |
499 origin.send(reply); | |
423 return true; | 500 return true; |
424 end | 501 end |
425 | 502 |
426 local function remove_handler(event) | 503 local function remove_handler(event) |
427 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); | 504 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); |
482 | 559 |
483 module:hook("message/full", msg_handler, 10); | 560 module:hook("message/full", msg_handler, 10); |
484 module:hook("message/bare", msg_handler, 10); | 561 module:hook("message/bare", msg_handler, 10); |
485 | 562 |
486 -- FIXME sort collections | 563 -- FIXME sort collections |
487 | 564 -- TODO exactmatch |