Sat, 08 Jan 2011 18:00:50 +0000
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 +