Comparison

mod_adhoc_groups/mod_adhoc_groups.lua @ 2848:232da6b1d2c1

mod_adhoc_groups: Allow users to create and join roster groups
author Kim Alvefur <zash@zash.se>
date Tue, 21 Nov 2017 16:58:50 +0100
parent 2847:907a15c9d621
child 2870:d8325dfb6a13
comparison
equal deleted inserted replaced
2847:907a15c9d621 2848: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"));