Merge with ciarang

Sat, 08 Jan 2011 18:00:50 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Sat, 08 Jan 2011 18:00:50 +0000
changeset 52
0157bfe14958
parent 50
cd9b25249098 (diff)
parent 51
c93cae5fe3dc (current diff)
child 55
3a321510707c

Merge with ciarang

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/bookmarks.lua	Sat Jan 08 18:00:50 2011 +0000
@@ -0,0 +1,70 @@
+local st = require "util.stanza";
+
+-- set allow_add_bookmarks = true; in config to enable the bookmark command
+
+function riddim.plugins.bookmarks(bot)
+	local my_bookmarks = {};
+
+	bot.stream:add_plugin("private");
+
+	local function get_bookmarks(callback) 
+		bot.stream:private_get("storage", "storage:bookmarks", function(storage)
+			if not storage then
+				storage = st.tag("storage", { xmlns = "storage:bookmarks" });
+			end
+			if callback and type(callback) == "function" then
+				callback(storage);
+			end
+		end);
+	end
+
+	local function add_bookmark(bookmark, callback)
+		-- TODO Check if a room is bookmarked already
+		if not bookmark or type(bookmark) ~= "table" or not bookmark.jid then return end
+		if not bookmark.name then
+			bookmark.name = jid.split(bookmark.jid);
+		end
+		local nick = bot.config.nick;
+		if bookmark.nick then
+			nick = bookmark.nick;
+			bookmark.nick = nil;
+		end
+		get_bookmarks(function(storage)
+			storage:tag("conference", bookmark)
+				:tag("nick"):text(nick):up()
+			:up();
+			bot.stream:private_set("storage", "storage:bookmarks", storage, callback);
+		end);
+	end
+
+	local function join_bookmarked_rooms()
+		get_bookmarks(function(storage)
+			for i, room in ipairs(storage) do
+				if room.name == "conference" and room.attr.jid then
+					my_bookmarks[room.attr.jid] = true; -- to know which rooms are bookmarked
+					if room.attr.autojoin == "true" or room.attr.autojoin == "1" then
+						nick = room:get_child("nick");
+						nick = nick and nick[1] or bot.config.nick;
+						bot:join_room(room.attr.jid, nick);
+					end
+					-- TODO Passwords
+					-- Maybe get the hook in before the groupchat is loaded
+					-- and add to the bot.config.autojoin variable?
+				end
+			end
+		end);
+	end
+
+	bot:hook("started", join_bookmarked_rooms);
+
+	if bot.config.allow_add_bookmarks then
+		bot:hook("commands/bookmark", function(command)
+			local room = command.param and jid.bare(command.param) or command.room.jid;
+			if my_bookmarks[room] then return "Already bookmarked" end
+			my_bookmarks[room] = true;
+				
+			add_bookmark({ jid = room, autojoin = "true" }, function() command:reply("Bookmarked " .. room) end);
+		end);
+	end
+
+end
--- a/plugins/groupchat.lua	Fri Nov 19 10:17:53 2010 +0000
+++ b/plugins/groupchat.lua	Sat Jan 08 18:00:50 2011 +0000
@@ -80,6 +80,15 @@
 					jid = presence.stanza.attr.from;
 					presence = presence.stanza;
 				};
+				local x = presence.stanza:get_child("x", xmlns_muc .. "#user");
+				if x then
+					local x_item = x:get_child("item");
+					if x_item and x_item.attr then
+						occupants[nick].real_jid    = x_item.attr.jid;
+						occupants[nick].affiliation = x_item.attr.affiliation;
+						occupants[nick].role        = x_item.attr.role;
+					end
+				end
 				if nick == room.nick then
 					room.bot:event("groupchat/joined", room);
 				else
@@ -122,6 +131,20 @@
 	self:send(st.presence({type="unavailable"}));
 end
 
+function room_mt:set_role(nick, role, reason)
+	self:send(st.iq({type="set"})
+		:query(xmlns_muc .. "#admin")
+			:tag("item", {nick = nick, role = role})
+				:tag("reason"):text(reason or ""));
+end
+
+function room_mt:set_affiliation(nick, affiliation, reason)
+	self:send(st.iq({type="set"})
+		:query(xmlns_muc .. "#admin")
+			:tag("item", {nick = nick, affiliation = affiliation})
+				:tag("reason"):text(reason or ""));
+end
+
 function room_mt:event(name, arg)
 	self.bot.stream:debug("Firing room event: %s", name);
 	return self.events.fire_event(name, arg);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/opdown.lua	Sat Jan 08 18:00:50 2011 +0000
@@ -0,0 +1,76 @@
+local jid_bare = require "util.jid".bare;
+
+function riddim.plugins.opdown(bot)
+	local admin = bot.config.admin;
+
+	-- To allow anyone other than the admin to use a command,
+	-- simply add them to the table, like
+	-- opdown_map = {
+	--   op = { role = "moderator", "operator@host" }, -- operator is allowed to use !op
+	--   "admin@host" -- allowed to use all commands
+	-- }
+	-- also, bot.config.admin is allowed to do anything
+
+	local command_map = bot.config.opdown_map or {
+		owner = { affiliation =       "owner" };
+		admin = { affiliation =       "admin" };
+		op    = { role        =   "moderator" };
+		member= { affiliation =      "member" };
+		down  = { role        = "participant",
+		          affiliation =        "none" };
+		--ban   = { affiliation =     "outcast" };
+		--kick  = { role        =        "none" };
+	}
+
+	function opdown(command)
+		if not command.room then
+			return "This command is only available in groupchats.";
+		end
+
+		local what = command_map[command.command];
+		if not what then return end
+		local room = command.room;
+		local who = command.param or command.sender.nick;
+		local commander = command.sender;
+		local actor = jid_bare(command.sender.real_jid);
+
+		if not actor then
+			return "I don't know who you really are?";
+		end
+
+		if actor ~= admin then
+			local allow = false;
+			for i = 1,#what do
+				if what[i] == actor then
+					allow = true;
+					break;
+				end
+			end
+			if not allow then
+				for i = 1,#command_map do
+					if command_map[i] == actor then
+						allow = true;
+						break;
+					end
+				end
+			end
+			if not allow then
+				return "I can't let you do that!";
+			end
+		end
+
+		if command.room.occupants[who] then
+			if what.role then
+				command.room:set_role(who, what.role, "As commanded");
+			end
+			if what.affiliation then
+				command.room:set_affiliation(who, what.affiliation, "As commanded");
+			end
+		end
+	end
+
+	for k in pairs(command_map) do
+		bot:hook("commands/" .. k, opdown);
+	end
+end
+

mercurial