Mercurial > prosody-modules
diff mod_http_muc_log/mod_http_muc_log.lua @ 1606:2c8b985ebde5
mod_http_muc_log: Switch to a calendar view for selecting dates
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 10 Feb 2015 15:00:10 +0100 |
parents | c8a51d1bc96d |
children | c427de617ada |
line wrap: on
line diff
--- a/mod_http_muc_log/mod_http_muc_log.lua Mon Feb 09 00:47:38 2015 +0100 +++ b/mod_http_muc_log/mod_http_muc_log.lua Tue Feb 10 15:00:10 2015 +0100 @@ -1,4 +1,5 @@ local st = require "util.stanza"; +local mt = require"util.multitable"; local datetime = require"util.datetime"; local jid_split = require"util.jid".split; local nodeprep = require"util.encodings".stringprep.nodeprep; @@ -8,6 +9,7 @@ local url = require"socket.url"; local xml_escape = st.xml_escape; local t_concat = table.concat; +local os_time, os_date = os.time, os.date; local archive = module:open_store("muc_log", "archive"); @@ -92,40 +94,90 @@ and room._data.logging == true); end --- FIXME Invent some more efficient API for this -local function dates_page(event, path) +local function sort_Y(a,b) return a.year > b.year end +local function sort_m(a,b) return a.n > b.n end + +local t_diff = os_time(os_date("*t")) - os_time(os_date("!*t")); +local function time(t) + return os_time(t) + t_diff; +end + +local function years_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; + local dates = mt.new(); module:log("debug", "Find all dates with messages"); - local prev_day; + local next_day, t; repeat local iter = archive:find(room, { - ["end"] = prev_day; + start = next_day; limit = 1; with = "message<groupchat"; - reverse = true; }) if not iter then break end - prev_day = nil; + next_day = nil; for key, message, when in iter do - prev_day = datetime.date(when); - dates[i], i = { - date = prev_day; - }, i + 1; - prev_day = datetime.parse(prev_day .. "T00:00:00Z") - 1; + t = os_date("!*t", when); + dates:set(t.year, t.month, t.day, when ); + next_day = when + (86400 - (when % 86400)); break; end - until not prev_day; + until not next_day; + + local year, years; + local month, months; + local week, weeks; + local days; + local tmp, n; + + years = {}; + + for Y, m in pairs(dates.data) do + t = { year = Y, month = 1, day = 1 }; + months = { }; + year = { year = Y, months = months }; + years[#years+1] = year; + for m, d in pairs(m) do + t.day = 1; + t.month = m; + tmp = os_date("!*t", time(t)); + days = {}; + week = { days = days } + weeks = { week }; + month = { year = year.year, month = os_date("!%B", time(t)), n = m, weeks = weeks }; + months[#months+1] = month; + n = 1; + for i=1, (tmp.wday+5)%7 do + days[n], n = {}, n+1; + end + for i = 1, 31 do + t.day = i; + tmp = os_date("!*t", time(t)); + if tmp.month ~= m then break end + if i > 1 and tmp.wday == 2 then + days = {}; + weeks[#weeks+1] = { days = days }; + n = 1; + end + if d[i] then + days[n], n = { wday = tmp.wday, links = {{ href = datetime.date(d[i]), day = i }} }, n+1; + else + days[n], n = { wday = tmp.wday, plain = i }, n+1; + end + end + end + table.sort(year, sort_m); + end + table.sort(years, sort_Y); response.headers.content_type = "text/html; charset=utf-8"; return render(template, { title = get_room(room):get_name(); jid = get_room(room).jid; - dates = dates; + years = years; links = { { href = "../", rel = "up", text = "Back to room list" }, }; @@ -138,7 +190,7 @@ 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); + return years_page(event, path); end if not public_room(room) then return end @@ -208,7 +260,7 @@ jid = get_room(room).jid; lines = logs; links = { - { href = "./", rel = "up", text = "Back to date list" }, + { href = "./", rel = "up", text = "Back to calendar" }, { href = prev_when, rel = "prev", text = prev_when}, { href = next_when, rel = "next", text = next_when}, };