comparison 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
comparison
equal deleted inserted replaced
1605:c8a51d1bc96d 1606:2c8b985ebde5
1 local st = require "util.stanza"; 1 local st = require "util.stanza";
2 local mt = require"util.multitable";
2 local datetime = require"util.datetime"; 3 local datetime = require"util.datetime";
3 local jid_split = require"util.jid".split; 4 local jid_split = require"util.jid".split;
4 local nodeprep = require"util.encodings".stringprep.nodeprep; 5 local nodeprep = require"util.encodings".stringprep.nodeprep;
5 local uuid = require"util.uuid".generate; 6 local uuid = require"util.uuid".generate;
6 local it = require"util.iterators"; 7 local it = require"util.iterators";
7 local gettime = require"socket".gettime; 8 local gettime = require"socket".gettime;
8 local url = require"socket.url"; 9 local url = require"socket.url";
9 local xml_escape = st.xml_escape; 10 local xml_escape = st.xml_escape;
10 local t_concat = table.concat; 11 local t_concat = table.concat;
12 local os_time, os_date = os.time, os.date;
11 13
12 local archive = module:open_store("muc_log", "archive"); 14 local archive = module:open_store("muc_log", "archive");
13 15
14 -- Support both old and new MUC code 16 -- Support both old and new MUC code
15 local mod_muc = module:depends"muc"; 17 local mod_muc = module:depends"muc";
90 and not (room.get_hidden or room.is_hidden)(room) 92 and not (room.get_hidden or room.is_hidden)(room)
91 and not (room.get_members_only or room.is_members_only)(room) 93 and not (room.get_members_only or room.is_members_only)(room)
92 and room._data.logging == true); 94 and room._data.logging == true);
93 end 95 end
94 96
95 -- FIXME Invent some more efficient API for this 97 local function sort_Y(a,b) return a.year > b.year end
96 local function dates_page(event, path) 98 local function sort_m(a,b) return a.n > b.n end
99
100 local t_diff = os_time(os_date("*t")) - os_time(os_date("!*t"));
101 local function time(t)
102 return os_time(t) + t_diff;
103 end
104
105 local function years_page(event, path)
97 local request, response = event.request, event.response; 106 local request, response = event.request, event.response;
98 107
99 local room = nodeprep(path:match("^(.*)/$")); 108 local room = nodeprep(path:match("^(.*)/$"));
100 if not room or not public_room(room) then return end 109 if not room or not public_room(room) then return end
101 110
102 local dates, i = {}, 1; 111 local dates = mt.new();
103 module:log("debug", "Find all dates with messages"); 112 module:log("debug", "Find all dates with messages");
104 local prev_day; 113 local next_day, t;
105 repeat 114 repeat
106 local iter = archive:find(room, { 115 local iter = archive:find(room, {
107 ["end"] = prev_day; 116 start = next_day;
108 limit = 1; 117 limit = 1;
109 with = "message<groupchat"; 118 with = "message<groupchat";
110 reverse = true;
111 }) 119 })
112 if not iter then break end 120 if not iter then break end
113 prev_day = nil; 121 next_day = nil;
114 for key, message, when in iter do 122 for key, message, when in iter do
115 prev_day = datetime.date(when); 123 t = os_date("!*t", when);
116 dates[i], i = { 124 dates:set(t.year, t.month, t.day, when );
117 date = prev_day; 125 next_day = when + (86400 - (when % 86400));
118 }, i + 1;
119 prev_day = datetime.parse(prev_day .. "T00:00:00Z") - 1;
120 break; 126 break;
121 end 127 end
122 until not prev_day; 128 until not next_day;
129
130 local year, years;
131 local month, months;
132 local week, weeks;
133 local days;
134 local tmp, n;
135
136 years = {};
137
138 for Y, m in pairs(dates.data) do
139 t = { year = Y, month = 1, day = 1 };
140 months = { };
141 year = { year = Y, months = months };
142 years[#years+1] = year;
143 for m, d in pairs(m) do
144 t.day = 1;
145 t.month = m;
146 tmp = os_date("!*t", time(t));
147 days = {};
148 week = { days = days }
149 weeks = { week };
150 month = { year = year.year, month = os_date("!%B", time(t)), n = m, weeks = weeks };
151 months[#months+1] = month;
152 n = 1;
153 for i=1, (tmp.wday+5)%7 do
154 days[n], n = {}, n+1;
155 end
156 for i = 1, 31 do
157 t.day = i;
158 tmp = os_date("!*t", time(t));
159 if tmp.month ~= m then break end
160 if i > 1 and tmp.wday == 2 then
161 days = {};
162 weeks[#weeks+1] = { days = days };
163 n = 1;
164 end
165 if d[i] then
166 days[n], n = { wday = tmp.wday, links = {{ href = datetime.date(d[i]), day = i }} }, n+1;
167 else
168 days[n], n = { wday = tmp.wday, plain = i }, n+1;
169 end
170 end
171 end
172 table.sort(year, sort_m);
173 end
174 table.sort(years, sort_Y);
123 175
124 response.headers.content_type = "text/html; charset=utf-8"; 176 response.headers.content_type = "text/html; charset=utf-8";
125 return render(template, { 177 return render(template, {
126 title = get_room(room):get_name(); 178 title = get_room(room):get_name();
127 jid = get_room(room).jid; 179 jid = get_room(room).jid;
128 dates = dates; 180 years = years;
129 links = { 181 links = {
130 { href = "../", rel = "up", text = "Back to room list" }, 182 { href = "../", rel = "up", text = "Back to room list" },
131 }; 183 };
132 }); 184 });
133 end 185 end
136 local request, response = event.request, event.response; 188 local request, response = event.request, event.response;
137 189
138 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$"); 190 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$");
139 room = nodeprep(room); 191 room = nodeprep(room);
140 if not room then 192 if not room then
141 return dates_page(event, path); 193 return years_page(event, path);
142 end 194 end
143 if not public_room(room) then return end 195 if not public_room(room) then return end
144 196
145 local logs, i = {}, 1; 197 local logs, i = {}, 1;
146 local iter, err = archive:find(room, { 198 local iter, err = archive:find(room, {
206 return render(template, { 258 return render(template, {
207 title = ("%s - %s"):format(get_room(room):get_name(), date); 259 title = ("%s - %s"):format(get_room(room):get_name(), date);
208 jid = get_room(room).jid; 260 jid = get_room(room).jid;
209 lines = logs; 261 lines = logs;
210 links = { 262 links = {
211 { href = "./", rel = "up", text = "Back to date list" }, 263 { href = "./", rel = "up", text = "Back to calendar" },
212 { href = prev_when, rel = "prev", text = prev_when}, 264 { href = prev_when, rel = "prev", text = prev_when},
213 { href = next_when, rel = "next", text = next_when}, 265 { href = next_when, rel = "next", text = next_when},
214 }; 266 };
215 }); 267 });
216 end 268 end