Diff

mod_muc_search/mod_muc_search.lua @ 4136:d2a9aa27169d

mod_muc_search: Implementation of the search.jabber.network XMPP API https://search.jabber.network/docs/api#xmpp
author Kim Alvefur <zash@zash.se>
date Fri, 17 Aug 2018 09:49:27 +0200
child 4137:5f4bcaad18ee
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_search/mod_muc_search.lua	Fri Aug 17 09:49:27 2018 +0200
@@ -0,0 +1,100 @@
+local dataforms = require "util.dataforms";
+local st = require "util.stanza";
+
+local mod_muc = module:depends("muc");
+assert(mod_muc.live_rooms, "Missing required MUC API. Prosody >= hg:f5c43e829d93 required")
+
+local search_form = dataforms.new {
+	{
+		type = "hidden";
+		value = "https://xmlns.zombofant.net/muclumbus/search/1.0#params";
+		name = "FORM_TYPE";
+	};
+	{
+		type = "text-single";
+		label = "Search for";
+		name = "q";
+	};
+	{
+		type = "boolean";
+		value = true;
+		label = "Search in name";
+		name = "sinname";
+	};
+	{
+		type = "boolean";
+		value = true;
+		label = "Search in description";
+		name = "sindescription";
+	};
+	{
+		type = "boolean";
+		value = true;
+		label = "Search in address";
+		name = "sinaddr";
+	};
+	{
+		type = "text-single";
+		value = "1";
+		label = "Minimum number of users";
+		name = "min_users";
+	};
+	{
+		options = {
+			{
+				label = "Number of online users";
+				value = "nusers";
+			};
+			{
+				label = "Address";
+				value = "address";
+			};
+		};
+		type = "list-single";
+		value = "nusers";
+		label = "Sort results by";
+		name = "key";
+	};
+};
+
+module:hook("iq-get/host/https://xmlns.zombofant.net/muclumbus/search/1.0:search", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	origin.send(st.reply(stanza)
+		:tag("search", { xmlns = "https://xmlns.zombofant.net/muclumbus/search/1.0" })
+			:add_child(search_form:form()));
+	return true;
+end);
+
+module:hook("iq-set/host/https://xmlns.zombofant.net/muclumbus/search/1.0:search", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	local search = stanza.tags[1];
+	local submitted = search:get_child("x", "jabber:x:data");
+	if not submitted then
+		origin.send(st.error_reply("modify", "bad-request", "Missing dataform"));
+		return;
+	end
+	local query = search_form:data(submitted);
+	module:log("debug", "Got query: %q", query);
+
+	local result = st.reply(stanza)
+		:tag("result", { xmlns = "https://xmlns.zombofant.net/muclumbus/search/1.0" });
+
+	for room in mod_muc.live_rooms() do
+
+		if room:get_public() and not room:get_members_only() then
+			module:log("debug", "Looking at room %s %q", room.jid, room._data);
+			if (query.sinname and room:get_name():find(query.q, 1, true))
+			or (query.sindescription and (room:get_description() or ""):find(query.q, 1, true))
+			or (query.sinaddr and room.jid:find(query.q, 1, true)) then
+				result:tag("item", { address = room.jid })
+					:text_tag("name", room:get_name())
+					:text_tag("description", room:get_description())
+					:text_tag("language", room:get_language())
+					:tag("is-open"):up()
+				:up();
+			end
+		end
+	end
+	origin.send(result);
+	return true;
+end);