1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
local groups;
local members;
local jid, datamanager = require "util.jid", require "util.datamanager";
local jid_prep = jid.prep;
local module_host = module:get_host();
function inject_roster_contacts(event)
local username, host= event.username, event.host;
--module:log("debug", "Injecting group members to roster");
local bare_jid = username.."@"..host;
if not members[bare_jid] and not members[false] then return; end -- Not a member of any groups
local roster = event.roster;
local function import_jids_to_roster(group_name)
for jid in pairs(groups[group_name]) do
-- Add them to roster
--module:log("debug", "processing jid %s in group %s", tostring(jid), tostring(group_name));
if jid ~= bare_jid then
if not roster[jid] then roster[jid] = {}; end
roster[jid].subscription = "both";
if groups[group_name][jid] then
roster[jid].name = groups[group_name][jid];
end
if not roster[jid].groups then
roster[jid].groups = { [group_name] = true };
end
roster[jid].groups[group_name] = true;
roster[jid].persist = false;
end
end
end
-- Find groups this JID is a member of
if members[bare_jid] then
for _, group_name in ipairs(members[bare_jid]) do
--module:log("debug", "Importing group %s", group_name);
import_jids_to_roster(group_name);
end
end
-- Import public groups
if members[false] then
for _, group_name in ipairs(members[false]) do
--module:log("debug", "Importing group %s", group_name);
import_jids_to_roster(group_name);
end
end
if roster[false] then
roster[false].version = true;
end
end
function remove_virtual_contacts(username, host, datastore, data)
if host == module_host and datastore == "roster" then
local new_roster = {};
for jid, contact in pairs(data) do
if contact.persist ~= false then
new_roster[jid] = contact;
end
end
if new_roster[false] then
new_roster[false].version = nil; -- Version is void
end
return username, host, datastore, new_roster;
end
return username, host, datastore, data;
end
function module.load()
local groups_file = module:get_option_path("groups_file", nil, "config");
if not groups_file then return; end
module:hook("roster-load", inject_roster_contacts);
datamanager.add_callback(remove_virtual_contacts);
groups = { default = {} };
members = { };
local curr_group = "default";
for line in io.lines(groups_file) do
if line:match("^%s*%[.-%]%s*$") then
curr_group = line:match("^%s*%[(.-)%]%s*$");
if curr_group:match("^%+") then
curr_group = curr_group:gsub("^%+", "");
if not members[false] then
members[false] = {};
end
members[false][#members[false]+1] = curr_group; -- Is a public group
end
module:log("debug", "New group: %s", tostring(curr_group));
groups[curr_group] = groups[curr_group] or {};
else
-- Add JID
local entryjid, name = line:match("([^=]*)=?(.*)");
module:log("debug", "entryjid = '%s', name = '%s'", entryjid, name);
local jid;
jid = jid_prep(entryjid:match("%S+"));
if jid then
module:log("debug", "New member of %s: %s", tostring(curr_group), tostring(jid));
groups[curr_group][jid] = name or false;
members[jid] = members[jid] or {};
members[jid][#members[jid]+1] = curr_group;
elseif entryjid:match("%S") then
module:log("warn", "Invalid JID: %q", entryjid);
end
end
end
module:log("info", "Groups loaded successfully");
end
function module.unload()
datamanager.remove_callback(remove_virtual_contacts);
end
-- Public for other modules to access
function group_contains(group_name, jid)
return groups[group_name][jid];
end
|