Mercurial > prosody-modules
comparison mod_muc_log_http/mod_muc_log_http.lua @ 94:941fd7d8b9b2
mod_muc_log: split into mod_muc_log and mod_muc_log_http
mod_muc_log: should be enabled per muc component which should log!
mod_muc_log_http: handle /me messages, add previous, next day links to day view, add link to speeqe.com to directly join the room,
make the window recalculate the content div size, scrollbars are only shown when needed
author | Thilo Cestonaro <thilo@cestona.ro> |
---|---|
date | Tue, 17 Nov 2009 21:19:17 +0100 |
parents | |
children | e3c09996cf7b |
comparison
equal
deleted
inserted
replaced
93:611d16867410 | 94:941fd7d8b9b2 |
---|---|
1 -- Copyright (C) 2009 Thilo Cestonaro | |
2 -- | |
3 -- This project is MIT/X11 licensed. Please see the | |
4 -- COPYING file in the source package for more information. | |
5 -- | |
6 local prosody = prosody; | |
7 local tabSort = table.sort; | |
8 local tonumber = _G.tonumber; | |
9 local tostring = _G.tostring; | |
10 local strformat = string.format; | |
11 local splitJid = require "util.jid".split; | |
12 local config_get = require "core.configmanager".get; | |
13 local httpserver = require "net.httpserver"; | |
14 local datamanager = require "util.datamanager"; | |
15 local data_load, data_getpath = datamanager.load, datamanager.getpath; | |
16 local datastore = "muc_log"; | |
17 local muc_hosts = {}; | |
18 local config = nil; | |
19 | |
20 local lom = require "lxp.lom"; | |
21 | |
22 --[[ LuaFileSystem | |
23 * URL: http://www.keplerproject.org/luafilesystem/index.html | |
24 * Install: luarocks install luafilesystem | |
25 * ]] | |
26 local lfs = require "lfs"; | |
27 | |
28 | |
29 --[[ | |
30 * Default templates for the html output. | |
31 ]]-- | |
32 local html = {}; | |
33 html.doc = [[<html> | |
34 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > | |
35 <head> | |
36 <title>muc_log</title> | |
37 </head> | |
38 <script type="text/javascript"><!-- | |
39 function showHide(name) { | |
40 var eles = document.getElementsByName(name); | |
41 for (var i = 0; i < eles.length; i++) { | |
42 eles[i].style.display = eles[i].style.display != "none" ? "none" : ""; | |
43 } | |
44 | |
45 } | |
46 --></script> | |
47 <style type="text/css"> | |
48 <!-- | |
49 .timestuff {color: #AAAAAA; text-decoration: none;} | |
50 .muc_join {color: #009900; font-style: italic;} | |
51 .muc_leave {color: #009900; font-style: italic;} | |
52 .muc_statusChange {color: #009900; font-style: italic;} | |
53 .muc_title {color: #BBBBBB; font-size: 32px;} | |
54 .muc_titleChange {color: #009900; font-style: italic;} | |
55 .muc_kick {color: #009900; font-style: italic;} | |
56 .muc_bann {color: #009900; font-style: italic;} | |
57 .muc_msg_nick {color: #0000AA;} | |
58 .muc_msg_me {color: #0000AA;} | |
59 .join_link {font-height: 9px;} | |
60 //--> | |
61 </style> | |
62 <body> | |
63 ###BODY_STUFF### | |
64 </body> | |
65 </html>]]; | |
66 | |
67 html.components = {}; | |
68 html.components.bit = [[<a href="###COMPONENT###/">###COMPONENT###</a><br />]] | |
69 html.components.body = [[<h2>MUC hosts available on this server:</h2><hr /><p> | |
70 ###COMPONENTS_STUFF### | |
71 </p><hr />]]; | |
72 | |
73 html.rooms = {}; | |
74 html.rooms.bit = [[<a href="###ROOM###/">###ROOM###</a><br />]] | |
75 html.rooms.body = [[<h2>Rooms hosted on MUC host: ###COMPONENT###</h2><hr /><p> | |
76 ###ROOMS_STUFF### | |
77 </p><hr />]]; | |
78 | |
79 html.days = {}; | |
80 html.days.bit = [[<a href="###BARE_DAY###/">20###YEAR###/###MONTH###/###DAY###</a><br />]]; | |
81 html.days.body = [[<h2>available logged days of room: ###JID###</h2><hr /><p> | |
82 ###DAYS_STUFF### | |
83 </p><hr />]]; | |
84 | |
85 html.day = {}; | |
86 html.day.title = [[Subject: <font class="muc_title">###TITLE###</font>]]; | |
87 html.day.time = [[<a name="###TIME###" href="####TIME###" class="timestuff">[###TIME###]</a> ]]; -- the one ####TIME### need to stay! it will evaluate to e.g. #09:10:56 which is an anker then | |
88 html.day.presence = {}; | |
89 html.day.presence.join = [[<div name="joinLeave" style="display: ###SHOWHIDE###;">###TIME_STUFF###<font class="muc_join"> *** ###NICK### joins the room</font><br /></div>]]; | |
90 html.day.presence.leave = [[<div name="joinLeave" style="display: ###SHOWHIDE###;">###TIME_STUFF###<font class="muc_leave"> *** ###NICK### leaves the room</font><br /></div>]]; | |
91 html.day.presence.statusText = [[ and his status message is "###STATUS###"]]; | |
92 html.day.presence.statusChange = [[<div name="status" style="display: ###SHOWHIDE###;">###TIME_STUFF###<font class="muc_statusChange"> *** ###NICK### shows now as "###SHOW###"###STATUS_STUFF###</font><br /></div>]]; | |
93 html.day.message = [[###TIME_STUFF###<font class="muc_msg_nick"><###NICK###></font> ###MSG###<br />]]; | |
94 html.day.message_me = [[###TIME_STUFF###<font class="muc_msg_me">*###NICK### ###MSG###</font><br />]]; | |
95 html.day.titleChange = [[###TIME_STUFF###<font class="muc_titleChange"> *** ###NICK### changed the title to "###TITLE###"</font><br />]]; | |
96 html.day.reason = [[, the reason was "###REASON###"]] | |
97 html.day.kick = [[###TIME_STUFF###<font class="muc_kick"> *** ###VICTIM### got kicked###REASON_STUFF###</font><br />]]; | |
98 html.day.bann = [[###TIME_STUFF###<font class="muc_bann"> *** ###VICTIM### got banned###REASON_STUFF###</font><br />]]; | |
99 html.day.day_link = [[<a href="../###DAY###/">###TEXT###</a>]] | |
100 html.day.body = [[<h2>Logs of room ###JID### of 20###YEAR###/###MONTH###/###DAY###</h2> | |
101 <p>###TITLE_STUFF###</p> | |
102 <font class="join_link"><a href="http://speeqe.com/room/###JID###/" target="_blank">Join room now via speeqe.com!</a></font><br /> | |
103 ###PREVIOUS_LINK### ###NEXT_LINK###<br /> | |
104 <input type="checkbox" onclick="showHide('joinLeave')" ###JOIN_CHECKED###/>show/hide joins and Leaves</button> | |
105 <input type="checkbox" onclick="showHide('status')" ###STATUS_CHECKED###/>show/hide status changes</button> | |
106 <hr /><div id="main" style="overflow: auto;"> | |
107 ###DAY_STUFF### | |
108 </div><hr /> | |
109 <script><!-- | |
110 window.captureEvents(Event.RESIZE | Event.LOAD); | |
111 window.onresize = resize; | |
112 window.onload = resize; | |
113 function resize(e) { | |
114 var ele = document.getElementById("main"); | |
115 ele.style.height = window.innerHeight - ele.offsetTop - 25; | |
116 } | |
117 | |
118 --></script>]]; | |
119 | |
120 local function checkDatastorePathExists(node, host, today, create) | |
121 create = create or false; | |
122 local path = data_getpath(node, host, datastore, "dat", true); | |
123 path = path:gsub("/[^/]*$", ""); | |
124 | |
125 -- check existance | |
126 local attributes, err = lfs.attributes(path); | |
127 if attributes == nil or attributes.mode ~= "directory" then | |
128 module:log("warn", "muc_log folder isn't a folder: %s", path); | |
129 return false; | |
130 end | |
131 | |
132 attributes, err = lfs.attributes(path .. "/" .. today); | |
133 if attributes == nil then | |
134 if create then | |
135 return lfs.mkdir(path .. "/" .. today); | |
136 else | |
137 return false; | |
138 end | |
139 elseif attributes.mode == "directory" then | |
140 return true; | |
141 end | |
142 return false; | |
143 end | |
144 | |
145 function createDoc(body) | |
146 if body then | |
147 return html.doc:gsub("###BODY_STUFF###", body); | |
148 end | |
149 end | |
150 | |
151 local function htmlEscape(t) | |
152 t = t:gsub("<", "<"); | |
153 t = t:gsub(">", ">"); | |
154 t = t:gsub("(http://[%a%d@%.:/&%?=%-_#]+)", [[<a href="%1">%1</a>]]); | |
155 t = t:gsub("\n", "<br />"); | |
156 return t; | |
157 end | |
158 | |
159 function splitUrl(url) | |
160 local tmp = url:sub(string.len("/muc_log/") + 1); | |
161 local day = nil; | |
162 local room = nil; | |
163 local component = nil; | |
164 local at = nil; | |
165 local slash = nil; | |
166 local slash2 = nil; | |
167 | |
168 slash = tmp:find("/"); | |
169 if slash then | |
170 component = tmp:sub(1, slash - 1); | |
171 if tmp:len() > slash then | |
172 room = tmp:sub(slash + 1); | |
173 slash = room:find("/"); | |
174 if slash then | |
175 tmp = room; | |
176 room = tmp:sub(1, slash - 1); | |
177 if tmp:len() > slash then | |
178 day = tmp:sub(slash + 1); | |
179 slash = day:find("/"); | |
180 if slash then | |
181 day = day:sub(1, slash - 1); | |
182 end | |
183 end | |
184 end | |
185 end | |
186 end | |
187 | |
188 return room, component, day; | |
189 end | |
190 | |
191 local function generateComponentListSiteContent() | |
192 local components = ""; | |
193 for component,muc_host in pairs(muc_hosts) do | |
194 components = components .. html.components.bit:gsub("###COMPONENT###", component); | |
195 end | |
196 if components ~= "" then | |
197 return html.components.body:gsub("###COMPONENTS_STUFF###", components); | |
198 end | |
199 end | |
200 | |
201 local function generateRoomListSiteContent(component) | |
202 local rooms = ""; | |
203 if prosody.hosts[component] and prosody.hosts[component].muc ~= nil then | |
204 for jid, room in pairs(prosody.hosts[component].muc.rooms) do | |
205 local node = splitJid(jid); | |
206 if not room._data.hidden and node then | |
207 rooms = rooms .. html.rooms.bit:gsub("###ROOM###", node):gsub("###COMPONENT###", component); | |
208 end | |
209 end | |
210 if rooms ~= "" then | |
211 return html.rooms.body:gsub("###ROOMS_STUFF###", rooms):gsub("###COMPONENT###", component); | |
212 end | |
213 end | |
214 end | |
215 | |
216 local function generateDayListSiteContentByRoom(bareRoomJid) | |
217 local days = ""; | |
218 local arrDays = {}; | |
219 local tmp; | |
220 local node, host, resource = splitJid(bareRoomJid); | |
221 local path = data_getpath(node, host, datastore); | |
222 local room = nil; | |
223 local attributes = nil; | |
224 | |
225 path = path:gsub("/[^/]*$", ""); | |
226 attributes = lfs.attributes(path); | |
227 if muc_hosts[host] and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bareRoomJid] ~= nil then | |
228 room = prosody.hosts[host].muc.rooms[bareRoomJid]; | |
229 if room._data.hidden then | |
230 room = nil | |
231 end | |
232 end | |
233 if attributes ~= nil and room ~= nil then | |
234 for file in lfs.dir(path) do | |
235 local year, month, day = file:match("^(%d%d)(%d%d)(%d%d)"); | |
236 if year ~= nil and month ~= nil and day ~= nil and | |
237 year ~= "" and month ~= "" and day ~= "" | |
238 then | |
239 arrDays[#arrDays + 1] = {bare=file, year=year, month=month, day=day}; | |
240 end | |
241 end | |
242 tabSort(arrDays, function(a,b) | |
243 return a.bare < b.bare; | |
244 end); | |
245 for _, date in pairs(arrDays) do | |
246 tmp = html.days.bit; | |
247 tmp = tmp:gsub("###ROOM###", node):gsub("###COMPONENT###", host); | |
248 tmp = tmp:gsub("###BARE_DAY###", date.bare); | |
249 tmp = tmp:gsub("###YEAR###", date.year):gsub("###MONTH###", date.month):gsub("###DAY###", date.day); | |
250 days = tmp .. days; | |
251 end | |
252 end | |
253 | |
254 if days ~= "" then | |
255 tmp = html.days.body:gsub("###DAYS_STUFF###", days); | |
256 return tmp:gsub("###JID###", bareRoomJid); | |
257 end | |
258 end | |
259 | |
260 local function parseIqStanza(stanza, timeStuff, nick) | |
261 local text = nil; | |
262 local victim = nil; | |
263 if(stanza.attr.type == "set") then | |
264 for _,tag in ipairs(stanza) do | |
265 if tag.tag == "query" then | |
266 for _,item in ipairs(tag) do | |
267 if item.tag == "item" and item.attr.nick ~= nil and tostring(item.attr.role) == 'none' then | |
268 victim = item.attr.nick; | |
269 for _,reason in ipairs(item) do | |
270 if reason.tag == "reason" then | |
271 text = reason[1]; | |
272 break; | |
273 end | |
274 end | |
275 break; | |
276 end | |
277 end | |
278 break; | |
279 end | |
280 end | |
281 if victim ~= nil then | |
282 if text ~= nil then | |
283 text = html.day.reason:gsub("###REASON###", htmlEscape(text)); | |
284 else | |
285 text = ""; | |
286 end | |
287 return html.day.kick:gsub("###TIME_STUFF###", timeStuff):gsub("###VICTIM###", victim):gsub("###REASON_STUFF###", text); | |
288 end | |
289 end | |
290 return; | |
291 end | |
292 | |
293 local function parsePresenceStanza(stanza, timeStuff, nick) | |
294 local ret = ""; | |
295 local showJoin = "block" | |
296 | |
297 if config and not config.showJoin then | |
298 showJoin = "none"; | |
299 end | |
300 | |
301 if stanza.attr.type == nil then | |
302 local showStatus = "block" | |
303 if config and not config.showStatus then | |
304 showStatus = "none"; | |
305 end | |
306 local show, status = nil, ""; | |
307 local alreadyJoined = false; | |
308 for _, tag in ipairs(stanza) do | |
309 if tag.tag == "alreadyJoined" then | |
310 alreadyJoined = true; | |
311 elseif tag.tag == "show" then | |
312 show = tag[1]; | |
313 elseif tag.tag == "status" then | |
314 status = tag[1]; | |
315 end | |
316 end | |
317 if alreadyJoined == true then | |
318 if show == nil then | |
319 show = "online"; | |
320 end | |
321 ret = html.day.presence.statusChange:gsub("###TIME_STUFF###", timeStuff); | |
322 if status ~= "" then | |
323 status = html.day.presence.statusText:gsub("###STATUS###", htmlEscape(status)); | |
324 end | |
325 ret = ret:gsub("###SHOW###", show):gsub("###NICK###", nick):gsub("###SHOWHIDE###", showStatus):gsub("###STATUS_STUFF###", status); | |
326 else | |
327 ret = html.day.presence.join:gsub("###TIME_STUFF###", timeStuff):gsub("###SHOWHIDE###", showJoin):gsub("###NICK###", nick); | |
328 end | |
329 elseif stanza.attr.type ~= nil and stanza.attr.type == "unavailable" then | |
330 | |
331 ret = html.day.presence.leave:gsub("###TIME_STUFF###", timeStuff):gsub("###SHOWHIDE###", showJoin):gsub("###NICK###", nick); | |
332 end | |
333 return ret; | |
334 end | |
335 | |
336 local function parseMessageStanza(stanza, timeStuff, nick) | |
337 local body, title, ret = nil, nil, ""; | |
338 | |
339 for _,tag in ipairs(stanza) do | |
340 if tag.tag == "body" then | |
341 body = tag[1]; | |
342 if nick ~= nil then | |
343 break; | |
344 end | |
345 elseif tag.tag == "nick" and nick == nil then | |
346 nick = htmlEscape(tag[1]); | |
347 if body ~= nil or title ~= nil then | |
348 break; | |
349 end | |
350 elseif tag.tag == "subject" then | |
351 title = tag[1]; | |
352 if nick ~= nil then | |
353 break; | |
354 end | |
355 end | |
356 end | |
357 if nick ~= nil and body ~= nil then | |
358 body = htmlEscape(body); | |
359 local me = body:find("^/me"); | |
360 local template = ""; | |
361 if not me then | |
362 template = html.day.message; | |
363 else | |
364 template = html.day.message_me; | |
365 body = body:gsub("^/me ", ""); | |
366 end | |
367 ret = template:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###MSG###", body); | |
368 elseif nick ~= nil and title ~= nil then | |
369 title = htmlEscape(title); | |
370 ret = html.day.titleChange:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###TITLE###", title); | |
371 end | |
372 return ret; | |
373 end | |
374 | |
375 local function incrementDay(bare_day) | |
376 local year, month, day = bare_day:match("^(%d%d)(%d%d)(%d%d)"); | |
377 local leapyear = false; | |
378 module:log("debug", tostring(day).."/"..tostring(month).."/"..tostring(year)) | |
379 | |
380 day = tonumber(day); | |
381 month = tonumber(month); | |
382 year = tonumber(year); | |
383 | |
384 if year%4 == 0 and year%100 == 0 then | |
385 if year%400 == 0 then | |
386 leapyear = true; | |
387 else | |
388 leapyear = false; -- turn of the century but not a leapyear | |
389 end | |
390 elseif year%4 == 0 then | |
391 leapyear = true; | |
392 end | |
393 | |
394 if (month == 2 and leapyear and day + 1 > 29) or | |
395 (month == 2 and not leapyear and day + 1 > 28) or | |
396 (month < 8 and month%2 == 1 and day + 1 > 31) or | |
397 (month < 8 and month%2 == 0 and day + 1 > 30) or | |
398 (month >= 8 and month%2 == 0 and day + 1 > 31) or | |
399 (month >= 8 and month%2 == 1 and day + 1 > 30) | |
400 then | |
401 if month + 1 > 12 then | |
402 year = year + 1; | |
403 else | |
404 month = month + 1; | |
405 end | |
406 else | |
407 day = day + 1; | |
408 end | |
409 return strformat("%.02d%.02d%.02d", year, month, day); | |
410 end | |
411 | |
412 local function findNextDay(bareRoomJid, bare_day) | |
413 local node, host, resource = splitJid(bareRoomJid); | |
414 local day = incrementDay(bare_day); | |
415 local max_trys = 7; | |
416 | |
417 module:log("debug", day); | |
418 while(not checkDatastorePathExists(node, host, day, false)) do | |
419 max_trys = max_trys - 1; | |
420 if max_trys == 0 then | |
421 break; | |
422 end | |
423 day = incrementDay(day); | |
424 end | |
425 if max_trys == 0 then | |
426 return nil; | |
427 else | |
428 return day; | |
429 end | |
430 end | |
431 | |
432 local function decrementDay(bare_day) | |
433 local year, month, day = bare_day:match("^(%d%d)(%d%d)(%d%d)"); | |
434 module:log("debug", tostring(day).."/"..tostring(month).."/"..tostring(year)) | |
435 day = tonumber(day); | |
436 month = tonumber(month); | |
437 year = tonumber(year); | |
438 | |
439 if day - 1 == 0 then | |
440 if month - 1 == 0 then | |
441 year = year - 1; | |
442 else | |
443 month = month - 1; | |
444 end | |
445 else | |
446 day = day - 1; | |
447 end | |
448 return strformat("%.02d%.02d%.02d", year, month, day); | |
449 end | |
450 | |
451 local function findPreviousDay(bareRoomJid, bare_day) | |
452 local node, host, resource = splitJid(bareRoomJid); | |
453 local day = decrementDay(bare_day); | |
454 local max_trys = 7; | |
455 module:log("debug", day); | |
456 while(not checkDatastorePathExists(node, host, day, false)) do | |
457 max_trys = max_trys - 1; | |
458 if max_trys == 0 then | |
459 break; | |
460 end | |
461 day = decrementDay(day); | |
462 end | |
463 if max_trys == 0 then | |
464 return nil; | |
465 else | |
466 return day; | |
467 end | |
468 end | |
469 | |
470 local function parseDay(bareRoomJid, roomSubject, bare_day) | |
471 local ret = ""; | |
472 local year; | |
473 local month; | |
474 local day; | |
475 local tmp; | |
476 local node, host, resource = splitJid(bareRoomJid); | |
477 local year, month, day = bare_day:match("^(%d%d)(%d%d)(%d%d)"); | |
478 local previousDay = findPreviousDay(bareRoomJid, bare_day); | |
479 local nextDay = findNextDay(bareRoomJid, bare_day); | |
480 | |
481 if bare_day ~= nil then | |
482 local data = data_load(node, host, datastore .. "/" .. bare_day); | |
483 if data ~= nil then | |
484 for i=1, #data, 1 do | |
485 local stanza = lom.parse(data[i]); | |
486 if stanza ~= nil and stanza.attr ~= nil and stanza.attr.time ~= nil then | |
487 local timeStuff = html.day.time:gsub("###TIME###", stanza.attr.time); | |
488 if stanza[1] ~= nil then | |
489 local nick; | |
490 local tmp; | |
491 | |
492 -- grep nick from "from" resource | |
493 if stanza[1].attr.from ~= nil then -- presence and messages | |
494 nick = htmlEscape(stanza[1].attr.from:match("/(.+)$")); | |
495 elseif stanza[1].attr.to ~= nil then -- iq | |
496 nick = htmlEscape(stanza[1].attr.to:match("/(.+)$")); | |
497 end | |
498 | |
499 if stanza[1].tag == "presence" and nick ~= nil then | |
500 tmp = parsePresenceStanza(stanza[1], timeStuff, nick); | |
501 elseif stanza[1].tag == "message" then | |
502 tmp = parseMessageStanza(stanza[1], timeStuff, nick); | |
503 elseif stanza[1].tag == "iq" then | |
504 tmp = parseIqStanza(stanza[1], timeStuff, nick); | |
505 else | |
506 module:log("info", "unknown stanza subtag in log found. room: %s; day: %s", bareRoomJid, year .. "/" .. month .. "/" .. day); | |
507 end | |
508 if tmp ~= nil then | |
509 ret = ret .. tmp | |
510 tmp = nil; | |
511 end | |
512 end | |
513 end | |
514 end | |
515 end | |
516 if ret ~= "" then | |
517 if nextDay then | |
518 nextDay = html.day.day_link:gsub("###DAY###", nextDay):gsub("###TEXT###", "next day >>") | |
519 end | |
520 if previousDay then | |
521 previousDay = html.day.day_link:gsub("###DAY###", previousDay):gsub("###TEXT###", "<< previous day"); | |
522 end | |
523 tmp = html.day.body:gsub("###DAY_STUFF###", ret):gsub("###JID###", bareRoomJid); | |
524 tmp = tmp:gsub("###YEAR###", year):gsub("###MONTH###", month):gsub("###DAY###", day); | |
525 tmp = tmp:gsub("###TITLE_STUFF###", html.day.title:gsub("###TITLE###", roomSubject)); | |
526 tmp = tmp:gsub("###STATUS_CHECKED###", config.showStatus and "checked='checked'" or ""); | |
527 tmp = tmp:gsub("###JOIN_CHECKED###", config.showJoin and "checked='checked'" or ""); | |
528 tmp = tmp:gsub("###NEXT_LINK###", nextDay or ""); | |
529 tmp = tmp:gsub("###PREVIOUS_LINK###", previousDay or ""); | |
530 | |
531 return tmp; | |
532 end | |
533 end | |
534 end | |
535 | |
536 function handle_request(method, body, request) | |
537 local node, host, day = splitUrl(request.url.path); | |
538 | |
539 if node ~= nil and host ~= nil then | |
540 local bare = node .. "@" .. host; | |
541 if prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil then | |
542 if prosody.hosts[host].muc.rooms[bare] ~= nil then | |
543 local room = prosody.hosts[host].muc.rooms[bare]; | |
544 if day == nil then | |
545 return createDoc(generateDayListSiteContentByRoom(bare)); | |
546 else | |
547 local subject = "" | |
548 if room._data ~= nil and room._data.subject ~= nil then | |
549 subject = room._data.subject; | |
550 end | |
551 return createDoc(parseDay(bare, subject, day)); | |
552 end | |
553 else | |
554 return createDoc(generateRoomListSiteContent(host)); | |
555 end | |
556 else | |
557 return createDoc(generateComponentListSiteContent()); | |
558 end | |
559 elseif host ~= nil then | |
560 return createDoc(generateRoomListSiteContent(host)); | |
561 else | |
562 return createDoc(generateComponentListSiteContent()); | |
563 end | |
564 return; | |
565 end | |
566 | |
567 function module.load() | |
568 config = config_get("*", "core", "muc_log_http") or {}; | |
569 if config.showStatus == nil then | |
570 config.showStatus = true; | |
571 end | |
572 if config.showJoin == nil then | |
573 config.showJoin = true; | |
574 end | |
575 httpserver.new_from_config({ config.http_port or true }, handle_request, { base = "muc_log" }); | |
576 | |
577 for jid, host in pairs(prosody.hosts) do | |
578 if host.muc then | |
579 local enabledModules = config_get(jid, "core", "modules_enabled"); | |
580 if enabledModules then | |
581 for _,mod in ipairs(enabledModules) do | |
582 if(mod == "muc_log") then | |
583 module:log("debug", "component: %s", tostring(jid)); | |
584 muc_hosts[jid] = true; | |
585 break; | |
586 end | |
587 end | |
588 end | |
589 end | |
590 end | |
591 end | |
592 | |
593 function module.unload() | |
594 muc_hosts = nil; | |
595 end | |
596 | |
597 module:add_event_hook("component-activated", function(component, config) | |
598 if config.core and config.core.modules_enabled then | |
599 for _,mod in ipairs(config.core.modules_enabled) do | |
600 if(mod == "muc_log") then | |
601 module:log("debug", "component: %s", tostring(component)); | |
602 muc_hosts[component] = true; | |
603 break; | |
604 end | |
605 end | |
606 end | |
607 end); |