mod_mam_muc/mod_mam_muc.lua
changeset 1535 efbb047c01e7
parent 1534 4dd6eebc8fbd
child 1536 4fb280768efc
equal deleted inserted replaced
1534:4dd6eebc8fbd 1535:efbb047c01e7
    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);