# HG changeset patch # User shinysky # Date 1278311259 -28800 # Node ID 18a0e5c0bb6286809e99a6d05a09b7b5e4a743f7 # Parent 12d6316d9eabfc9c2609b01aaa43a7f79774c92f mod_archive: Archive Management - Retrieving a List of Collections diff -r 12d6316d9eab -r 18a0e5c0bb62 mod_archive/mod_archive.lua --- a/mod_archive/mod_archive.lua Sun Jul 04 23:38:54 2010 +0500 +++ b/mod_archive/mod_archive.lua Mon Jul 05 14:27:39 2010 +0800 @@ -8,6 +8,7 @@ local st = require "util.stanza"; local dm = require "util.datamanager"; local jid = require "util.jid"; +local datetime = require "util.datetime"; local PREFS_DIR = "archive_prefs"; local ARCHIVE_DIR = "archive"; @@ -29,6 +30,16 @@ dm.store(node, host, PREFS_DIR, st.preserialize(data)); end +local function os_time() + -- return tostring(os.time(os.date('!*t'))); + return datetime.datetime(); +end + +local function date_parse(s) + local year, month, day, hour, min, sec = s:match("(....)-?(..)-?(..)T(..):(..):(..)Z"); + return os.time({year=year, month=month, day=day, hour=hour, min=min, sec=sec}); +end + local function store_msg(msg, node, host, isfrom) local body = msg:child_with_name("body"); local thread = msg:child_with_name("thread"); @@ -36,20 +47,10 @@ local tag = (isfrom and "from") or "to"; if data then for k, v in ipairs(data) do - -- - -- Art thou not Romeo, and a Montague? - -- Neither, fair saint, if either thee dislike. - -- How cam'st thou hither, tell me, and wherefore? - -- I think she might fancy me. - -- local collection = st.deserialize(v); if collection.attr["thread"] == thread:get_text() then -- TODO figure out secs - collection:tag(tag, {secs='1'}):add_child(body); + collection:tag(tag, {secs='1', utc=os_time()}):add_child(body); local ver = tonumber(collection.attr["version"]) + 1; collection.attr["version"] = tostring(ver); data[k] = collection; @@ -59,9 +60,9 @@ end end -- not found, create new collection - -- TODO figure out start time - local collection = st.stanza('chat', {with = isfrom and msg.attr.to or msg.attr.from, start='2010-06-01T09:56:15Z', thread=thread:get_text(), version='0'}); - collection:tag(tag, {secs='0'}):add_child(body); + local utc = os_time(); + local collection = st.stanza('chat', {with = isfrom and msg.attr.to or msg.attr.from, start=utc, thread=thread:get_text(), version='0'}); + collection:tag(tag, {secs='0', utc=utc}):add_child(body); dm.list_append(node, host, ARCHIVE_DIR, st.preserialize(collection)); end @@ -185,7 +186,7 @@ end local function itemremove_handler(event) - -- TODO use 'assert' to check imcoming stanza? + -- TODO use 'assert' to check incoming stanza? -- or use pcall() to catch exceptions? local origin, stanza = event.origin, event.stanza; if stanza.attr.type ~= "set" then @@ -257,31 +258,9 @@ return true; end -local function chat_handler(event) - module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); - return true; -end - -local function list_handler(event) - module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); - return true; -end - -local function modified_handler(event) - module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); - return true; -end - -local function remove_handler(event) - module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); - return true; -end - -local function retrieve_handler(event) - module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); - return true; -end - +------------------------------------------------------------ +-- Manual Archiving +------------------------------------------------------------ local function save_handler(event) local origin, stanza = event.origin, event.stanza; if stanza.attr.type ~= "set" then @@ -303,7 +282,8 @@ if type(newchild) == "table" then if newchild.name == "from" or newchild.name == "to" then collection:add_child(newchild); - elseif newchild.name == "note" or newchild.name == "previous" or newchild.name == "next" or newchild.name == "x" then + elseif newchild.name == "note" or newchild.name == "previous" + or newchild.name == "next" or newchild.name == "x" then local found = false; for i, c in ipairs(collection) do if c.name == newchild.name then @@ -338,6 +318,71 @@ end ------------------------------------------------------------ +-- Archive Management +------------------------------------------------------------ +local function filter_with(with, coll_with) + return not with or coll_with:find(with); +end + +local function filter_start(start, coll_start) + return not start or start <= coll_start; +end + +local function filter_end(endtime, coll_start) + return not endtime or endtime >= coll_start; +end + +local function list_handler(event) + local origin, stanza = event.origin, event.stanza; + local node, host = origin.username, origin.host; + local data = dm.list_load(node, host, ARCHIVE_DIR); + local elem = stanza.tags[1]; + local resset = {} + if data then + for k, v in ipairs(data) do + local collection = st.deserialize(v); + local res = filter_with(elem.attr["with"], collection.attr["with"]); + res = res and filter_start(elem.attr["start"], collection.attr["start"]); + res = res and filter_end(elem.attr["end"], collection.attr["start"]); + if res then + table.insert(resset, collection); + end + end + end + local reply = st.reply(stanza):tag('list', {xmlns='urn:xmpp:archive'}); + if table.getn(resset) > 0 then + local max = tonumber(elem.tags[1].tags[1]:get_text()); + -- Assuming result set is sorted. + for i, c in ipairs(resset) do + if i <= max then + local chat = st.stanza('chat', c.attr); + reply:add_child(chat); + else break; end + end + end + origin.send(reply); + return true; +end + +local function retrieve_handler(event) + module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); + return true; +end + +local function remove_handler(event) + module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); + return true; +end + +------------------------------------------------------------ +-- Replication +------------------------------------------------------------ +local function modified_handler(event) + module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); + return true; +end + +------------------------------------------------------------ -- Message Handler ------------------------------------------------------------ local function msg_handler(data) @@ -367,17 +412,22 @@ return nil; end +-- Preferences module:hook("iq/self/urn:xmpp:archive:pref", preferences_handler); module:hook("iq/self/urn:xmpp:archive:itemremove", itemremove_handler); module:hook("iq/self/urn:xmpp:archive:sessionremove", sessionremove_handler); module:hook("iq/self/urn:xmpp:archive:auto", auto_handler); --- module:hook("iq/self/urn:xmpp:archive:chat", chat_handler); +-- Manual archiving +module:hook("iq/self/urn:xmpp:archive:save", save_handler); +-- Archive management module:hook("iq/self/urn:xmpp:archive:list", list_handler); +module:hook("iq/self/urn:xmpp:archive:retrieve", retrieve_handler); +module:hook("iq/self/urn:xmpp:archive:remove", remove_handler); +-- Replication module:hook("iq/self/urn:xmpp:archive:modified", modified_handler); -module:hook("iq/self/urn:xmpp:archive:remove", remove_handler); -module:hook("iq/self/urn:xmpp:archive:retrieve", retrieve_handler); -module:hook("iq/self/urn:xmpp:archive:save", save_handler); module:hook("message/full", msg_handler, 10); module:hook("message/bare", msg_handler, 10); +-- FIXME sort collections +