29 local max_history_length = module:get_option_number("max_history_messages", 1000); |
29 local max_history_length = module:get_option_number("max_history_messages", 1000); |
30 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", max_history_length); |
30 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", max_history_length); |
31 |
31 |
32 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false); |
32 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false); |
33 local log_by_default = module:get_option_boolean("muc_log_by_default", true); |
33 local log_by_default = module:get_option_boolean("muc_log_by_default", true); |
34 local advertise_archive = module:get_option_boolean("muc_log_advertise", true); |
|
35 |
34 |
36 local archive_store = "archive2"; |
35 local archive_store = "archive2"; |
37 local archive = module:open_store(archive_store, "archive"); |
36 local archive = module:open_store(archive_store, "archive"); |
38 if not archive or archive.name == "null" then |
37 if not archive or archive.name == "null" then |
39 module:log("error", "Could not open archive storage"); |
38 module:log("error", "Could not open archive storage"); |
107 end |
106 end |
108 end |
107 end |
109 end); |
108 end); |
110 end |
109 end |
111 |
110 |
|
111 local query_form = dataform { |
|
112 { name = "FORM_TYPE"; type = "hidden"; value = xmlns_mam; }; |
|
113 { name = "with"; type = "jid-single"; }; |
|
114 { name = "start"; type = "text-single" }; |
|
115 { name = "end"; type = "text-single"; }; |
|
116 }; |
|
117 |
|
118 -- Serve form |
|
119 module:hook("iq-get/self/"..xmlns_mam..":query", function(event) |
|
120 local origin, stanza = event.origin, event.stanza; |
|
121 return origin.send(st.reply(stanza):add_child(query_form:form())); |
|
122 end); |
|
123 |
112 -- Handle archive queries |
124 -- Handle archive queries |
113 module:hook("iq-get/bare/"..xmlns_mam..":query", function(event) |
125 module:hook("iq-set/bare/"..xmlns_mam..":query", function(event) |
114 local origin, stanza = event.origin, event.stanza; |
126 local origin, stanza = event.origin, event.stanza; |
115 local room = stanza.attr.to; |
127 local room = stanza.attr.to; |
116 local room_node = jid_split(room); |
128 local room_node = jid_split(room); |
117 local orig_from = stanza.attr.from; |
129 local orig_from = stanza.attr.from; |
118 local query = stanza.tags[1]; |
130 local query = stanza.tags[1]; |
131 end |
143 end |
132 |
144 |
133 local qid = query.attr.queryid; |
145 local qid = query.attr.queryid; |
134 |
146 |
135 -- Search query parameters |
147 -- Search query parameters |
136 local qstart = query:get_child_text("start"); |
148 local qwith, qstart, qend; |
137 local qend = query:get_child_text("end"); |
149 local form = query:get_child("x", "jabber:x:data"); |
138 module:log("debug", "Archive query, id %s from %s until %s)", |
150 if form then |
139 tostring(qid), qstart or "the dawn of time", qend or "now"); |
151 local err; |
|
152 form, err = query_form:data(form); |
|
153 if err then |
|
154 return origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err)))) |
|
155 end |
|
156 qwith, qstart, qend = form["with"], form["start"], form["end"]; |
|
157 qwith = qwith and jid_bare(qwith); -- dataforms does jidprep |
|
158 end |
140 |
159 |
141 if qstart or qend then -- Validate timestamps |
160 if qstart or qend then -- Validate timestamps |
142 local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend)) |
161 local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend)) |
143 if (qstart and not vstart) or (qend and not vend) then |
162 if (qstart and not vstart) or (qend and not vend) then |
144 origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid timestamp")) |
163 origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid timestamp")) |
167 if not data then |
186 if not data then |
168 return origin.send(st.error_reply(stanza, "cancel", "internal-server-error")); |
187 return origin.send(st.error_reply(stanza, "cancel", "internal-server-error")); |
169 end |
188 end |
170 local count = err; |
189 local count = err; |
171 |
190 |
|
191 origin.send(st.reply(stanza)) |
172 local msg_reply_attr = { to = stanza.attr.from, from = stanza.attr.to }; |
192 local msg_reply_attr = { to = stanza.attr.from, from = stanza.attr.to }; |
173 |
193 |
174 -- Wrap it in stuff and deliver |
194 -- Wrap it in stuff and deliver |
175 local fwd_st, first, last; |
195 local fwd_st, first, last; |
176 for id, item, when in data do |
196 for id, item, when in data do |
192 end |
212 end |
193 -- That's all folks! |
213 -- That's all folks! |
194 module:log("debug", "Archive query %s completed", tostring(qid)); |
214 module:log("debug", "Archive query %s completed", tostring(qid)); |
195 |
215 |
196 if reverse then first, last = last, first; end |
216 if reverse then first, last = last, first; end |
197 return origin.send(st.reply(stanza) |
217 return origin.send(st.message(msg_reply_attr) |
198 :query(xmlns_mam):add_child(rsm.generate { |
218 :tag("fin", { xmlns = xmlns_mam, queryid = qid }) |
199 first = first, last = last, count = count })); |
219 :add_child(rsm.generate { |
|
220 first = first, last = last, count = count })); |
200 end); |
221 end); |
201 |
222 |
202 function send_history(self, to, stanza) |
223 function send_history(self, to, stanza) |
203 local maxchars, maxstanzas, seconds, since; |
224 local maxchars, maxstanzas, seconds, since; |
204 local history_tag = stanza:find("{http://jabber.org/protocol/muc}x/history") |
225 local history_tag = stanza:find("{http://jabber.org/protocol/muc}x/history") |
262 -- And stash it |
283 -- And stash it |
263 local with = stanza.name |
284 local with = stanza.name |
264 if stanza.attr.type then |
285 if stanza.attr.type then |
265 with = with .. "<" .. stanza.attr.type |
286 with = with .. "<" .. stanza.attr.type |
266 end |
287 end |
267 local ok, id = archive:append(room, nil, time_now(), with, stanza); |
288 archive:append(room, nil, time_now(), with, stanza); |
268 if ok and advertise_archive then |
|
269 stanza:tag("archived", { xmlns = xmlns_mam, by = jid_bare(orig_to), id = id }):up(); |
|
270 end |
|
271 end |
289 end |
272 |
290 |
273 module:hook("muc-room-destroyed", function(event) |
291 module:hook("muc-room-destroyed", function(event) |
274 archive:delete(jid_split(event.room.jid)); |
292 archive:delete(jid_split(event.room.jid)); |
275 end); |
293 end); |