Comparison

mod_http_muc_log/mod_http_muc_log.lua @ 1654:1a6d6221c5f6

mod_http_muc_log: Cleanup [luacheck]
author Kim Alvefur <zash@zash.se>
date Tue, 07 Apr 2015 18:12:40 +0200
parent 1625:c427de617ada
child 1671:c813b69ae279
comparison
equal deleted inserted replaced
1653:1fe899527ee5 1654:1a6d6221c5f6
70 return value; 70 return value;
71 end 71 end
72 end)); 72 end));
73 end 73 end
74 74
75 local template = "Could not load template" 75 local template;
76 do 76 do
77 local template_file = module:get_option_string(module.name .. "_template", module.name .. ".html"); 77 local template_file = module:get_option_string(module.name .. "_template", module.name .. ".html");
78 template_file = assert(module:load_resource(template_file)); 78 template_file = assert(module:load_resource(template_file));
79 template = template_file:read("*a"); 79 template = template_file:read("*a");
80 template_file:close(); 80 template_file:close();
81 end 81 end
82 82
83 local base_url = module:http_url() .. '/'; 83 -- local base_url = module:http_url() .. '/'; -- TODO: Generate links in a smart way
84 local get_link do 84 local get_link do
85 local link, path = { path = '/' }, { "", "", is_directory = true }; 85 local link, path = { path = '/' }, { "", "", is_directory = true };
86 function get_link(room, date) 86 function get_link(room, date)
87 path[1], path[2] = room, date; 87 path[1], path[2] = room, date;
88 path.is_directory = not date; 88 path.is_directory = not date;
107 local t_diff = os_time(os_date("*t")) - os_time(os_date("!*t")); 107 local t_diff = os_time(os_date("*t")) - os_time(os_date("!*t"));
108 local function time(t) 108 local function time(t)
109 return os_time(t) + t_diff; 109 return os_time(t) + t_diff;
110 end 110 end
111 111
112 local function find_once(room, query, retval)
113 if query then query.limit = 1; else query = { limit = 1 }; end
114 local iter, err = archive:find(room, query);
115 if not iter then return iter, err; end
116 if retval then
117 return select(retval, iter());
118 end
119 return iter();
120 end
121
112 local function years_page(event, path) 122 local function years_page(event, path)
113 local request, response = event.request, event.response; 123 local response = event.response;
114 124
115 local room = nodeprep(path:match("^(.*)/$")); 125 local room = nodeprep(path:match("^(.*)/$"));
116 if not room or not public_room(room) then return end 126 if not room or not public_room(room) then return end
117 127
118 local dates = mt.new(); 128 local dates = mt.new();
119 module:log("debug", "Find all dates with messages"); 129 module:log("debug", "Find all dates with messages");
120 local next_day, t; 130 local next_day;
121 repeat 131 repeat
122 local iter = archive:find(room, { 132 local when = find_once(room, { start = next_day; with = "message<groupchat"; }, 3);
123 start = next_day; 133 if not when then break; end
124 limit = 1; 134 local t = os_date("!*t", when);
125 with = "message<groupchat"; 135 dates:set(t.year, t.month, t.day, when );
126 }) 136 next_day = when + (86400 - (when % 86400));
127 if not iter then break end
128 next_day = nil;
129 for key, message, when in iter do
130 t = os_date("!*t", when);
131 dates:set(t.year, t.month, t.day, when );
132 next_day = when + (86400 - (when % 86400));
133 break;
134 end
135 until not next_day; 137 until not next_day;
136 138
137 local year, years; 139 local years = {};
138 local month, months; 140
139 local week, weeks; 141 for current_year, months_t in pairs(dates.data) do
140 local days; 142 local t = { year = current_year, month = 1, day = 1 };
141 local tmp, n; 143 local months = { };
142 144 local year = { year = current_year, months = months };
143 years = {};
144
145 for Y, m in pairs(dates.data) do
146 t = { year = Y, month = 1, day = 1 };
147 months = { };
148 year = { year = Y, months = months };
149 years[#years+1] = year; 145 years[#years+1] = year;
150 for m, d in pairs(m) do 146 for current_month, days_t in pairs(months_t) do
151 t.day = 1; 147 t.day = 1;
152 t.month = m; 148 t.month = current_month;
153 tmp = os_date("!*t", time(t)); 149 local tmp = os_date("!*t", time(t));
154 days = {}; 150 local days = {};
155 week = { days = days } 151 local week = { days = days }
156 weeks = { week }; 152 local weeks = { week };
157 month = { year = year.year, month = os_date("!%B", time(t)), n = m, weeks = weeks }; 153 local month = { year = year.year, month = os_date("!%B", time(t)), n = current_month, weeks = weeks };
158 months[#months+1] = month; 154 months[#months+1] = month;
159 n = 1; 155 local current_day = 1;
160 for i=1, (tmp.wday+5)%7 do 156 for _=1, (tmp.wday+5)%7 do
161 days[n], n = {}, n+1; 157 days[current_day], current_day = {}, current_day+1;
162 end 158 end
163 for i = 1, 31 do 159 for i = 1, 31 do
164 t.day = i; 160 t.day = i;
165 tmp = os_date("!*t", time(t)); 161 tmp = os_date("!*t", time(t));
166 if tmp.month ~= m then break end 162 if tmp.month ~= current_month then break end
167 if i > 1 and tmp.wday == 2 then 163 if i > 1 and tmp.wday == 2 then
168 days = {}; 164 days = {};
169 weeks[#weeks+1] = { days = days }; 165 weeks[#weeks+1] = { days = days };
170 n = 1; 166 current_day = 1;
171 end 167 end
172 days[n], n = { wday = tmp.wday, day = i, href = d[i] and datetime.date(d[i]) }, n+1; 168 days[current_day], current_day = { wday = tmp.wday, day = i, href = days_t[i] and datetime.date(days_t[i]) }, current_day+1;
173 end 169 end
174 end 170 end
175 table.sort(year, sort_m); 171 table.sort(year, sort_m);
176 end 172 end
177 table.sort(years, sort_Y); 173 table.sort(years, sort_Y);
186 }; 182 };
187 }); 183 });
188 end 184 end
189 185
190 local function logs_page(event, path) 186 local function logs_page(event, path)
191 local request, response = event.request, event.response; 187 local response = event.response;
192 188
193 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$"); 189 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$");
194 room = nodeprep(room); 190 room = nodeprep(room);
195 if not room then 191 if not room then
196 return years_page(event, path); 192 return years_page(event, path);
201 local iter, err = archive:find(room, { 197 local iter, err = archive:find(room, {
202 ["start"] = datetime.parse(date.."T00:00:00Z"); 198 ["start"] = datetime.parse(date.."T00:00:00Z");
203 ["end"] = datetime.parse(date.."T23:59:59Z"); 199 ["end"] = datetime.parse(date.."T23:59:59Z");
204 -- with = "message<groupchat"; 200 -- with = "message<groupchat";
205 }); 201 });
206 if not iter then return 500; end 202 if not iter then
203 module:log("warn", "Could not search archive: %s", err or "no error");
204 return 500;
205 end
207 206
208 local first, last; 207 local first, last;
209 local verb, subject, body; 208 local verb, subject, body;
210 for key, item, when in iter do 209 for key, item, when in iter do
211 body = item:get_child_text("body"); 210 body = item:get_child_text("body");
233 first = first or key; 232 first = first or key;
234 last = key; 233 last = key;
235 end 234 end
236 if i == 1 then return end -- No items 235 if i == 1 then return end -- No items
237 236
238 local next_when = "";
239 local prev_when = "";
240
241 module:log("debug", "Find next date with messages"); 237 module:log("debug", "Find next date with messages");
242 for key, message, when in archive:find(room, { 238 local next_when = find_once(room, { after = last }, 3);
243 after = last; 239 if next_when then
244 limit = 1; 240 next_when = datetime.date(next_when);
245 }) do 241 module:log("debug", "Next message: %s", datetime.datetime(next_when));
246 next_when = datetime.date(when); 242 else
247 module:log("debug", "Next message: %s", datetime.datetime(when)); 243 next_when = "";
248 end 244 end
249 245
250 module:log("debug", "Find prev date with messages"); 246 module:log("debug", "Find prev date with messages");
251 for key, message, when in archive:find(room, { 247 local prev_when = find_once(room, { before = first, reverse = true }, 3);
252 before = first; 248 if prev_when then
253 limit = 1; 249 prev_when = datetime.date(prev_when);
254 reverse = true; 250 module:log("debug", "Previous message: %s", datetime.datetime(prev_when));
255 }) do 251 else
256 prev_when = datetime.date(when); 252 prev_when = "";
257 module:log("debug", "Previous message: %s", datetime.datetime(when));
258 end 253 end
259 254
260 response.headers.content_type = "text/html; charset=utf-8"; 255 response.headers.content_type = "text/html; charset=utf-8";
261 return render(template, { 256 return render(template, {
262 title = ("%s - %s"):format(get_room(room):get_name(), date); 257 title = ("%s - %s"):format(get_room(room):get_name(), date);
269 }; 264 };
270 }); 265 });
271 end 266 end
272 267
273 local function list_rooms(event) 268 local function list_rooms(event)
274 local request, response = event.request, event.response; 269 local response = event.response;
275 local room_list, i = {}, 1; 270 local room_list, i = {}, 1;
276 for room in each_room() do 271 for room in each_room() do
277 if public_room(room) then 272 if public_room(room) then
278 room_list[i], i = { 273 room_list[i], i = {
279 href = get_link(jid_split(room.jid), nil); 274 href = get_link(jid_split(room.jid), nil);
311 response.headers.content_type = "text/html; charset=utf-8"; 306 response.headers.content_type = "text/html; charset=utf-8";
312 return cached[1]; 307 return cached[1];
313 end 308 end
314 309
315 local start = gettime(); 310 local start = gettime();
316 local render = f(event, path); 311 local rendered = f(event, path);
317 module:log("debug", "Rendering took %dms", math.floor( (gettime() - start) * 1000 + 0.5)); 312 module:log("debug", "Rendering took %dms", math.floor( (gettime() - start) * 1000 + 0.5));
318 313
319 if type(render) == "string" then 314 if type(rendered) == "string" then
320 local etag = uuid(); 315 local etag = uuid();
321 cached = { render, etag = etag, date = datetime.date() }; 316 cached = { rendered, etag = etag, date = datetime.date() };
322 response.headers.etag = etag; 317 response.headers.etag = etag;
323 cache[ckey] = cached; 318 cache[ckey] = cached;
324 end 319 end
325 320
326 response.headers.content_type = "text/html; charset=utf-8"; 321 response.headers.content_type = "text/html; charset=utf-8";
327 return render; 322 return rendered;
328 end 323 end
329 end 324 end
330 325
331 -- How is cache invalidation a hard problem? ;) 326 -- How is cache invalidation a hard problem? ;)
332 module:hook("muc-broadcast-message", function (event) 327 module:hook("muc-broadcast-message", function (event)