Software /
code /
prosody-modules
Comparison
mod_muc_log/mod_muc_log.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 |
parent | 90:d6521ebea967 |
child | 103:0491aa849c91 |
comparison
equal
deleted
inserted
replaced
93:611d16867410 | 94:941fd7d8b9b2 |
---|---|
2 -- | 2 -- |
3 -- This project is MIT/X11 licensed. Please see the | 3 -- This project is MIT/X11 licensed. Please see the |
4 -- COPYING file in the source package for more information. | 4 -- COPYING file in the source package for more information. |
5 -- | 5 -- |
6 local prosody = prosody; | 6 local prosody = prosody; |
7 local tabSort = table.sort; | 7 local tostring = _G.tostring; |
8 local splitJid = require "util.jid".split; | 8 local splitJid = require "util.jid".split; |
9 local bareJid = require "util.jid".bare; | |
10 local config_get = require "core.configmanager".get; | 9 local config_get = require "core.configmanager".get; |
11 local httpserver = require "net.httpserver"; | |
12 local serialize = require "util.serialization".serialize; | |
13 local datamanager = require "util.datamanager"; | 10 local datamanager = require "util.datamanager"; |
14 local data_load, data_store, data_getpath = datamanager.load, datamanager.store, datamanager.getpath; | 11 local data_load, data_store, data_getpath = datamanager.load, datamanager.store, datamanager.getpath; |
15 local datastore = "muc_log"; | 12 local datastore = "muc_log"; |
16 local muc_hosts = {}; | 13 -- local mod_host = module:get_host(); |
17 local config = nil; | 14 local config = nil; |
18 | |
19 | 15 |
20 --[[ LuaFileSystem | 16 --[[ LuaFileSystem |
21 * URL: http://www.keplerproject.org/luafilesystem/index.html | 17 * URL: http://www.keplerproject.org/luafilesystem/index.html |
22 * Install: luarocks install luafilesystem | 18 * Install: luarocks install luafilesystem |
23 * ]] | 19 * ]] |
24 local lfs = require "lfs"; | 20 local lfs = require "lfs"; |
25 | |
26 local lom = require "lxp.lom"; | |
27 | |
28 | |
29 --[[ | 21 --[[ |
30 * Default templates for the html output. | 22 local function checkDatastorePathExists(node, host, today, create) |
31 ]]-- | 23 create = create or false; |
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 //--> | |
59 </style> | |
60 <body> | |
61 ###BODY_STUFF### | |
62 </body> | |
63 </html>]]; | |
64 | |
65 html.components = {}; | |
66 html.components.bit = [[<a href="###COMPONENT###/">###COMPONENT###</a><br />]] | |
67 html.components.body = [[<h2>MUC hosts available on this server:</h2><hr /><p> | |
68 ###COMPONENTS_STUFF### | |
69 </p><hr />]]; | |
70 | |
71 html.rooms = {}; | |
72 html.rooms.bit = [[<a href="###ROOM###/">###ROOM###</a><br />]] | |
73 html.rooms.body = [[<h2>Rooms hosted on MUC host: ###COMPONENT###</h2><hr /><p> | |
74 ###ROOMS_STUFF### | |
75 </p><hr />]]; | |
76 | |
77 html.days = {}; | |
78 html.days.bit = [[<a href="###BARE_DAY###/">20###YEAR###/###MONTH###/###DAY###</a><br />]]; | |
79 html.days.body = [[<h2>available logged days of room: ###JID###</h2><hr /><p> | |
80 ###DAYS_STUFF### | |
81 </p><hr />]]; | |
82 | |
83 html.day = {}; | |
84 html.day.title = [[Subject: <font class="muc_title">###TITLE###</font>]]; | |
85 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 | |
86 html.day.presence = {}; | |
87 html.day.presence.join = [[<div name="joinLeave" style="display: ###SHOWHIDE###;">###TIME_STUFF###<font class="muc_join"> *** ###NICK### joins the room</font><br /></div>]]; | |
88 html.day.presence.leave = [[<div name="joinLeave" style="display: ###SHOWHIDE###;">###TIME_STUFF###<font class="muc_leave"> *** ###NICK### leaves the room</font><br /></div>]]; | |
89 html.day.presence.statusText = [[ and his status message is "###STATUS###"]]; | |
90 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>]]; | |
91 html.day.message = [[###TIME_STUFF###<font class="muc_msg_nick"><###NICK###></font> ###MSG###<br />]]; | |
92 html.day.titleChange = [[###TIME_STUFF###<font class="muc_titleChange"> *** ###NICK### changed the title to "###TITLE###"</font><br />]]; | |
93 html.day.reason = [[, the reason was "###REASON###"]] | |
94 html.day.kick = [[###TIME_STUFF###<font class="muc_kick"> *** ###VICTIM### got kicked###REASON_STUFF###</font><br />]]; | |
95 html.day.bann = [[###TIME_STUFF###<font class="muc_bann"> *** ###VICTIM### got banned###REASON_STUFF###</font><br />]]; | |
96 html.day.body = [[<h2>room ###JID### logging of 20###YEAR###/###MONTH###/###DAY###</h2> | |
97 <p>###TITLE_STUFF###</p> | |
98 <input type="checkbox" onclick="showHide('joinLeave')" ###JOIN_CHECKED###/>show/hide joins and Leaves</button> | |
99 <input type="checkbox" onclick="showHide('status')" ###STATUS_CHECKED###/>show/hide status changes</button> | |
100 <hr /><div id="main" style="overflow: scroll;"> | |
101 ###DAY_STUFF### | |
102 </div><hr /> | |
103 <script><!-- | |
104 var ele = document.getElementById("main"); | |
105 ele.style.height = window.innerHeight - ele.offsetTop - 25; | |
106 --></script>]]; | |
107 | |
108 html.help = [[ | |
109 MUC logging is not configured correctly.<br /> | |
110 Here is a example config:<br /> | |
111 Component "rooms.example.com" "muc"<br /> | |
112 modules_enabled = {<br /> | |
113 "muc_log";<br /> | |
114 }<br /> | |
115 muc_log = {<br /> | |
116 folder = "/opt/local/var/log/prosody/rooms";<br /> | |
117 http_port = "/opt/local/var/log/prosody/rooms";<br /> | |
118 }<br /> | |
119 ]]; | |
120 | |
121 local function ensureDatastorePathExists(node, host, today) | |
122 local path = data_getpath(node, host, datastore, "dat", true); | 24 local path = data_getpath(node, host, datastore, "dat", true); |
123 path = path:gsub("/[^/]*$", ""); | 25 path = path:gsub("/[^/]*$", ""); |
124 | 26 |
125 -- check existance | 27 -- check existance |
126 local attributes, err = lfs.attributes(path); | 28 local attributes, err = lfs.attributes(path); |
129 return false; | 31 return false; |
130 end | 32 end |
131 | 33 |
132 attributes, err = lfs.attributes(path .. "/" .. today); | 34 attributes, err = lfs.attributes(path .. "/" .. today); |
133 if attributes == nil then | 35 if attributes == nil then |
134 return lfs.mkdir(path .. "/" .. today); | 36 if create then |
37 return lfs.mkdir(path .. "/" .. today); | |
38 else | |
39 return false; | |
40 end | |
135 elseif attributes.mode == "directory" then | 41 elseif attributes.mode == "directory" then |
136 return true; | 42 return true; |
137 end | 43 end |
138 return false; | 44 return false; |
139 end | 45 end |
146 (stanza.name == "message" and tostring(stanza.attr.type) == "groupchat") | 52 (stanza.name == "message" and tostring(stanza.attr.type) == "groupchat") |
147 then | 53 then |
148 local node, host, resource = splitJid(stanza.attr.to); | 54 local node, host, resource = splitJid(stanza.attr.to); |
149 if node ~= nil and host ~= nil then | 55 if node ~= nil and host ~= nil then |
150 local bare = node .. "@" .. host; | 56 local bare = node .. "@" .. host; |
151 if muc_hosts[host] and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then | 57 if host == mod_host and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then |
152 local room = prosody.hosts[host].muc.rooms[bare] | 58 local room = prosody.hosts[host].muc.rooms[bare] |
153 local today = os.date("%y%m%d"); | 59 local today = os.date("%y%m%d"); |
154 local now = os.date("%X") | 60 local now = os.date("%X") |
155 local mucTo = nil | 61 local mucTo = nil |
156 local mucFrom = nil; | 62 local mucFrom = nil; |
186 break; | 92 break; |
187 end | 93 end |
188 end | 94 end |
189 end | 95 end |
190 | 96 |
191 if (mucFrom ~= nil or mucTo ~= nil) and ensureDatastorePathExists(node, host, today) then | 97 if (mucFrom ~= nil or mucTo ~= nil) and checkDatastorePathExists(node, host, today, true) then |
192 local data = data_load(node, host, datastore .. "/" .. today); | 98 local data = data_load(node, host, datastore .. "/" .. today); |
193 local realFrom = stanza.attr.from; | 99 local realFrom = stanza.attr.from; |
194 local realTo = stanza.attr.to; | 100 local realTo = stanza.attr.to; |
195 | 101 |
196 if data == nil then | 102 if data == nil then |
217 data_store(node, host, datastore .. "/" .. today, data); | 123 data_store(node, host, datastore .. "/" .. today, data); |
218 end | 124 end |
219 end | 125 end |
220 end | 126 end |
221 end | 127 end |
222 return; | |
223 end | 128 end |
224 | 129 |
225 function createDoc(body) | 130 module:hook("message/bare", logIfNeeded, 500); |
226 return html.doc:gsub("###BODY_STUFF###", body or ""); | 131 module:hook("iq/bare", logIfNeeded, 500); |
227 end | 132 module:hook("presence/full", logIfNeeded, 500); |
228 | |
229 local function htmlEscape(t) | |
230 t = t:gsub("<", "<"); | |
231 t = t:gsub(">", ">"); | |
232 t = t:gsub("(http://[%a%d@%.:/&%?=%-_#]+)", [[<a href="%1">%1</a>]]); | |
233 t = t:gsub("\n", "<br />"); | |
234 -- TODO do any html escaping stuff ... | |
235 return t; | |
236 end | |
237 | |
238 function splitUrl(url) | |
239 local tmp = url:sub(string.len("/muc_log/") + 1); | |
240 local day = nil; | |
241 local room = nil; | |
242 local component = nil; | |
243 local at = nil; | |
244 local slash = nil; | |
245 local slash2 = nil; | |
246 | |
247 slash = tmp:find("/"); | |
248 if slash then | |
249 component = tmp:sub(1, slash - 1); | |
250 if tmp:len() > slash then | |
251 room = tmp:sub(slash + 1); | |
252 slash = room:find("/"); | |
253 if slash then | |
254 tmp = room; | |
255 room = tmp:sub(1, slash - 1); | |
256 if tmp:len() > slash then | |
257 day = tmp:sub(slash + 1); | |
258 slash = day:find("/"); | |
259 if slash then | |
260 day = day:sub(1, slash - 1); | |
261 end | |
262 end | |
263 end | |
264 end | |
265 end | |
266 | |
267 return room, component, day; | |
268 end | |
269 | |
270 local function generateComponentListSiteContent() | |
271 local components = ""; | |
272 for component,muc_host in pairs(muc_hosts) do | |
273 components = components .. html.components.bit:gsub("###COMPONENT###", component); | |
274 end | |
275 | |
276 return html.components.body:gsub("###COMPONENTS_STUFF###", components); | |
277 end | |
278 | |
279 local function generateRoomListSiteContent(component) | |
280 local rooms = ""; | |
281 if prosody.hosts[component] and prosody.hosts[component].muc ~= nil then | |
282 for jid, room in pairs(prosody.hosts[component].muc.rooms) do | |
283 local node = splitJid(jid); | |
284 if not room._data.hidden and node then | |
285 rooms = rooms .. html.rooms.bit:gsub("###ROOM###", node):gsub("###COMPONENT###", component); | |
286 end | |
287 end | |
288 return html.rooms.body:gsub("###ROOMS_STUFF###", rooms):gsub("###COMPONENT###", component); | |
289 end | |
290 return generateComponentListSiteContent(); -- fallback | |
291 end | |
292 | |
293 local function generateDayListSiteContentByRoom(bareRoomJid) | |
294 local days = ""; | |
295 local arrDays = {}; | |
296 local tmp; | |
297 local node, host, resource = splitJid(bareRoomJid); | |
298 local path = data_getpath(node, host, datastore); | |
299 local room = nil; | |
300 local attributes = nil; | |
301 | |
302 path = path:gsub("/[^/]*$", ""); | |
303 attributes = lfs.attributes(path); | |
304 if muc_hosts[host] and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bareRoomJid] ~= nil then | |
305 room = prosody.hosts[host].muc.rooms[bareRoomJid]; | |
306 if room._data.hidden then | |
307 room = nil | |
308 end | |
309 end | |
310 if attributes ~= nil and room ~= nil then | |
311 for file in lfs.dir(path) do | |
312 local year, month, day = file:match("^(%d%d)(%d%d)(%d%d)"); | |
313 if year ~= nil and month ~= nil and day ~= nil and | |
314 year ~= "" and month ~= "" and day ~= "" | |
315 then | |
316 arrDays[#arrDays + 1] = {bare=file, year=year, month=month, day=day}; | |
317 end | |
318 end | |
319 tabSort(arrDays, function(a,b) | |
320 return a.bare < b.bare; | |
321 end); | |
322 for _, date in pairs(arrDays) do | |
323 tmp = html.days.bit; | |
324 tmp = tmp:gsub("###ROOM###", node):gsub("###COMPONENT###", host); | |
325 tmp = tmp:gsub("###BARE_DAY###", date.bare); | |
326 tmp = tmp:gsub("###YEAR###", date.year):gsub("###MONTH###", date.month):gsub("###DAY###", date.day); | |
327 days = tmp .. days; | |
328 end | |
329 end | |
330 | |
331 if days ~= "" then | |
332 tmp = html.days.body:gsub("###DAYS_STUFF###", days); | |
333 return tmp:gsub("###JID###", bareRoomJid); | |
334 else | |
335 return generateRoomListSiteContent(host); -- fallback | |
336 end | |
337 end | |
338 | |
339 local function parseIqStanza(stanza, timeStuff, nick) | |
340 local text = nil; | |
341 local victim = nil; | |
342 if(stanza.attr.type == "set") then | |
343 for _,tag in ipairs(stanza) do | |
344 if tag.tag == "query" then | |
345 for _,item in ipairs(tag) do | |
346 if item.tag == "item" and item.attr.nick ~= nil and tostring(item.attr.role) == 'none' then | |
347 victim = item.attr.nick; | |
348 for _,reason in ipairs(item) do | |
349 if reason.tag == "reason" then | |
350 text = reason[1]; | |
351 break; | |
352 end | |
353 end | |
354 break; | |
355 end | |
356 end | |
357 break; | |
358 end | |
359 end | |
360 if victim ~= nil then | |
361 if text ~= nil then | |
362 text = html.day.reason:gsub("###REASON###", htmlEscape(text)); | |
363 else | |
364 text = ""; | |
365 end | |
366 return html.day.kick:gsub("###TIME_STUFF###", timeStuff):gsub("###VICTIM###", victim):gsub("###REASON_STUFF###", text); | |
367 end | |
368 end | |
369 return; | |
370 end | |
371 | |
372 local function parsePresenceStanza(stanza, timeStuff, nick) | |
373 local ret = ""; | |
374 local showJoin = "block" | |
375 | |
376 if config and not config.showJoin then | |
377 showJoin = "none"; | |
378 end | |
379 | |
380 if stanza.attr.type == nil then | |
381 local showStatus = "block" | |
382 if config and not config.showStatus then | |
383 showStatus = "none"; | |
384 end | |
385 local show, status = nil, ""; | |
386 local alreadyJoined = false; | |
387 for _, tag in ipairs(stanza) do | |
388 if tag.tag == "alreadyJoined" then | |
389 alreadyJoined = true; | |
390 elseif tag.tag == "show" then | |
391 show = tag[1]; | |
392 elseif tag.tag == "status" then | |
393 status = tag[1]; | |
394 end | |
395 end | |
396 if alreadyJoined == true then | |
397 if show == nil then | |
398 show = "online"; | |
399 end | |
400 ret = html.day.presence.statusChange:gsub("###TIME_STUFF###", timeStuff); | |
401 if status ~= "" then | |
402 status = html.day.presence.statusText:gsub("###STATUS###", htmlEscape(status)); | |
403 end | |
404 ret = ret:gsub("###SHOW###", show):gsub("###NICK###", nick):gsub("###SHOWHIDE###", showStatus):gsub("###STATUS_STUFF###", status); | |
405 else | |
406 ret = html.day.presence.join:gsub("###TIME_STUFF###", timeStuff):gsub("###SHOWHIDE###", showJoin):gsub("###NICK###", nick); | |
407 end | |
408 elseif stanza.attr.type ~= nil and stanza.attr.type == "unavailable" then | |
409 | |
410 ret = html.day.presence.leave:gsub("###TIME_STUFF###", timeStuff):gsub("###SHOWHIDE###", showJoin):gsub("###NICK###", nick); | |
411 end | |
412 return ret; | |
413 end | |
414 | |
415 local function parseMessageStanza(stanza, timeStuff, nick) | |
416 local body, title, ret = nil, nil, ""; | |
417 | |
418 for _,tag in ipairs(stanza) do | |
419 if tag.tag == "body" then | |
420 body = tag[1]; | |
421 if nick ~= nil then | |
422 break; | |
423 end | |
424 elseif tag.tag == "nick" and nick == nil then | |
425 nick = htmlEscape(tag[1]); | |
426 if body ~= nil or title ~= nil then | |
427 break; | |
428 end | |
429 elseif tag.tag == "subject" then | |
430 title = tag[1]; | |
431 if nick ~= nil then | |
432 break; | |
433 end | |
434 end | |
435 end | |
436 if nick ~= nil and body ~= nil then | |
437 body = htmlEscape(body); | |
438 ret = html.day.message:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###MSG###", body); | |
439 elseif nick ~= nil and title ~= nil then | |
440 title = htmlEscape(title); | |
441 ret = html.day.titleChange:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###TITLE###", title); | |
442 end | |
443 return ret; | |
444 end | |
445 | |
446 local function parseDay(bareRoomJid, roomSubject, bare_day) | |
447 local ret = ""; | |
448 local year; | |
449 local month; | |
450 local day; | |
451 local tmp; | |
452 local node, host, resource = splitJid(bareRoomJid); | |
453 local year, month, day = bare_day:match("^(%d%d)(%d%d)(%d%d)"); | |
454 | |
455 if bare_day ~= nil then | |
456 local data = data_load(node, host, datastore .. "/" .. bare_day); | |
457 if data ~= nil then | |
458 for i=1, #data, 1 do | |
459 local stanza = lom.parse(data[i]); | |
460 if stanza ~= nil and stanza.attr ~= nil and stanza.attr.time ~= nil then | |
461 local timeStuff = html.day.time:gsub("###TIME###", stanza.attr.time); | |
462 if stanza[1] ~= nil then | |
463 local nick; | |
464 local tmp; | |
465 | |
466 -- grep nick from "from" resource | |
467 if stanza[1].attr.from ~= nil then -- presence and messages | |
468 nick = htmlEscape(stanza[1].attr.from:match("/(.+)$")); | |
469 elseif stanza[1].attr.to ~= nil then -- iq | |
470 nick = htmlEscape(stanza[1].attr.to:match("/(.+)$")); | |
471 end | |
472 | |
473 if stanza[1].tag == "presence" and nick ~= nil then | |
474 tmp = parsePresenceStanza(stanza[1], timeStuff, nick); | |
475 elseif stanza[1].tag == "message" then | |
476 tmp = parseMessageStanza(stanza[1], timeStuff, nick); | |
477 elseif stanza[1].tag == "iq" then | |
478 tmp = parseIqStanza(stanza[1], timeStuff, nick); | |
479 else | |
480 module:log("info", "unknown stanza subtag in log found. room: %s; day: %s", bareRoomJid, year .. "/" .. month .. "/" .. day); | |
481 end | |
482 if tmp ~= nil then | |
483 ret = ret .. tmp | |
484 tmp = nil; | |
485 end | |
486 end | |
487 end | |
488 end | |
489 else | |
490 return generateDayListSiteContentByRoom(bareRoomJid); -- fallback | |
491 end | |
492 tmp = html.day.body:gsub("###DAY_STUFF###", ret):gsub("###JID###", bareRoomJid); | |
493 tmp = tmp:gsub("###YEAR###", year):gsub("###MONTH###", month):gsub("###DAY###", day); | |
494 tmp = tmp:gsub("###TITLE_STUFF###", html.day.title:gsub("###TITLE###", roomSubject)); | |
495 tmp = tmp:gsub("###STATUS_CHECKED###", config.showStatus and "checked='checked'" or ""); | |
496 tmp = tmp:gsub("###JOIN_CHECKED###", config.showJoin and "checked='checked'" or ""); | |
497 return tmp; | |
498 else | |
499 return generateDayListSiteContentByRoom(bareRoomJid); -- fallback | |
500 end | |
501 end | |
502 | |
503 --[[ | |
504 local function loggingMucComponents() | |
505 local n = 0; | |
506 for component,_ in pairs(muc_hosts) do | |
507 n = n + 1; | |
508 end | |
509 return n; | |
510 end | |
511 ]]-- | 133 ]]-- |
512 | 134 module:log("debug", "module mod_muc_log loaded!"); |
513 function handle_request(method, body, request) | |
514 -- local query = splitQuery(request.url.query); | |
515 local node, host, day = splitUrl(request.url.path); | |
516 --[[if host == nil and loggingMucComponents() == 1 then | |
517 for component,_ in pairs(muc_hosts) do | |
518 host = component; | |
519 break; | |
520 end | |
521 module:log("debug", "host: %s", tostring(host)); | |
522 end]]-- | |
523 | |
524 if node ~= nil and host ~= nil then | |
525 local bare = node .. "@" .. host; | |
526 if prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil then | |
527 if prosody.hosts[host].muc.rooms[bare] ~= nil then | |
528 local room = prosody.hosts[host].muc.rooms[bare]; | |
529 if day == nil then | |
530 return createDoc(generateDayListSiteContentByRoom(bare)); | |
531 else | |
532 local subject = "" | |
533 if room._data ~= nil and room._data.subject ~= nil then | |
534 subject = room._data.subject; | |
535 end | |
536 return createDoc(parseDay(bare, subject, day)); | |
537 end | |
538 else | |
539 return createDoc(generateRoomListSiteContent(host)); | |
540 end | |
541 else | |
542 return createDoc(generateComponentListSiteContent()); | |
543 end | |
544 elseif host ~= nil then | |
545 return createDoc(generateRoomListSiteContent(host)); | |
546 else | |
547 return createDoc(generateComponentListSiteContent()); | |
548 end | |
549 return; | |
550 end | |
551 | |
552 function module.load() | |
553 config = config_get("*", "core", "muc_log") or {}; | |
554 if config.showStatus == nil then | |
555 config.showStatus = true; | |
556 end | |
557 if config.showJoin == nil then | |
558 config.showJoin = true; | |
559 end | |
560 httpserver.new_from_config({ config.http_port or true }, handle_request, { base = "muc_log" }); | |
561 | |
562 for jid, host in pairs(prosody.hosts) do | |
563 if host.muc then | |
564 local logging = config_get(jid, "core", "logging"); | |
565 if logging then | |
566 module:log("debug", "component: %s", tostring(jid)); | |
567 muc_hosts[jid] = true; | |
568 end | |
569 end | |
570 end | |
571 end | |
572 | |
573 function module.unload() | |
574 muc_hosts = nil; | |
575 end | |
576 | |
577 module:add_event_hook("component-activated", function(component, config) | |
578 if config.core.logging == true then | |
579 module:log("debug", "component: %s", tostring(component)); | |
580 muc_hosts[component] = true; | |
581 end | |
582 end); | |
583 | |
584 module:hook("message/bare", logIfNeeded, 500); | |
585 module:hook("pre-message/bare", logIfNeeded, 500); | |
586 module:hook("iq/bare", logIfNeeded, 500); | |
587 module:hook("pre-iq/bare", logIfNeeded, 500); | |
588 module:hook("presence/full", logIfNeeded, 500); | |
589 module:hook("pre-presence/full", logIfNeeded, 500); |