local st = require "util.stanza";
local datetime = require"util.datetime";
local jid_split = require"util.jid".split;
local nodeprep = require"util.encodings".stringprep.nodeprep;
local uuid = require"util.uuid".generate;
local it = require"util.iterators";
local gettime = require"socket".gettime;
local archive = module:open_store("archive2", "archive");
-- Support both old and new MUC code
local mod_muc = module:depends"muc";
local rooms = rawget(mod_muc, "rooms");
local each_room = rawget(mod_muc, "each_room") or function() return it.values(rooms); end;
if not rooms then
rooms = module:shared"muc/rooms";
end
local get_room_from_jid = rawget(mod_muc, "get_room_from_jid") or
function (jid)
return rooms[jid];
end
local function get_room(name)
local jid = name .. '@' .. module.host;
return get_room_from_jid(jid);
end
module:depends"http";
local function template(data)
local _doc = [[
Like util.template, but deals with plain text
Returns a closure that is called with a table of values
{name} is substituted for values["name"] and is XML escaped
{name!} is substituted without XML escaping
{name?} is optional and is replaced with an empty string if no value exists
]]
return function(values)
return (data:gsub("{([^!}]-)(%p?)}", function (name, opt)
local value = values[name];
if value then
if opt ~= "!" then
return st.xml_escape(value);
end
return value;
elseif opt == "?" then
return "";
end
end));
end
end
local base = template[[
{title}
{title}
{body!}
]]
local dates_template = template(base{
title = "Logs for room {room}";
body = [[
]];
local function public_room(room)
if type(room) == "string" then
room = get_room(room);
end
return room and not room:get_hidden() and not room:get_members_only() and room._data.logging ~= false;
end
-- FIXME Invent some more efficient API for this
local function dates_page(event, path)
local request, response = event.request, event.response;
local room = nodeprep(path:match("^(.*)/$"));
if not room or not public_room(room) then return end
local dates, i = {}, 1;
module:log("debug", "Find all dates with messages");
local next_day;
repeat
local iter = archive:find(room, {
["start"] = next_day;
limit = 1;
})
if not iter then break end
next_day = nil;
for key, message, when in iter do
next_day = datetime.date(when);
dates[i], i = date_line_template{
date = next_day;
}, i + 1;
next_day = datetime.parse(next_day .. "T23:59:59Z") + 1;
break;
end
until not next_day;
return dates_template{
room = room;
lines = table.concat(dates);
};
end
local function logs_page(event, path)
local request, response = event.request, event.response;
local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$");
room = nodeprep(room);
if not room then
return dates_page(event, path);
end
if not public_room(room) then return end
local logs, i = {}, 1;
local iter, err = archive:find(room, {
["start"] = datetime.parse(date.."T00:00:00Z");
["end"] = datetime.parse(date.."T23:59:59Z");
limit = math.huge;
-- with = "message