Comparison

plugins/muc/mod_muc.lua @ 6333:93b8438fe761

plugins/muc/mod_muc: Use map store for room persistence
author daurnimator <quae@daurnimator.com>
date Thu, 07 Aug 2014 12:35:12 -0400
parent 6332:490acb4941ca
child 6334:ba2555e06c7c
comparison
equal deleted inserted replaced
6332:490acb4941ca 6333:93b8438fe761
42 if is_admin(jid) then return nil, "modify", "not-acceptable"; end 42 if is_admin(jid) then return nil, "modify", "not-acceptable"; end
43 return _set_affiliation(self, actor, jid, ...); 43 return _set_affiliation(self, actor, jid, ...);
44 end 44 end
45 end 45 end
46 46
47 local persistent = module:require "muc/persistent";
48 local persistent_rooms_storage = module:open_store("persistent");
49 local persistent_rooms = module:open_store("persistent", "map");
50 local room_configs = module:open_store("config");
51
52 local function room_save(room, forced)
53 local node = jid_split(room.jid);
54 local is_persistent = persistent.get(room);
55 persistent_rooms:set(room.jid, is_persistent);
56 if is_persistent then
57 local history = room._data.history;
58 room._data.history = nil;
59 local data = {
60 jid = room.jid;
61 _data = room._data;
62 _affiliations = room._affiliations;
63 };
64 room_configs:set(node, data);
65 room._data.history = history;
66 elseif forced then
67 room_configs:set(node, nil);
68 if not next(room._occupants) then -- Room empty
69 rooms[room.jid] = nil;
70 end
71 end
72 end
73
74 -- Automatically destroy empty non-persistent rooms
75 module:hook("muc-occupant-left",function(event)
76 local room = event.room
77 if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room
78 module:fire_event("muc-room-destroyed", { room = room });
79 end
80 end);
81
47 function track_room(room) 82 function track_room(room)
48 rooms[room.jid] = room; 83 rooms[room.jid] = room;
84 -- When room is created, over-ride 'save' method
85 room.save = room_save;
86 end
87
88 local function restore_room(jid)
89 local node = jid_split(jid);
90 local data = room_configs:get(node);
91 if data then
92 local room = muclib.new_room(jid);
93 room._data = data._data;
94 room._affiliations = data._affiliations;
95 track_room(room);
96 return room;
97 end
49 end 98 end
50 99
51 function forget_room(jid) 100 function forget_room(jid)
52 rooms[jid] = nil; 101 rooms[jid] = nil;
102 local node = jid_split(room.jid);
103 room_configs:set(node, nil);
104 if persistent.get(room_jid) then
105 persistent_rooms:set(room_jid, nil);
106 end
53 end 107 end
54 108
55 function get_room_from_jid(room_jid) 109 function get_room_from_jid(room_jid)
56 return rooms[room_jid] 110 local room = rooms[room_jid];
111 if room == nil then
112 -- Check if in persistent storage
113 if persistent_rooms:get(room_jid) then
114 room = restore_room(room_jid);
115 if room == nil then
116 module:log("error", "Missing data for room '%s', removing from persistent room list", room_jid);
117 persistent_rooms:set(room_jid, nil);
118 end
119 end
120 end
121 return room
57 end 122 end
58 123
59 function each_room() 124 function each_room()
125 for room_jid in pairs(persistent_rooms_storage:get(nil) or {}) do
126 if rooms[room_jid] == nil then -- Don't restore rooms that already exist
127 local room = restore_room(room_jid);
128 if room == nil then
129 module:log("error", "Missing data for room '%s', omitting from iteration", room_jid);
130 end
131 end
132 end
60 return iterators.values(rooms); 133 return iterators.values(rooms);
61 end
62
63 do -- Persistent rooms
64 local persistent = module:require "muc/persistent";
65 local persistent_rooms_storage = module:open_store("persistent");
66 local persistent_rooms = persistent_rooms_storage:get() or {};
67 local room_configs = module:open_store("config");
68
69 local function room_save(room, forced)
70 local node = jid_split(room.jid);
71 local is_persistent = persistent.get(room);
72 persistent_rooms[room.jid] = is_persistent;
73 if is_persistent then
74 local history = room._data.history;
75 room._data.history = nil;
76 local data = {
77 jid = room.jid;
78 _data = room._data;
79 _affiliations = room._affiliations;
80 };
81 room_configs:set(node, data);
82 room._data.history = history;
83 elseif forced then
84 room_configs:set(node, nil);
85 if not next(room._occupants) then -- Room empty
86 rooms[room.jid] = nil;
87 end
88 end
89 if forced then persistent_rooms_storage:set(nil, persistent_rooms); end
90 end
91
92 -- When room is created, over-ride 'save' method
93 module:hook("muc-room-pre-create", function(event)
94 event.room.save = room_save;
95 end, 1000);
96
97 -- Automatically destroy empty non-persistent rooms
98 module:hook("muc-occupant-left",function(event)
99 local room = event.room
100 if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room
101 module:fire_event("muc-room-destroyed", { room = room });
102 end
103 end);
104
105 local persistent_errors = false;
106 for jid in pairs(persistent_rooms) do
107 local node = jid_split(jid);
108 local data = room_configs:get(node);
109 if data then
110 local room = muclib.new_room(jid);
111 room._data = data._data;
112 room._affiliations = data._affiliations;
113 track_room(room);
114 else -- missing room data
115 persistent_rooms[jid] = nil;
116 module:log("error", "Missing data for room '%s', removing from persistent room list", jid);
117 persistent_errors = true;
118 end
119 end
120 if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end
121 end 134 end
122 135
123 module:hook("host-disco-items", function(event) 136 module:hook("host-disco-items", function(event)
124 local reply = event.reply; 137 local reply = event.reply;
125 module:log("debug", "host-disco-items called"); 138 module:log("debug", "host-disco-items called");