mod_adhoc_groups/mod_adhoc_groups.lua
changeset 2852 232da6b1d2c1
parent 2851 907a15c9d621
child 2874 d8325dfb6a13
equal deleted inserted replaced
2851:907a15c9d621 2852:232da6b1d2c1
     1 local rostermanager = require"core.rostermanager";
     1 local rostermanager = require"core.rostermanager";
     2 local jid_join = require"util.jid".join;
     2 local jid_join = require"util.jid".join;
       
     3 local jid_split = require"util.jid".split;
     3 local host = module.host;
     4 local host = module.host;
     4 local sessions = prosody.hosts[host].sessions;
     5 local st = require "util.stanza";
       
     6 
       
     7 local groups = module:open_store("groups");
       
     8 local memberships = module:open_store("groups", "map");
       
     9 
       
    10 module:depends("adhoc");
       
    11 
       
    12 local adhoclib = module:require "adhoc";
       
    13 local dataform = require"util.dataforms";
       
    14 local adhoc_inital_data = require "util.adhoc".new_initial_data_form;
     5 
    15 
     6 -- Make a *one-way* subscription. User will see when contact is online,
    16 -- Make a *one-way* subscription. User will see when contact is online,
     7 -- contact will not see when user is online.
    17 -- contact will not see when user is online.
     8 local function subscribe(user, contact)
    18 local function subscribe(user, contact)
     9 	local user_jid, contact_jid = jid_join(user, host), jid_join(contact, host);
    19 	local user_jid, contact_jid = jid_join(user, host), jid_join(contact, host);
    18 	rostermanager.process_inbound_subscription_approval(user, host, contact_jid);
    28 	rostermanager.process_inbound_subscription_approval(user, host, contact_jid);
    19 
    29 
    20 	-- Push updates to both rosters
    30 	-- Push updates to both rosters
    21 	rostermanager.roster_push(user, host, contact_jid);
    31 	rostermanager.roster_push(user, host, contact_jid);
    22 	rostermanager.roster_push(contact, host, user_jid);
    32 	rostermanager.roster_push(contact, host, user_jid);
       
    33 
       
    34 	module:send(st.presence({ type = "probe", from = user_jid, to = contact_jid }));
    23 end
    35 end
    24 
    36 
       
    37 local create_form = dataform.new {
       
    38 	title = "Create a new group";
       
    39 	{
       
    40 		type = "hidden";
       
    41 		name = "FORM_TYPE";
       
    42 		value = "xmpp:zash.se/adhoc_groups#new";
       
    43 	};
       
    44 	{
       
    45 		type = "text-single";
       
    46 		name = "group";
       
    47 		label = "Name of group";
       
    48 		required = true;
       
    49 	};
       
    50 };
    25 
    51 
    26 module:hook("resource-bind", function(event)
    52 local join_form = dataform.new {
    27 	local session = event.session;
    53 	title = "Pick the group to join";
    28 	local user = session.username;
    54 	{
    29 	local user_jid = jid_join(user, host);
    55 		type = "hidden";
    30 	for contact in pairs(sessions) do
    56 		name = "FORM_TYPE";
    31 		if contact ~= user then
    57 		value = "xmpp:zash.se/adhoc_groups#join";
    32 			local contact_jid = jid_join(contact, host);
    58 	};
    33 			if not rostermanager.is_contact_subscribed(user, host, contact_jid) then
    59 	{
    34 				subscribe(contact, user);
    60 		type = "list-single";
    35 			end
    61 		name = "group";
    36 			if not rostermanager.is_contact_subscribed(contact, host, user_jid) then
    62 		label = "Available groups";
    37 				subscribe(user, contact);
    63 		required = true;
    38 			end
    64 	};
       
    65 };
       
    66 
       
    67 local function _(f)
       
    68 	return function (fields, form_err, data)
       
    69 		local ok, message = f(fields, form_err, data);
       
    70 		if ok then
       
    71 			return { status = "completed", info = message };
       
    72 		else
       
    73 			return { status = "completed", error = { message = message} };
    39 		end
    74 		end
    40 	end
    75 	end
    41 end);
    76 end
    42 
    77 
       
    78 module:add_item("adhoc",
       
    79 	adhoclib.new("Create group",
       
    80 		"xmpp:zash.se/adhoc_groups#new",
       
    81 		adhoc_inital_data(create_form,
       
    82 			function ()
       
    83 				return {};
       
    84 			end,
       
    85 			_(function (fields, form_err, data)
       
    86 				local user = jid_split(data.from);
       
    87 				if form_err then
       
    88 					return false, "Problem in submitted form";
       
    89 				end
       
    90 
       
    91 				local group, err = groups:get(fields.group);
       
    92 				if group then
       
    93 					if err then
       
    94 						return false, "An error occured on the server. Please try again later.";
       
    95 					else
       
    96 						return false, "That group already exists";
       
    97 					end
       
    98 				end
       
    99 
       
   100 				if not groups:set(fields.group, { [user] = true }) then
       
   101 					return false, "An error occured while creating the group";
       
   102 				end
       
   103 
       
   104 				return true, ("The %s group has been created"):format(fields.group);
       
   105 			end)), "local_user")); -- Maybe admins only?
       
   106 
       
   107 module:add_item("adhoc",
       
   108 	adhoclib.new("Join group",
       
   109 		"xmpp:zash.se/adhoc_groups#join",
       
   110 		adhoc_inital_data(join_form,
       
   111 			function ()
       
   112 				local group_list = {};
       
   113 				for group in groups:users() do
       
   114 					table.insert(group_list, group);
       
   115 					module:log("debug", "Group: %q", group);
       
   116 				end
       
   117 				table.sort(group_list);
       
   118 				return { group = group_list };
       
   119 			end,
       
   120 			_(function (fields, form_err, data)
       
   121 				local user = jid_split(data.from);
       
   122 				if form_err then
       
   123 					return false, "Problem in submitted form";
       
   124 				end
       
   125 
       
   126 				local group, err = groups:get(fields.group);
       
   127 				if not group then
       
   128 					if err then
       
   129 						return false, "An error occured on the server. Please try again later.";
       
   130 					else
       
   131 						return false, "No such group";
       
   132 					end
       
   133 				end
       
   134 				if group[data.from] then
       
   135 					return false, "You are already in this group.";
       
   136 				end
       
   137 
       
   138 				if not memberships:set(fields.group, user, true) then
       
   139 					return false, "An error occured while adding you to the group";
       
   140 				end
       
   141 
       
   142 				for member in pairs(group) do
       
   143 					if member ~= user then
       
   144 						subscribe(user, member);
       
   145 						subscribe(member, user);
       
   146 					end
       
   147 				end
       
   148 
       
   149 				return true, ("Welcome to the %s group"):format(fields.group);
       
   150 			end)), "local_user"));