Comparison

plugins/muc/mod_muc.lua @ 6238:b2b523d21891

plugins/muc/mod_muc: Move room persistence to own block
author daurnimator <quae@daurnimator.com>
date Tue, 29 Apr 2014 14:24:50 -0400
parent 6237:a58685df9d16
child 6239:a791dd781238
comparison
equal deleted inserted replaced
6237:a58685df9d16 6238:b2b523d21891
22 end 22 end
23 23
24 local muclib = module:require "muc"; 24 local muclib = module:require "muc";
25 local muc_new_room = muclib.new_room; 25 local muc_new_room = muclib.new_room;
26 room_mt = muclib.room_mt; -- Yes, global. 26 room_mt = muclib.room_mt; -- Yes, global.
27 local persistent = module:require "muc/persistent";
28 local jid_split = require "util.jid".split; 27 local jid_split = require "util.jid".split;
29 local jid_bare = require "util.jid".bare; 28 local jid_bare = require "util.jid".bare;
30 local st = require "util.stanza"; 29 local st = require "util.stanza";
31 local um_is_admin = require "core.usermanager".is_admin; 30 local um_is_admin = require "core.usermanager".is_admin;
32 local hosts = prosody.hosts; 31 local hosts = prosody.hosts;
33 32
34 rooms = {}; 33 rooms = {};
35 local rooms = rooms; 34 local rooms = rooms;
36 local persistent_rooms_storage = module:open_store("persistent");
37 local persistent_rooms = persistent_rooms_storage:get() or {};
38 local room_configs = module:open_store("config");
39 35
40 -- Configurable options 36 -- Configurable options
41 muclib.set_max_history_length(module:get_option_number("max_history_messages")); 37 muclib.set_max_history_length(module:get_option_number("max_history_messages"));
42 38
43 module:depends("disco"); 39 module:depends("disco");
62 if is_admin(jid) then return nil, "modify", "not-acceptable"; end 58 if is_admin(jid) then return nil, "modify", "not-acceptable"; end
63 return _set_affiliation(self, actor, jid, ...); 59 return _set_affiliation(self, actor, jid, ...);
64 end 60 end
65 end 61 end
66 62
67 local function room_save(room, forced)
68 local node = jid_split(room.jid);
69 local is_persistent = persistent.get(room);
70 persistent_rooms[room.jid] = is_persistent;
71 if is_persistent then
72 local history = room._data.history;
73 room._data.history = nil;
74 local data = {
75 jid = room.jid;
76 _data = room._data;
77 _affiliations = room._affiliations;
78 };
79 room_configs:set(node, data);
80 room._data.history = history;
81 elseif forced then
82 room_configs:set(node, nil);
83 if not next(room._occupants) then -- Room empty
84 rooms[room.jid] = nil;
85 end
86 end
87 if forced then persistent_rooms_storage:set(nil, persistent_rooms); end
88 end
89
90 function create_room(jid) 63 function create_room(jid)
91 local room = muc_new_room(jid); 64 local room = muc_new_room(jid);
92 room.save = room_save;
93 rooms[jid] = room; 65 rooms[jid] = room;
94 module:fire_event("muc-room-created", { room = room }); 66 module:fire_event("muc-room-created", { room = room });
95 return room; 67 return room;
96 end 68 end
97 69
101 73
102 function get_room_from_jid(room_jid) 74 function get_room_from_jid(room_jid)
103 return rooms[room_jid] 75 return rooms[room_jid]
104 end 76 end
105 77
106 local persistent_errors = false; 78 do -- Persistent rooms
107 for jid in pairs(persistent_rooms) do 79 local persistent = module:require "muc/persistent";
108 local node = jid_split(jid); 80 local persistent_rooms_storage = module:open_store("persistent");
109 local data = room_configs:get(node); 81 local persistent_rooms = persistent_rooms_storage:get() or {};
110 if data then 82 local room_configs = module:open_store("config");
111 local room = create_room(jid); 83
112 room._data = data._data; 84 local function room_save(room, forced)
113 room._affiliations = data._affiliations; 85 local node = jid_split(room.jid);
114 else -- missing room data 86 local is_persistent = persistent.get(room);
115 persistent_rooms[jid] = nil; 87 persistent_rooms[room.jid] = is_persistent;
116 module:log("error", "Missing data for room '%s', removing from persistent room list", jid); 88 if is_persistent then
117 persistent_errors = true; 89 local history = room._data.history;
118 end 90 room._data.history = nil;
119 end 91 local data = {
120 if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end 92 jid = room.jid;
93 _data = room._data;
94 _affiliations = room._affiliations;
95 };
96 room_configs:set(node, data);
97 room._data.history = history;
98 elseif forced then
99 room_configs:set(node, nil);
100 if not next(room._occupants) then -- Room empty
101 rooms[room.jid] = nil;
102 end
103 end
104 if forced then persistent_rooms_storage:set(nil, persistent_rooms); end
105 end
106
107 -- When room is created, over-ride 'save' method
108 module:hook("muc-room-created", function(event)
109 event.room.save = room_save;
110 end);
111
112 -- Automatically destroy empty non-persistent rooms
113 module:hook("muc-occupant-left",function(event)
114 local room = event.room
115 if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room
116 module:fire_event("muc-room-destroyed", { room = room });
117 end
118 end);
119
120 local persistent_errors = false;
121 for jid in pairs(persistent_rooms) do
122 local node = jid_split(jid);
123 local data = room_configs:get(node);
124 if data then
125 local room = create_room(jid);
126 room._data = data._data;
127 room._affiliations = data._affiliations;
128 else -- missing room data
129 persistent_rooms[jid] = nil;
130 module:log("error", "Missing data for room '%s', removing from persistent room list", jid);
131 persistent_errors = true;
132 end
133 end
134 if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end
135 end
121 136
122 module:hook("host-disco-items", function(event) 137 module:hook("host-disco-items", function(event)
123 local reply = event.reply; 138 local reply = event.reply;
124 module:log("debug", "host-disco-items called"); 139 module:log("debug", "host-disco-items called");
125 for jid, room in pairs(rooms) do 140 for jid, room in pairs(rooms) do
131 146
132 module:hook("muc-room-destroyed",function(event) 147 module:hook("muc-room-destroyed",function(event)
133 local room = event.room 148 local room = event.room
134 forget_room(room.jid) 149 forget_room(room.jid)
135 end) 150 end)
136
137 module:hook("muc-occupant-left",function(event)
138 local room = event.room
139 if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room
140 module:fire_event("muc-room-destroyed", { room = room });
141 end
142 end);
143 151
144 -- Watch presence to create rooms 152 -- Watch presence to create rooms
145 local function attempt_room_creation(event) 153 local function attempt_room_creation(event)
146 local origin, stanza = event.origin, event.stanza; 154 local origin, stanza = event.origin, event.stanza;
147 local room_jid = jid_bare(stanza.attr.to); 155 local room_jid = jid_bare(stanza.attr.to);