Software /
code /
prosody-modules
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")); |