Software / code / prosody-modules
Comparison
mod_muc_log/mod_muc_log.lua @ 88:d8cdbebb58f2
mod_muc_log: can handle now more components and should be used as global module! HTTP Path changed to http://...../muc_log/<component>/<room>/
| author | Thilo Cestonaro <thilo@cestona.ro> |
|---|---|
| date | Mon, 09 Nov 2009 23:50:37 +0100 |
| parent | 87:0e639d081ba7 |
| child | 89:24c734c09982 |
comparison
equal
deleted
inserted
replaced
| 87:0e639d081ba7 | 88:d8cdbebb58f2 |
|---|---|
| 10 local httpserver = require "net.httpserver"; | 10 local httpserver = require "net.httpserver"; |
| 11 local serialize = require "util.serialization".serialize; | 11 local serialize = require "util.serialization".serialize; |
| 12 local datamanager = require "util.datamanager"; | 12 local datamanager = require "util.datamanager"; |
| 13 local data_load, data_store, data_getpath = datamanager.load, datamanager.store, datamanager.getpath; | 13 local data_load, data_store, data_getpath = datamanager.load, datamanager.store, datamanager.getpath; |
| 14 local datastore = "muc_log"; | 14 local datastore = "muc_log"; |
| 15 local muc_host = module:get_host(); | 15 local muc_hosts = {}; |
| 16 local config = {}; | 16 local config = nil; |
| 17 | 17 |
| 18 | 18 |
| 19 --[[ LuaFileSystem | 19 --[[ LuaFileSystem |
| 20 * URL: http://www.keplerproject.org/luafilesystem/index.html | 20 * URL: http://www.keplerproject.org/luafilesystem/index.html |
| 21 * Install: luarocks install luafilesystem | 21 * Install: luarocks install luafilesystem |
| 59 <body> | 59 <body> |
| 60 ###BODY_STUFF### | 60 ###BODY_STUFF### |
| 61 </body> | 61 </body> |
| 62 </html>]]; | 62 </html>]]; |
| 63 | 63 |
| 64 html.hosts = {}; | 64 html.components = {}; |
| 65 html.hosts.bit = [[<a href="/muc_log/###JID###">###JID###</a><br />]] | 65 html.components.bit = [[<a href="/muc_log/###COMPONENT###/">###COMPONENT###</a><br />]] |
| 66 html.hosts.body = [[<h2>Rooms hosted on this server:</h2><hr /><p> | 66 html.components.body = [[<h2>MUC hosts available on this server:</h2><hr /><p> |
| 67 ###HOSTS_STUFF### | 67 ###COMPONENTS_STUFF### |
| 68 </p><hr />]]; | 68 </p><hr />]]; |
| 69 | 69 |
| 70 html.rooms = {}; | |
| 71 html.rooms.bit = [[<a href="/muc_log/###COMPONENT###/###ROOM###">###ROOM###</a><br />]] | |
| 72 html.rooms.body = [[<h2>Rooms hosted on MUC host: ###COMPONENT###</h2><hr /><p> | |
| 73 ###ROOMS_STUFF### | |
| 74 </p><hr />]]; | |
| 75 | |
| 70 html.days = {}; | 76 html.days = {}; |
| 71 html.days.bit = [[<a href="/muc_log/###JID###/?year=###YEAR###&month=###MONTH###&day=###DAY###">20###YEAR###/###MONTH###/###DAY###</a><br />]]; | 77 html.days.bit = [[<a href="/muc_log/###COMPONENT###/###ROOM###/?year=###YEAR###&month=###MONTH###&day=###DAY###">20###YEAR###/###MONTH###/###DAY###</a><br />]]; |
| 72 html.days.body = [[<h2>available logged days of room: ###JID###</h2><hr /><p> | 78 html.days.body = [[<h2>available logged days of room: ###JID###</h2><hr /><p> |
| 73 ###DAYS_STUFF### | 79 ###DAYS_STUFF### |
| 74 </p><hr />]]; | 80 </p><hr />]]; |
| 75 | 81 |
| 76 html.day = {}; | 82 html.day = {}; |
| 138 (stanza.name == "message" and tostring(stanza.attr.type) == "groupchat") | 144 (stanza.name == "message" and tostring(stanza.attr.type) == "groupchat") |
| 139 then | 145 then |
| 140 local node, host, resource = splitJid(stanza.attr.to); | 146 local node, host, resource = splitJid(stanza.attr.to); |
| 141 if node ~= nil and host ~= nil then | 147 if node ~= nil and host ~= nil then |
| 142 local bare = node .. "@" .. host; | 148 local bare = node .. "@" .. host; |
| 143 if host == muc_host and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then | 149 if muc_hosts[host] and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then |
| 144 local room = prosody.hosts[host].muc.rooms[bare] | 150 local room = prosody.hosts[host].muc.rooms[bare] |
| 145 local today = os.date("%y%m%d"); | 151 local today = os.date("%y%m%d"); |
| 146 local now = os.date("%X") | 152 local now = os.date("%X") |
| 147 local mucTo = nil | 153 local mucTo = nil |
| 148 local mucFrom = nil; | 154 local mucFrom = nil; |
| 244 return ret; | 250 return ret; |
| 245 end | 251 end |
| 246 | 252 |
| 247 function grepRoomJid(url) | 253 function grepRoomJid(url) |
| 248 local tmp = url:sub(string.len("/muc_log/") + 1); | 254 local tmp = url:sub(string.len("/muc_log/") + 1); |
| 249 local node = nil; | 255 local room = nil; |
| 250 local host = nil; | 256 local component = nil; |
| 251 local at = nil; | 257 local at = nil; |
| 252 local slash = nil; | 258 local slash = nil; |
| 253 | 259 local slash2 = nil; |
| 254 at = tmp:find("@"); | 260 |
| 255 slash = tmp:find("/"); | 261 slash = tmp:find("/"); |
| 256 if slash ~= nil then | 262 if slash ~= nil then |
| 257 slash = slash - 1; | 263 component = tmp:sub(1, slash - 1); |
| 258 end | 264 if tmp:len() > slash then |
| 259 | 265 room = tmp:sub(slash + 1); |
| 260 if at ~= nil then | 266 slash = room:find("/"); |
| 261 node = tmp:sub(1, at - 1); | 267 if slash then |
| 262 host = tmp:sub(at + 1, slash); | 268 room = room:sub(1, slash - 1); |
| 263 end | 269 end |
| 264 return node, host; | 270 module:log("debug", "", room); |
| 265 end | 271 end |
| 266 | 272 end |
| 267 local function generateRoomListSiteContent() | 273 |
| 274 module:log("debug", "component: %s; room: %s", tostring(component), tostring(room)); | |
| 275 return room, component; | |
| 276 end | |
| 277 | |
| 278 local function generateComponentListSiteContent() | |
| 279 local components = ""; | |
| 280 for component,muc_host in pairs(muc_hosts) do | |
| 281 components = components .. html.components.bit:gsub("###COMPONENT###", component); | |
| 282 end | |
| 283 | |
| 284 return html.components.body:gsub("###COMPONENTS_STUFF###", components); | |
| 285 end | |
| 286 | |
| 287 local function generateRoomListSiteContent(component) | |
| 268 local rooms = ""; | 288 local rooms = ""; |
| 269 for host, config in pairs(prosody.hosts) do | 289 for host, config in pairs(prosody.hosts) do |
| 270 if host == muc_host and prosody.hosts[host].muc ~= nil then | 290 if host == component and prosody.hosts[host].muc ~= nil then |
| 271 for jid, room in pairs(prosody.hosts[host].muc.rooms) do | 291 for jid, room in pairs(prosody.hosts[host].muc.rooms) do |
| 272 if not room._data.hidden then | 292 local node = splitJid(jid); |
| 273 rooms = rooms .. html.hosts.bit:gsub("###JID###", jid); | 293 if not room._data.hidden and node then |
| 274 end | 294 rooms = rooms .. html.rooms.bit:gsub("###ROOM###", node):gsub("###COMPONENT###", host); |
| 275 end | 295 end |
| 276 end | 296 end |
| 277 end | 297 end |
| 278 | 298 end |
| 279 return html.hosts.body:gsub("###HOSTS_STUFF###", rooms); | 299 |
| 300 return html.rooms.body:gsub("###ROOMS_STUFF###", rooms):gsub("###COMPONENT###", component); | |
| 280 end | 301 end |
| 281 | 302 |
| 282 local function generateDayListSiteContentByRoom(bareRoomJid) | 303 local function generateDayListSiteContentByRoom(bareRoomJid) |
| 283 local days = ""; | 304 local days = ""; |
| 284 local tmp; | 305 local tmp; |
| 287 local room = nil; | 308 local room = nil; |
| 288 local attributes = nil; | 309 local attributes = nil; |
| 289 | 310 |
| 290 path = path:gsub("/[^/]*$", ""); | 311 path = path:gsub("/[^/]*$", ""); |
| 291 attributes = lfs.attributes(path); | 312 attributes = lfs.attributes(path); |
| 292 if host == muc_host and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bareRoomJid] ~= nil then | 313 if muc_hosts[host] and prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bareRoomJid] ~= nil then |
| 293 room = prosody.hosts[host].muc.rooms[bareRoomJid]; | 314 room = prosody.hosts[host].muc.rooms[bareRoomJid]; |
| 294 if room._data.hidden then | 315 if room._data.hidden then |
| 295 room = nil | 316 room = nil |
| 296 end | 317 end |
| 297 end | 318 end |
| 300 local year, month, day = file:match("^(%d%d)(%d%d)(%d%d)"); | 321 local year, month, day = file:match("^(%d%d)(%d%d)(%d%d)"); |
| 301 if year ~= nil and month ~= nil and day ~= nil and | 322 if year ~= nil and month ~= nil and day ~= nil and |
| 302 year ~= "" and month ~= "" and day ~= "" | 323 year ~= "" and month ~= "" and day ~= "" |
| 303 then | 324 then |
| 304 tmp = html.days.bit; | 325 tmp = html.days.bit; |
| 305 tmp = tmp:gsub("###JID###", bareRoomJid); | 326 tmp = tmp:gsub("###ROOM###", node):gsub("###COMPONENT###", host); |
| 306 tmp = tmp:gsub("###YEAR###", year):gsub("###MONTH###", month):gsub("###DAY###", day); | 327 tmp = tmp:gsub("###YEAR###", year):gsub("###MONTH###", month):gsub("###DAY###", day); |
| 307 days = tmp .. days; | 328 days = tmp .. days; |
| 308 end | 329 end |
| 309 end | 330 end |
| 310 end | 331 end |
| 311 if days ~= "" then | 332 if days ~= "" then |
| 312 tmp = html.days.body:gsub("###DAYS_STUFF###", days); | 333 tmp = html.days.body:gsub("###DAYS_STUFF###", days); |
| 313 return tmp:gsub("###JID###", bareRoomJid); | 334 return tmp:gsub("###JID###", bareRoomJid); |
| 314 else | 335 else |
| 315 return generateRoomListSiteContent(); -- fallback | 336 return generateRoomListSiteContent(host); -- fallback |
| 316 end | 337 end |
| 317 end | 338 end |
| 318 | 339 |
| 319 local function parseIqStanza(stanza, timeStuff, nick) | 340 local function parseIqStanza(stanza, timeStuff, nick) |
| 320 local text = nil; | 341 local text = nil; |
| 350 end | 371 end |
| 351 | 372 |
| 352 local function parsePresenceStanza(stanza, timeStuff, nick) | 373 local function parsePresenceStanza(stanza, timeStuff, nick) |
| 353 local ret = ""; | 374 local ret = ""; |
| 354 local showJoin = "block" | 375 local showJoin = "block" |
| 355 if not config.showJoin then | 376 |
| 377 if config and not config.showJoin then | |
| 356 showJoin = "none"; | 378 showJoin = "none"; |
| 357 end | 379 end |
| 358 | 380 |
| 359 if stanza.attr.type == nil then | 381 if stanza.attr.type == nil then |
| 360 local showStatus = "block" | 382 local showStatus = "block" |
| 361 if not config.showStatus then | 383 if config and not config.showStatus then |
| 362 showStatus = "none"; | 384 showStatus = "none"; |
| 363 end | 385 end |
| 364 local show, status = nil, ""; | 386 local show, status = nil, ""; |
| 365 local alreadyJoined = false; | 387 local alreadyJoined = false; |
| 366 for _, tag in ipairs(stanza) do | 388 for _, tag in ipairs(stanza) do |
| 480 | 502 |
| 481 function handle_request(method, body, request) | 503 function handle_request(method, body, request) |
| 482 local query = splitQuery(request.url.query); | 504 local query = splitQuery(request.url.query); |
| 483 local node, host = grepRoomJid(request.url.path); | 505 local node, host = grepRoomJid(request.url.path); |
| 484 | 506 |
| 485 if node ~= nil and host ~= nil then | 507 if node ~= nil and host ~= nil then |
| 486 local bare = node .. "@" .. host; | 508 local bare = node .. "@" .. host; |
| 487 if prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then | 509 if prosody.hosts[host] ~= nil and prosody.hosts[host].muc ~= nil and prosody.hosts[host].muc.rooms[bare] ~= nil then |
| 488 local room = prosody.hosts[host].muc.rooms[bare]; | 510 local room = prosody.hosts[host].muc.rooms[bare]; |
| 489 if request.url.query == nil then | 511 if request.url.query == nil then |
| 490 return createDoc(generateDayListSiteContentByRoom(bare)); | 512 return createDoc(generateDayListSiteContentByRoom(bare)); |
| 493 if room._data ~= nil and room._data.subject ~= nil then | 515 if room._data ~= nil and room._data.subject ~= nil then |
| 494 subject = room._data.subject; | 516 subject = room._data.subject; |
| 495 end | 517 end |
| 496 return createDoc(parseDay(bare, subject, query)); | 518 return createDoc(parseDay(bare, subject, query)); |
| 497 end | 519 end |
| 498 else | 520 end |
| 499 return createDoc(generateRoomListSiteContent()); | 521 elseif host ~= nil then |
| 500 end | 522 return createDoc(generateRoomListSiteContent(host)); |
| 501 else | 523 else |
| 502 return createDoc(generateRoomListSiteContent()); | 524 module:log("debug", "build component list site content") |
| 525 return createDoc(generateComponentListSiteContent()); | |
| 503 end | 526 end |
| 504 return; | 527 return; |
| 505 end | 528 end |
| 506 | 529 |
| 507 config = config_get(module:get_host(), "core", "muc_log"); | 530 function module.load() |
| 508 config.showStatus = config.showStatus or true; | 531 config = config_get("*", "core", "muc_log") or {}; |
| 509 config.showJoin = config.showJoin or true; | 532 config.showStatus = config.showStatus or true; |
| 510 | 533 config.showJoin = config.showJoin or true; |
| 511 httpserver.new_from_config({ config.http_port or true }, handle_request, { base = "muc_log" }); | 534 httpserver.new_from_config({ config.http_port or true }, handle_request, { base = "muc_log" }); |
| 535 | |
| 536 for jid, host in pairs(prosody.hosts) do | |
| 537 if host.muc then | |
| 538 local logging = config_get(jid, "core", "logging"); | |
| 539 if logging then | |
| 540 module:log("debug", "Component enabled: %s", jid); | |
| 541 muc_hosts[jid] = true; | |
| 542 end | |
| 543 end | |
| 544 end | |
| 545 end | |
| 546 | |
| 547 function module.unload() | |
| 548 muc_hosts = nil; | |
| 549 end | |
| 550 | |
| 551 module:add_event_hook("component-activated", function(component, config) | |
| 552 if config.core.logging == true then | |
| 553 module:log("debug", "Component enabled: %s", component); | |
| 554 muc_hosts[component] = true; | |
| 555 end | |
| 556 end); | |
| 512 | 557 |
| 513 module:hook("message/bare", logIfNeeded, 500); | 558 module:hook("message/bare", logIfNeeded, 500); |
| 514 module:hook("pre-message/bare", logIfNeeded, 500); | 559 module:hook("pre-message/bare", logIfNeeded, 500); |
| 515 module:hook("iq/bare", logIfNeeded, 500); | 560 module:hook("iq/bare", logIfNeeded, 500); |
| 516 module:hook("pre-iq/bare", logIfNeeded, 500); | 561 module:hook("pre-iq/bare", logIfNeeded, 500); |