Mercurial > 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 |
| parents | 907a15c9d621 |
| children | 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")); |
