Software /
code /
prosody-modules
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) |