Mercurial > prosody-modules
comparison mod_http_muc_log/mod_http_muc_log.lua @ 1606:2c8b985ebde5
mod_http_muc_log: Switch to a calendar view for selecting dates
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 10 Feb 2015 15:00:10 +0100 |
parents | c8a51d1bc96d |
children | c427de617ada |
comparison
equal
deleted
inserted
replaced
1605:c8a51d1bc96d | 1606:2c8b985ebde5 |
---|---|
1 local st = require "util.stanza"; | 1 local st = require "util.stanza"; |
2 local mt = require"util.multitable"; | |
2 local datetime = require"util.datetime"; | 3 local datetime = require"util.datetime"; |
3 local jid_split = require"util.jid".split; | 4 local jid_split = require"util.jid".split; |
4 local nodeprep = require"util.encodings".stringprep.nodeprep; | 5 local nodeprep = require"util.encodings".stringprep.nodeprep; |
5 local uuid = require"util.uuid".generate; | 6 local uuid = require"util.uuid".generate; |
6 local it = require"util.iterators"; | 7 local it = require"util.iterators"; |
7 local gettime = require"socket".gettime; | 8 local gettime = require"socket".gettime; |
8 local url = require"socket.url"; | 9 local url = require"socket.url"; |
9 local xml_escape = st.xml_escape; | 10 local xml_escape = st.xml_escape; |
10 local t_concat = table.concat; | 11 local t_concat = table.concat; |
12 local os_time, os_date = os.time, os.date; | |
11 | 13 |
12 local archive = module:open_store("muc_log", "archive"); | 14 local archive = module:open_store("muc_log", "archive"); |
13 | 15 |
14 -- Support both old and new MUC code | 16 -- Support both old and new MUC code |
15 local mod_muc = module:depends"muc"; | 17 local mod_muc = module:depends"muc"; |
90 and not (room.get_hidden or room.is_hidden)(room) | 92 and not (room.get_hidden or room.is_hidden)(room) |
91 and not (room.get_members_only or room.is_members_only)(room) | 93 and not (room.get_members_only or room.is_members_only)(room) |
92 and room._data.logging == true); | 94 and room._data.logging == true); |
93 end | 95 end |
94 | 96 |
95 -- FIXME Invent some more efficient API for this | 97 local function sort_Y(a,b) return a.year > b.year end |
96 local function dates_page(event, path) | 98 local function sort_m(a,b) return a.n > b.n end |
99 | |
100 local t_diff = os_time(os_date("*t")) - os_time(os_date("!*t")); | |
101 local function time(t) | |
102 return os_time(t) + t_diff; | |
103 end | |
104 | |
105 local function years_page(event, path) | |
97 local request, response = event.request, event.response; | 106 local request, response = event.request, event.response; |
98 | 107 |
99 local room = nodeprep(path:match("^(.*)/$")); | 108 local room = nodeprep(path:match("^(.*)/$")); |
100 if not room or not public_room(room) then return end | 109 if not room or not public_room(room) then return end |
101 | 110 |
102 local dates, i = {}, 1; | 111 local dates = mt.new(); |
103 module:log("debug", "Find all dates with messages"); | 112 module:log("debug", "Find all dates with messages"); |
104 local prev_day; | 113 local next_day, t; |
105 repeat | 114 repeat |
106 local iter = archive:find(room, { | 115 local iter = archive:find(room, { |
107 ["end"] = prev_day; | 116 start = next_day; |
108 limit = 1; | 117 limit = 1; |
109 with = "message<groupchat"; | 118 with = "message<groupchat"; |
110 reverse = true; | |
111 }) | 119 }) |
112 if not iter then break end | 120 if not iter then break end |
113 prev_day = nil; | 121 next_day = nil; |
114 for key, message, when in iter do | 122 for key, message, when in iter do |
115 prev_day = datetime.date(when); | 123 t = os_date("!*t", when); |
116 dates[i], i = { | 124 dates:set(t.year, t.month, t.day, when ); |
117 date = prev_day; | 125 next_day = when + (86400 - (when % 86400)); |
118 }, i + 1; | |
119 prev_day = datetime.parse(prev_day .. "T00:00:00Z") - 1; | |
120 break; | 126 break; |
121 end | 127 end |
122 until not prev_day; | 128 until not next_day; |
129 | |
130 local year, years; | |
131 local month, months; | |
132 local week, weeks; | |
133 local days; | |
134 local tmp, n; | |
135 | |
136 years = {}; | |
137 | |
138 for Y, m in pairs(dates.data) do | |
139 t = { year = Y, month = 1, day = 1 }; | |
140 months = { }; | |
141 year = { year = Y, months = months }; | |
142 years[#years+1] = year; | |
143 for m, d in pairs(m) do | |
144 t.day = 1; | |
145 t.month = m; | |
146 tmp = os_date("!*t", time(t)); | |
147 days = {}; | |
148 week = { days = days } | |
149 weeks = { week }; | |
150 month = { year = year.year, month = os_date("!%B", time(t)), n = m, weeks = weeks }; | |
151 months[#months+1] = month; | |
152 n = 1; | |
153 for i=1, (tmp.wday+5)%7 do | |
154 days[n], n = {}, n+1; | |
155 end | |
156 for i = 1, 31 do | |
157 t.day = i; | |
158 tmp = os_date("!*t", time(t)); | |
159 if tmp.month ~= m then break end | |
160 if i > 1 and tmp.wday == 2 then | |
161 days = {}; | |
162 weeks[#weeks+1] = { days = days }; | |
163 n = 1; | |
164 end | |
165 if d[i] then | |
166 days[n], n = { wday = tmp.wday, links = {{ href = datetime.date(d[i]), day = i }} }, n+1; | |
167 else | |
168 days[n], n = { wday = tmp.wday, plain = i }, n+1; | |
169 end | |
170 end | |
171 end | |
172 table.sort(year, sort_m); | |
173 end | |
174 table.sort(years, sort_Y); | |
123 | 175 |
124 response.headers.content_type = "text/html; charset=utf-8"; | 176 response.headers.content_type = "text/html; charset=utf-8"; |
125 return render(template, { | 177 return render(template, { |
126 title = get_room(room):get_name(); | 178 title = get_room(room):get_name(); |
127 jid = get_room(room).jid; | 179 jid = get_room(room).jid; |
128 dates = dates; | 180 years = years; |
129 links = { | 181 links = { |
130 { href = "../", rel = "up", text = "Back to room list" }, | 182 { href = "../", rel = "up", text = "Back to room list" }, |
131 }; | 183 }; |
132 }); | 184 }); |
133 end | 185 end |
136 local request, response = event.request, event.response; | 188 local request, response = event.request, event.response; |
137 | 189 |
138 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$"); | 190 local room, date = path:match("^(.-)/(%d%d%d%d%-%d%d%-%d%d)$"); |
139 room = nodeprep(room); | 191 room = nodeprep(room); |
140 if not room then | 192 if not room then |
141 return dates_page(event, path); | 193 return years_page(event, path); |
142 end | 194 end |
143 if not public_room(room) then return end | 195 if not public_room(room) then return end |
144 | 196 |
145 local logs, i = {}, 1; | 197 local logs, i = {}, 1; |
146 local iter, err = archive:find(room, { | 198 local iter, err = archive:find(room, { |
206 return render(template, { | 258 return render(template, { |
207 title = ("%s - %s"):format(get_room(room):get_name(), date); | 259 title = ("%s - %s"):format(get_room(room):get_name(), date); |
208 jid = get_room(room).jid; | 260 jid = get_room(room).jid; |
209 lines = logs; | 261 lines = logs; |
210 links = { | 262 links = { |
211 { href = "./", rel = "up", text = "Back to date list" }, | 263 { href = "./", rel = "up", text = "Back to calendar" }, |
212 { href = prev_when, rel = "prev", text = prev_when}, | 264 { href = prev_when, rel = "prev", text = prev_when}, |
213 { href = next_when, rel = "next", text = next_when}, | 265 { href = next_when, rel = "next", text = next_when}, |
214 }; | 266 }; |
215 }); | 267 }); |
216 end | 268 end |