plugins/mod_groups.lua

1
-- Prosody IM
2
-- Copyright (C) 2008-2010 Matthew Wild
3
-- Copyright (C) 2008-2010 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("debug", "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 groups[group_name][jid] then
33
					roster[jid].name = groups[group_name][jid];
34
				end
35
				if not roster[jid].groups then
36
					roster[jid].groups = { [group_name] = true };
37
				end
38
				roster[jid].groups[group_name] = true;
39
				roster[jid].persist = false;
40
			end
41
		end
42
	end
43
 
44
	-- Find groups this JID is a member of
45
	if members[bare_jid] then
46
		for _, group_name in ipairs(members[bare_jid]) do
47
			--module:log("debug", "Importing group %s", group_name);
48
			import_jids_to_roster(group_name);
49
		end
50
	end
51
	
52
	-- Import public groups
53
	if members[false] then
54
		for _, group_name in ipairs(members[false]) do
55
			--module:log("debug", "Importing group %s", group_name);
56
			import_jids_to_roster(group_name);
57
		end
58
	end
59
	
60
	if roster[false] then
61
		roster[false].version = true;
62
	end
63
end
64
 
65
function remove_virtual_contacts(username, host, datastore, data)
66
	if host == module_host and datastore == "roster" then
67
		local new_roster = {};
68
		for jid, contact in pairs(data) do
69
			if contact.persist ~= false then
70
				new_roster[jid] = contact;
71
			end
72
		end
73
		if new_roster[false] then
74
			new_roster[false].version = nil; -- Version is void
75
		end
76
		return username, host, datastore, new_roster;
77
	end
78
 
79
	return username, host, datastore, data;
80
end
81
 
82
function module.load()
83
	groups_file = config.get(module:get_host(), "core", "groups_file");
84
	if not groups_file then return; end
85
	
86
	module:hook("roster-load", inject_roster_contacts);
87
	datamanager.add_callback(remove_virtual_contacts);
88
	
89
	groups = { default = {} };
90
	members = { };
91
	local curr_group = "default";
92
	for line in io.lines(groups_file) do
93
		if line:match("^%s*%[.-%]%s*$") then
94
			curr_group = line:match("^%s*%[(.-)%]%s*$");
95
			if curr_group:match("^%+") then
96
				curr_group = curr_group:gsub("^%+", "");
97
				if not members[false] then
98
					members[false] = {};
99
				end
100
				members[false][#members[false]+1] = curr_group; -- Is a public group
101
			end
102
			module:log("debug", "New group: %s", tostring(curr_group));
103
			groups[curr_group] = groups[curr_group] or {};
104
		else
105
			-- Add JID
106
			local entryjid, name = line:match("([^=]*)=?(.*)");
107
			module:log("debug", "entryjid = '%s', name = '%s'", entryjid, name);
108
			local jid;
109
			jid = jid_prep(entryjid:match("%S+"));
110
			if jid then
111
				module:log("debug", "New member of %s: %s", tostring(curr_group), tostring(jid));
112
				groups[curr_group][jid] = name or false;
113
				members[jid] = members[jid] or {};
114
				members[jid][#members[jid]+1] = curr_group;
115
			end
116
		end
117
	end
118
	module:log("info", "Groups loaded successfully");
119
end
120
 
121
function module.unload()
122
	datamanager.remove_callback(remove_virtual_contacts);
123
end