Software /
code /
prosody-modules
Diff
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 |
line wrap: on
line diff
--- a/mod_adhoc_groups/mod_adhoc_groups.lua Tue Nov 21 15:01:18 2017 +0100 +++ b/mod_adhoc_groups/mod_adhoc_groups.lua Tue Nov 21 16:58:50 2017 +0100 @@ -1,7 +1,17 @@ local rostermanager = require"core.rostermanager"; local jid_join = require"util.jid".join; +local jid_split = require"util.jid".split; local host = module.host; -local sessions = prosody.hosts[host].sessions; +local st = require "util.stanza"; + +local groups = module:open_store("groups"); +local memberships = module:open_store("groups", "map"); + +module:depends("adhoc"); + +local adhoclib = module:require "adhoc"; +local dataform = require"util.dataforms"; +local adhoc_inital_data = require "util.adhoc".new_initial_data_form; -- Make a *one-way* subscription. User will see when contact is online, -- contact will not see when user is online. @@ -20,23 +30,121 @@ -- Push updates to both rosters rostermanager.roster_push(user, host, contact_jid); rostermanager.roster_push(contact, host, user_jid); + + module:send(st.presence({ type = "probe", from = user_jid, to = contact_jid })); +end + +local create_form = dataform.new { + title = "Create a new group"; + { + type = "hidden"; + name = "FORM_TYPE"; + value = "xmpp:zash.se/adhoc_groups#new"; + }; + { + type = "text-single"; + name = "group"; + label = "Name of group"; + required = true; + }; +}; + +local join_form = dataform.new { + title = "Pick the group to join"; + { + type = "hidden"; + name = "FORM_TYPE"; + value = "xmpp:zash.se/adhoc_groups#join"; + }; + { + type = "list-single"; + name = "group"; + label = "Available groups"; + required = true; + }; +}; + +local function _(f) + return function (fields, form_err, data) + local ok, message = f(fields, form_err, data); + if ok then + return { status = "completed", info = message }; + else + return { status = "completed", error = { message = message} }; + end + end end +module:add_item("adhoc", + adhoclib.new("Create group", + "xmpp:zash.se/adhoc_groups#new", + adhoc_inital_data(create_form, + function () + return {}; + end, + _(function (fields, form_err, data) + local user = jid_split(data.from); + if form_err then + return false, "Problem in submitted form"; + end -module:hook("resource-bind", function(event) - local session = event.session; - local user = session.username; - local user_jid = jid_join(user, host); - for contact in pairs(sessions) do - if contact ~= user then - local contact_jid = jid_join(contact, host); - if not rostermanager.is_contact_subscribed(user, host, contact_jid) then - subscribe(contact, user); - end - if not rostermanager.is_contact_subscribed(contact, host, user_jid) then - subscribe(user, contact); - end - end - end -end); + local group, err = groups:get(fields.group); + if group then + if err then + return false, "An error occured on the server. Please try again later."; + else + return false, "That group already exists"; + end + end + + if not groups:set(fields.group, { [user] = true }) then + return false, "An error occured while creating the group"; + end + + return true, ("The %s group has been created"):format(fields.group); + end)), "local_user")); -- Maybe admins only? +module:add_item("adhoc", + adhoclib.new("Join group", + "xmpp:zash.se/adhoc_groups#join", + adhoc_inital_data(join_form, + function () + local group_list = {}; + for group in groups:users() do + table.insert(group_list, group); + module:log("debug", "Group: %q", group); + end + table.sort(group_list); + return { group = group_list }; + end, + _(function (fields, form_err, data) + local user = jid_split(data.from); + if form_err then + return false, "Problem in submitted form"; + end + + local group, err = groups:get(fields.group); + if not group then + if err then + return false, "An error occured on the server. Please try again later."; + else + return false, "No such group"; + end + end + if group[data.from] then + return false, "You are already in this group."; + end + + if not memberships:set(fields.group, user, true) then + return false, "An error occured while adding you to the group"; + end + + for member in pairs(group) do + if member ~= user then + subscribe(user, member); + subscribe(member, user); + end + end + + return true, ("Welcome to the %s group"):format(fields.group); + end)), "local_user"));