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