Mercurial > prosody-modules
comparison mod_muc_log/mod_muc_log.lua @ 59:50e3d5b87119
mod_muc_log: better presence and message parsing; react on subject changes
author | Thilo Cestonaro <thilo@cestona.ro> |
---|---|
date | Tue, 20 Oct 2009 23:25:21 +0200 |
parents | cddcea7c091a |
children | 5cca708c9f11 |
comparison
equal
deleted
inserted
replaced
58:b07193056935 | 59:50e3d5b87119 |
---|---|
63 html.day = {}; | 63 html.day = {}; |
64 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 | 64 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 |
65 html.day.presence = {}; | 65 html.day.presence = {}; |
66 html.day.presence.join = [[###TIME_STUFF###<font class="muc_join"> *** ###NICK### joins the room</font><br />]]; | 66 html.day.presence.join = [[###TIME_STUFF###<font class="muc_join"> *** ###NICK### joins the room</font><br />]]; |
67 html.day.presence.leave = [[###TIME_STUFF###<font class="muc_leave"> *** ###NICK### leaves the room</font><br />]]; | 67 html.day.presence.leave = [[###TIME_STUFF###<font class="muc_leave"> *** ###NICK### leaves the room</font><br />]]; |
68 html.day.presence.statusChange = [[###TIME_STUFF###<font class="muc_statusChange"> *** ###NICK### changed his/her status to: ###STATUS###</font><br />]]; | 68 html.day.presence.statusText = [[ and his status message is "###STATUS###"]]; |
69 html.day.presence.statusChange = [[###TIME_STUFF###<font class="muc_statusChange"> *** ###NICK### shows now as "###SHOW###"###STATUS_STUFF###</font><br />]]; | |
69 html.day.message = [[###TIME_STUFF###<font class="muc_name"><###NICK###></font> ###MSG###<br />]]; | 70 html.day.message = [[###TIME_STUFF###<font class="muc_name"><###NICK###></font> ###MSG###<br />]]; |
70 html.day.titleChange = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### change title to:</font> <font class="muc_title">###MSG###</font><br />]]; | 71 html.day.titleChange = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### changed the title to</font> <font class="muc_title">"###TITLE###"</font><br />]]; |
71 html.day.kick = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### kicked ###VICTIM###</font><br />]]; | 72 html.day.kick = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### kicked ###VICTIM###</font><br />]]; |
72 html.day.bann = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### banned ###VICTIM###</font><br />]]; | 73 html.day.bann = [[###TIME_STUFF###<font class="muc_titlenick"> *** ###NICK### banned ###VICTIM###</font><br />]]; |
73 html.day.body = [[<h2>room ###JID### logging of 20###YEAR###/###MONTH###/###DAY###</h2><hr /><p> | 74 html.day.body = [[<h2>room ###JID### logging of 20###YEAR###/###MONTH###/###DAY###</h2><hr /><p> |
74 ###DAY_STUFF### | 75 ###DAY_STUFF### |
75 </p><hr />]]; | 76 </p><hr />]]; |
166 return t; | 167 return t; |
167 end | 168 end |
168 | 169 |
169 function splitQuery(query) | 170 function splitQuery(query) |
170 local ret = {}; | 171 local ret = {}; |
172 local name, value = nil, nil; | |
171 if query == nil then return ret; end | 173 if query == nil then return ret; end |
172 local last = 1; | 174 local last = 1; |
173 local idx = query:find("&", last); | 175 local idx = query:find("&", last); |
174 while idx ~= nil do | 176 while idx ~= nil do |
175 ret[#ret + 1] = query:sub(last, idx - 1); | 177 name, value = query:sub(last, idx - 1):match("^(%a+)=(%d+)$"); |
178 ret[name] = value; | |
176 last = idx + 1; | 179 last = idx + 1; |
177 idx = query:find("&", last); | 180 idx = query:find("&", last); |
178 end | 181 end |
179 ret[#ret + 1] = query:sub(last); | 182 name, value = query:sub(last):match("^(%a+)=(%d+)$"); |
183 ret[name] = value; | |
180 return ret; | 184 return ret; |
181 end | 185 end |
182 | 186 |
183 function grepRoomJid(url) | 187 function grepRoomJid(url) |
184 local tmp = url:sub(string.len("/muc_log/") + 1); | 188 local tmp = url:sub(string.len("/muc_log/") + 1); |
222 if year ~= nil and month ~= nil and day ~= nil and | 226 if year ~= nil and month ~= nil and day ~= nil and |
223 year ~= "" and month ~= "" and day ~= "" | 227 year ~= "" and month ~= "" and day ~= "" |
224 then | 228 then |
225 tmp = html.days.bit; | 229 tmp = html.days.bit; |
226 tmp = tmp:gsub("###JID###", bareRoomJid); | 230 tmp = tmp:gsub("###JID###", bareRoomJid); |
227 tmp = tmp:gsub("###YEAR###", year); | 231 tmp = tmp:gsub("###YEAR###", year):gsub("###MONTH###", month):gsub("###DAY###", day); |
228 tmp = tmp:gsub("###MONTH###", month); | |
229 tmp = tmp:gsub("###DAY###", day); | |
230 days = tmp .. days; | 232 days = tmp .. days; |
231 end | 233 end |
232 end | 234 end |
233 if days ~= "" then | 235 if days ~= "" then |
234 tmp = html.days.body:gsub("###DAYS_STUFF###", days); | 236 tmp = html.days.body:gsub("###DAYS_STUFF###", days); |
235 return tmp:gsub("###JID###", bareRoomJid); | 237 return tmp:gsub("###JID###", bareRoomJid); |
236 else | 238 else |
237 return generateRoomListSiteContent(); -- fallback | 239 return generateRoomListSiteContent(); -- fallback |
238 end | 240 end |
241 end | |
242 | |
243 local function parsePresenceStanza(stanza, timeStuff, nick) | |
244 local ret = ""; | |
245 -- module:log("debug", serialize(stanza)); | |
246 if stanza[1].attr.type == nil then | |
247 local show, status = nil, ""; | |
248 for _, tag in ipairs(stanza[1]) do | |
249 module:log("debug", serialize(tag)); | |
250 if tag.tag == "show" then | |
251 show = tag[1]; | |
252 elseif tag.tag == "status" then | |
253 status = tag[1]; | |
254 end | |
255 end | |
256 if show ~= nil then | |
257 ret = html.day.presence.statusChange:gsub("###TIME_STUFF###", timeStuff); | |
258 if status ~= "" then | |
259 status = html.day.presence.statusText:gsub("###STATUS###", status); | |
260 end | |
261 ret = ret:gsub("###SHOW###", show):gsub("###NICK###", nick):gsub("###STATUS_STUFF###", status); | |
262 else | |
263 ret = html.day.presence.join:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick); | |
264 end | |
265 elseif stanza[1].attr.type ~= nil and stanza[1].attr.type == "unavailable" then | |
266 ret = html.day.presence.leave:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick); | |
267 end | |
268 return ret; | |
269 end | |
270 | |
271 local function parseMessageStanza(stanza, timeStuff, nick) | |
272 local body, title, ret = nil, nil, ""; | |
273 | |
274 for _,tag in ipairs(stanza[1]) do | |
275 if tag.tag == "body" then | |
276 body = tag[1]; | |
277 if nick ~= nil then | |
278 break; | |
279 end | |
280 elseif tag.tag == "nick" and nick == nil then | |
281 nick = tag[1]; | |
282 if body ~= nil or title ~= nil then | |
283 break; | |
284 end | |
285 elseif tag.tag == "subject" then | |
286 title = tag[1]; | |
287 if nick ~= nil then | |
288 break; | |
289 end | |
290 end | |
291 end | |
292 if nick ~= nil and body ~= nil then | |
293 body = htmlEscape(body); | |
294 ret = html.day.message:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###MSG###", body); | |
295 elseif nick ~= nil and title ~= nil then | |
296 title = htmlEscape(title); | |
297 ret = html.day.titleChange:gsub("###TIME_STUFF###", timeStuff):gsub("###NICK###", nick):gsub("###TITLE###", title); | |
298 end | |
299 return ret; | |
239 end | 300 end |
240 | 301 |
241 local function parseDay(bareRoomJid, query) | 302 local function parseDay(bareRoomJid, query) |
242 local ret = ""; | 303 local ret = ""; |
243 local year; | 304 local year; |
244 local month; | 305 local month; |
245 local day; | 306 local day; |
246 local tmp; | 307 local tmp; |
247 | 308 |
248 for _,str in ipairs(query) do | 309 if query.year ~= nil and query.month ~= nil and query.day ~= nil then |
249 local name, value; | 310 local file = config.folder .. "/" .. query.year .. query.month .. query.day .. "_" .. bareRoomJid .. ".log"; |
250 name, value = str:match("^(%a+)=(%d+)$"); | |
251 if name == "year" then | |
252 year = value; | |
253 elseif name == "month" then | |
254 month = value; | |
255 elseif name == "day" then | |
256 day = value; | |
257 else | |
258 log("warn", "unknown query value"); | |
259 end | |
260 end | |
261 | |
262 if year ~= nil and month ~= nil and day ~= nil then | |
263 local file = config.folder .. "/" .. year .. month .. day .. "_" .. bareRoomJid .. ".log"; | |
264 local f, err = io.open(file, "r"); | 311 local f, err = io.open(file, "r"); |
265 if f ~= nil then | 312 if f ~= nil then |
266 local content = f:read("*a"); | 313 local content = f:read("*a"); |
267 local parsed = lom.parse("<xml>" .. content .. "</xml>"); | 314 local parsed = lom.parse("<xml>" .. content .. "</xml>"); |
315 f:close(); | |
268 if parsed ~= nil then | 316 if parsed ~= nil then |
269 for _,stanza in ipairs(parsed) do | 317 for _,stanza in ipairs(parsed) do |
270 if stanza.attr ~= nil and stanza.attr.time ~= nil then | 318 if stanza.attr ~= nil and stanza.attr.time ~= nil then |
271 local timeStuff = html.day.time:gsub("###TIME###", stanza.attr.time); | 319 local timeStuff = html.day.time:gsub("###TIME###", stanza.attr.time); |
272 if stanza[1] ~= nil then | 320 if stanza[1] ~= nil then |
276 if stanza[1].attr.from ~= nil then | 324 if stanza[1].attr.from ~= nil then |
277 nick = stanza[1].attr.from:match("/(.+)$"); | 325 nick = stanza[1].attr.from:match("/(.+)$"); |
278 end | 326 end |
279 | 327 |
280 if stanza[1].tag == "presence" and nick ~= nil then | 328 if stanza[1].tag == "presence" and nick ~= nil then |
281 | 329 ret = ret .. parsePresenceStanza(stanza, timeStuff, nick); |
282 if stanza[1].attr.type == nil then | |
283 tmp = html.day.presence.join:gsub("###TIME_STUFF###", timeStuff); | |
284 ret = ret .. tmp:gsub("###NICK###", nick); | |
285 elseif stanza[1].attr.type ~= nil and stanza[1].attr.type == "unavailable" then | |
286 tmp = html.day.presence.leave:gsub("###TIME_STUFF###", timeStuff); | |
287 ret = ret .. tmp:gsub("###NICK###", nick); | |
288 else | |
289 tmp = html.day.presence.leave:gsub("###TIME_STUFF###", timeStuff); | |
290 tmp = tmp:gsub("###STATUS###", stanza[1].attr.type); | |
291 ret = ret .. tmp:gsub("###NICK###", nick); | |
292 end | |
293 elseif stanza[1].tag == "message" then | 330 elseif stanza[1].tag == "message" then |
294 local body; | 331 ret = ret .. parseMessageStanza(stanza, timeStuff, nick); |
295 for _,tag in ipairs(stanza[1]) do | |
296 if tag.tag == "body" then | |
297 body = htmlEscape(tag[1]); | |
298 if nick ~= nil then | |
299 break; | |
300 end | |
301 elseif tag.tag == "nick" and nick == nil then | |
302 nick = tag[1]; | |
303 if body ~= nil then | |
304 break; | |
305 end | |
306 end | |
307 end | |
308 if nick ~= nil and body ~= nil then | |
309 tmp = html.day.message:gsub("###TIME_STUFF###", timeStuff); | |
310 tmp = tmp:gsub("###NICK###", nick); | |
311 ret = ret .. tmp:gsub("###MSG###", body); | |
312 end | |
313 else | 332 else |
314 module:log("info", "unknown stanza subtag in log found. room: %s; day: %s", bareRoomJid, year .. "/" .. month .. "/" .. day); | 333 module:log("info", "unknown stanza subtag in log found. room: %s; day: %s", bareRoomJid, query.year .. "/" .. query.month .. "/" .. query.day); |
315 end | 334 end |
316 end | 335 end |
317 end | 336 end |
318 end | 337 end |
319 else | 338 else |
320 module:log("warn", "could not parse room log. room: %s; day: %s", bareRoomJid, year .. "/" .. month .. "/" .. day); | 339 module:log("warn", "could not parse room log. room: %s; day: %s", bareRoomJid, query.year .. "/" .. query.month .. "/" .. query.day); |
321 end | 340 end |
322 f:close(); | |
323 else | 341 else |
324 ret = err; | 342 ret = err; |
325 end | 343 end |
326 tmp = html.day.body:gsub("###DAY_STUFF###", ret); | 344 tmp = html.day.body:gsub("###DAY_STUFF###", ret):gsub("###JID###", bareRoomJid); |
327 tmp = tmp:gsub("###JID###", bareRoomJid); | 345 tmp = tmp:gsub("###YEAR###", query.year):gsub("###MONTH###", query.month):gsub("###DAY###", query.day); |
328 tmp = tmp:gsub("###YEAR###", year); | |
329 tmp = tmp:gsub("###MONTH###", month); | |
330 tmp = tmp:gsub("###DAY###", day); | |
331 return tmp; | 346 return tmp; |
332 else | 347 else |
333 return generateDayListSiteContentByRoom(bareRoomJid); -- fallback | 348 return generateDayListSiteContentByRoom(bareRoomJid); -- fallback |
334 end | 349 end |
335 end | 350 end |