plugins.xeps: Add 'xep' command for looking up XMPP extensions by name or number

Mon, 21 Jun 2010 14:39:19 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Mon, 21 Jun 2010 14:39:19 +0100
changeset 27
2c137706d42c
parent 26
f056ad661521
child 28
d0d1d88ec0ef

plugins.xeps: Add 'xep' command for looking up XMPP extensions by name or number

plugins/xeps.lua file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/xeps.lua	Mon Jun 21 14:39:19 2010 +0100
@@ -0,0 +1,84 @@
+local parse_xeps, xeps_updated_at;
+local xeps = {};
+
+function riddim.plugins.xeps(bot)
+	bot.stream:add_plugin("http");
+	local http = verse.http;
+	bot:hook("commands/xep", function(command)
+		-- Cache XEP list for an hour
+		if os.difftime(os.time(), xeps_updated_at) > (60 * 60) then -- Not refreshed within 1 hour
+			http.request('http://xmpp.org/extensions/xeps.xml', nil, function (data, code)
+				if code ~= 200 then
+					if code > 0 then
+						command:reply("Received HTTP "..code.." error trying to fetch the XEP list");
+					else
+						command:reply("Unable to fetch the XEP list from xmpp.org: "..data:gsub("%-", " "));
+					end
+					return;
+				end
+				xeps_updated_at = os.time();
+				parse_xeps(data);
+				command:reply(handle_xep_command(command));
+			end);
+		else
+			return handle_xep_command(command);
+		end
+	end);
+end
+
+function handle_xep_command(command)
+		local xepnum = command.param;
+		if not xepnum then return "Please supply an XEP number or a search string :)"; end
+			if not tonumber(xepnum) then -- Search for an XEP
+				if xepnum:match("^%d+ ex") then
+					local num, example = xepnum:match("^(%d+) ex%S* (%d+)$");
+					return "http://xmpp.org/extensions/xep-"..string.rep("0", 4-num:len())..num..".html#example-"..tostring(example);
+				end
+				local results = {};
+				for x, xep in pairs(xeps) do
+					name = " "..xep.name:lower().." ";
+					if name:match(xepnum:lower():gsub("%-", "%%-")) then
+						table.insert(results, x);
+						--return commands.xep(msg, x);
+					end
+				end
+				if #results == 0 then
+					return "Sorry, I couldn't find a match";
+				elseif #results == 1 then
+					command.param = results[1];
+					return handle_xep_command(command);
+				else
+					-- We have more than one match
+					local ret = "Multiple matches:";
+					for _, x in ipairs(results) do
+						local xepnum = tostring(tonumber(x));
+						xepnum = string.rep("0", 4-x:len())..x;
+						local xep = xeps[tostring(x)];
+						ret = string.format("%s XEP-%s: %s%s", ret, xep.number, xep.name, ((_ < #results) and ",") or "");
+					end
+					return ret;
+				end
+			end
+			-- Check that xepnum is a valid number
+			xepnum = tostring(tonumber(xepnum));
+			if not xepnum then return "What XEP? or enter a search string."; end
+			-- Expand to full 4 char number
+			xepnum = string.rep("0", 4-xepnum:len())..xepnum;
+			xep = xeps[tostring(xepnum)];
+			if not xep then return "Sorry, I don't think there is a XEP-"..xepnum; end
+			return "XEP-"..xep.number..": "..xep.name.." is "..xep.type.." ("..xep.status..", "..xep.updated..") See: http://xmpp.org/extensions/xep-"..xep.number..".html";
+end
+
+function parse_xeps(t)
+if not t then return nil; end
+local currxep = {};
+        for b in string.gmatch(t,"<xep>(.-)</xep>") do
+                for k,v in string.gmatch(b,"<(%w+)>(.-)</%1>") do
+                        currxep[k] = v;
+                end
+		xeps[currxep.number] = { };
+		for k, v in pairs(currxep) do xeps[currxep.number][k] = v end
+        end
+	xeps["0028"] = { number = "0028", name = "XSF Plans for World Domination", type="Top Secret", status = "Hidden", updated = "Work ongoing" };
+	return true;
+end

mercurial