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 |
