|
@@ -5,13 +5,20 @@ local neturl = require "net.url";
|
5
|
5
|
local parse = neturl.parseQuery;
|
6
|
6
|
local st = require "util.stanza";
|
7
|
7
|
local get_room_from_jid = module:require "util".get_room_from_jid;
|
|
8
|
+local timer = require "util.timer";
|
8
|
9
|
|
9
|
10
|
-- Options
|
10
|
11
|
local poltergeist_component
|
11
|
12
|
= module:get_option_string("poltergeist_component", module.host);
|
|
13
|
+-- defaults to 3 min
|
|
14
|
+local poltergeist_timeout
|
|
15
|
+ = module:get_option_string("poltergeist_leave_timeout", 180);
|
12
|
16
|
|
13
|
17
|
-- table to store all poltergeists we create
|
14
|
18
|
local poltergeists = {};
|
|
19
|
+-- table to mark that outgoing unavailable presences
|
|
20
|
+-- should be marked with ignore
|
|
21
|
+local poltergeists_pr_ignore = {};
|
15
|
22
|
|
16
|
23
|
-- poltergaist management functions
|
17
|
24
|
|
|
@@ -88,7 +95,7 @@ prosody.events.add_handler("pre-jitsi-authentication", function(session)
|
88
|
95
|
-- we will mark it with ignore tag
|
89
|
96
|
local nick = string.sub(username, 0, 8);
|
90
|
97
|
if (have_poltergeist_occupant(room, nick)) then
|
91
|
|
- remove_poltergeist_occupant(room, nick);
|
|
98
|
+ remove_poltergeist_occupant(room, nick, true);
|
92
|
99
|
end
|
93
|
100
|
|
94
|
101
|
return username;
|
|
@@ -121,17 +128,28 @@ function create_poltergeist_occupant(room, nick, name, avatar)
|
121
|
128
|
|
122
|
129
|
room:handle_first_presence(
|
123
|
130
|
prosody.hosts[poltergeist_component], join_presence);
|
|
131
|
+
|
|
132
|
+ timer.add_task(poltergeist_timeout,
|
|
133
|
+ function ()
|
|
134
|
+ if (have_poltergeist_occupant(room, nick)) then
|
|
135
|
+ remove_poltergeist_occupant(room, nick, false);
|
|
136
|
+ end
|
|
137
|
+ end);
|
124
|
138
|
end
|
125
|
139
|
|
126
|
140
|
-- Removes poltergeist occupant
|
127
|
141
|
-- @param room the room instance where to remove the occupant
|
128
|
142
|
-- @param nick the nick of the occupant to remove
|
129
|
|
-function remove_poltergeist_occupant(room, nick)
|
|
143
|
+-- @param ignore to mark the poltergeist unavailble presence to be ignored
|
|
144
|
+function remove_poltergeist_occupant(room, nick, ignore)
|
130
|
145
|
log("debug", "remove_poltergeist_occupant %s", nick);
|
131
|
146
|
local leave_presence = st.presence({
|
132
|
147
|
to = room.jid.."/"..nick,
|
133
|
148
|
from = poltergeist_component.."/"..nick,
|
134
|
149
|
type = "unavailable" });
|
|
150
|
+ if (ignore) then
|
|
151
|
+ poltergeists_pr_ignore[room.jid.."/"..nick] = true;
|
|
152
|
+ end
|
135
|
153
|
room:handle_normal_presence(
|
136
|
154
|
prosody.hosts[poltergeist_component], leave_presence);
|
137
|
155
|
end
|
|
@@ -150,7 +168,7 @@ end
|
150
|
168
|
--- Note: mod_muc and some of its sub-modules add event handlers between 0 and -100,
|
151
|
169
|
--- e.g. to check for banned users, etc.. Hence adding these handlers at priority -100.
|
152
|
170
|
module:hook("muc-decline", function (event)
|
153
|
|
- remove_poltergeist_occupant(event.room, bare(event.stanza.attr.from));
|
|
171
|
+ remove_poltergeist_occupant(event.room, bare(event.stanza.attr.from), false);
|
154
|
172
|
end, -100);
|
155
|
173
|
-- before sending the presence for a poltergeist leaving add ignore tag
|
156
|
174
|
-- as poltergeist is leaving just before the real user joins and in the client
|
|
@@ -158,9 +176,11 @@ end, -100);
|
158
|
176
|
-- user will reuse all currently created UI components for the same nick
|
159
|
177
|
module:hook("muc-broadcast-presence", function (event)
|
160
|
178
|
if (bare(event.occupant.jid) == poltergeist_component) then
|
161
|
|
- if(event.stanza.attr.type == "unavailable") then
|
|
179
|
+ if(event.stanza.attr.type == "unavailable"
|
|
180
|
+ and poltergeists_pr_ignore[event.occupant.nick]) then
|
162
|
181
|
event.stanza:tag(
|
163
|
182
|
"ignore", { xmlns = "http://jitsi.org/jitmeet/" }):up();
|
|
183
|
+ poltergeists_pr_ignore[event.occupant.nick] = nil;
|
164
|
184
|
end
|
165
|
185
|
end
|
166
|
186
|
end, -100);
|
|
@@ -235,6 +255,39 @@ function handle_update_poltergeist (event)
|
235
|
255
|
end
|
236
|
256
|
end
|
237
|
257
|
|
|
258
|
+--- Handles remove poltergeists
|
|
259
|
+-- @param event the http event, holds the request query
|
|
260
|
+-- @return GET response, containing a json with response details
|
|
261
|
+function handle_remove_poltergeist (event)
|
|
262
|
+ if (not event.request.url.query) then
|
|
263
|
+ return 400;
|
|
264
|
+ end
|
|
265
|
+
|
|
266
|
+ local params = parse(event.request.url.query);
|
|
267
|
+ local user_id = params["user"];
|
|
268
|
+ local room_name = params["room"];
|
|
269
|
+ local group = params["group"];
|
|
270
|
+
|
|
271
|
+ local room = get_room(room_name, group);
|
|
272
|
+ if (not room) then
|
|
273
|
+ log("error", "no room found %s", room_name);
|
|
274
|
+ return 404;
|
|
275
|
+ end
|
|
276
|
+
|
|
277
|
+ local username = get_username(room, user_id);
|
|
278
|
+ if (not username) then
|
|
279
|
+ return 404;
|
|
280
|
+ end
|
|
281
|
+
|
|
282
|
+ local nick = string.sub(username, 0, 8);
|
|
283
|
+ if (have_poltergeist_occupant(room, nick)) then
|
|
284
|
+ remove_poltergeist_occupant(room, nick, false);
|
|
285
|
+ return 200;
|
|
286
|
+ else
|
|
287
|
+ return 404;
|
|
288
|
+ end
|
|
289
|
+end
|
|
290
|
+
|
238
|
291
|
|
239
|
292
|
log("info", "Loading poltergeist service");
|
240
|
293
|
module:depends("http");
|
|
@@ -244,5 +297,6 @@ module:provides("http", {
|
244
|
297
|
route = {
|
245
|
298
|
["GET /poltergeist/create"] = handle_create_poltergeist;
|
246
|
299
|
["GET /poltergeist/update"] = handle_update_poltergeist;
|
|
300
|
+ ["GET /poltergeist/remove"] = handle_remove_poltergeist;
|
247
|
301
|
};
|
248
|
302
|
});
|