4 local jid_join = require "util.jid".join; |
4 local jid_join = require "util.jid".join; |
5 local set_new = require "util.set".new; |
5 local set_new = require "util.set".new; |
6 local st = require "util.stanza"; |
6 local st = require "util.stanza"; |
7 local calculate_hash = require "util.caps".calculate_hash; |
7 local calculate_hash = require "util.caps".calculate_hash; |
8 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; |
8 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; |
|
9 local cache = require "util.cache"; |
9 local set = require "util.set"; |
10 local set = require "util.set"; |
10 local new_id = require "util.id".medium; |
11 local new_id = require "util.id".medium; |
11 local storagemanager = require "core.storagemanager"; |
12 local storagemanager = require "core.storagemanager"; |
|
13 local usermanager = require "core.usermanager"; |
12 |
14 |
13 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; |
15 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; |
14 local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event"; |
16 local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event"; |
15 local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner"; |
17 local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner"; |
16 |
18 |
17 local lib_pubsub = module:require "pubsub"; |
19 local lib_pubsub = module:require "pubsub"; |
18 |
20 |
19 local empty_set = set_new(); |
21 local empty_set = set_new(); |
20 |
22 |
|
23 -- username -> object passed to module:add_items() |
|
24 local pep_service_items = {}; |
|
25 |
|
26 -- size of caches with full pubsub service objects |
|
27 local service_cache_size = module:get_option_number("pep_service_cache_size", 1000); |
|
28 |
21 -- username -> util.pubsub service object |
29 -- username -> util.pubsub service object |
22 local services = {}; |
30 local services = cache.new(service_cache_size, function (username, _) |
|
31 local item = pep_service_items[username]; |
|
32 pep_service_items[username] = nil; |
|
33 if item then |
|
34 module:remove_item("pep-service", item); |
|
35 end |
|
36 end):table(); |
|
37 |
|
38 -- size of caches with smaller objects |
|
39 local info_cache_size = module:get_option_number("pep_info_cache_size", 10000); |
23 |
40 |
24 -- username -> recipient -> set of nodes |
41 -- username -> recipient -> set of nodes |
25 local recipients = {}; |
42 local recipients = cache.new(info_cache_size):table(); |
26 |
43 |
27 -- caps hash -> set of nodes |
44 -- caps hash -> set of nodes |
28 local hash_map = {}; |
45 local hash_map = cache.new(info_cache_size):table(); |
29 |
46 |
30 local host = module.host; |
47 local host = module.host; |
31 |
48 |
32 local node_config = module:open_store("pep", "map"); |
49 local node_config = module:open_store("pep", "map"); |
33 local known_nodes = module:open_store("pep"); |
50 local known_nodes = module:open_store("pep"); |
48 end |
65 end |
49 end |
66 end |
50 |
67 |
51 function module.save() |
68 function module.save() |
52 return { |
69 return { |
53 services = services; |
|
54 recipients = recipients; |
70 recipients = recipients; |
55 }; |
71 }; |
56 end |
72 end |
57 |
73 |
58 function module.restore(data) |
74 function module.restore(data) |
59 services = data.services; |
|
60 recipients = data.recipients; |
75 recipients = data.recipients; |
61 for username, service in pairs(services) do |
|
62 local user_bare = jid_join(username, host); |
|
63 module:add_item("pep-service", { service = service, jid = user_bare }); |
|
64 end |
|
65 end |
76 end |
66 |
77 |
67 function is_item_stanza(item) |
78 function is_item_stanza(item) |
68 return st.is_stanza(item) and item.attr.xmlns == xmlns_pubsub and item.name == "item" and #item.tags == 1; |
79 return st.is_stanza(item) and item.attr.xmlns == xmlns_pubsub and item.name == "item" and #item.tags == 1; |
69 end |
80 end |
179 end |
190 end |
180 return broadcast_to; |
191 return broadcast_to; |
181 end |
192 end |
182 end |
193 end |
183 |
194 |
|
195 local nobody_service = pubsub.new({ |
|
196 service = pubsub.new({ |
|
197 node_defaults = { |
|
198 ["max_items"] = 1; |
|
199 ["persist_items"] = false; |
|
200 ["access_model"] = "presence"; |
|
201 ["send_last_published_item"] = "on_sub_and_presence"; |
|
202 }; |
|
203 }); |
|
204 }); |
|
205 |
184 function get_pep_service(username) |
206 function get_pep_service(username) |
185 local user_bare = jid_join(username, host); |
207 local user_bare = jid_join(username, host); |
186 local service = services[username]; |
208 local service = services[username]; |
187 if service then |
209 if service then |
188 return service; |
210 return service; |
|
211 end |
|
212 if not usermanager.user_exists(username, host) then |
|
213 return nobody_service; |
189 end |
214 end |
190 module:log("debug", "Creating pubsub service for user %q", username); |
215 module:log("debug", "Creating pubsub service for user %q", username); |
191 service = pubsub.new({ |
216 service = pubsub.new({ |
192 pep_username = username; |
217 pep_username = username; |
193 node_defaults = { |
218 node_defaults = { |
224 normalize_jid = jid_bare; |
249 normalize_jid = jid_bare; |
225 |
250 |
226 check_node_config = check_node_config; |
251 check_node_config = check_node_config; |
227 }); |
252 }); |
228 services[username] = service; |
253 services[username] = service; |
229 module:add_item("pep-service", { service = service, jid = user_bare }); |
254 local item = { service = service, jid = user_bare } |
|
255 pep_service_items[username] = item; |
|
256 module:add_item("pep-service", item); |
230 return service; |
257 return service; |
231 end |
258 end |
232 |
259 |
233 function handle_pubsub_iq(event) |
260 function handle_pubsub_iq(event) |
234 local origin, stanza = event.origin, event.stanza; |
261 local origin, stanza = event.origin, event.stanza; |
457 |
484 |
458 for node, node_obj in pairs(ret) do |
485 for node, node_obj in pairs(ret) do |
459 reply:tag("item", { jid = user_bare, node = node, name = node_obj.config.title }):up(); |
486 reply:tag("item", { jid = user_bare, node = node, name = node_obj.config.title }):up(); |
460 end |
487 end |
461 end); |
488 end); |
|
489 |
|
490 module:hook_global("user-deleted", function(event) |
|
491 if event.host ~= host then return end |
|
492 local username = event.username; |
|
493 local service = services[username]; |
|
494 if not service then return end |
|
495 for node in pairs(service.nodes) do service:delete(node, true); end |
|
496 |
|
497 local item = pep_service_items[username]; |
|
498 pep_service_items[username] = nil; |
|
499 if item then module:remove_item("pep-service", item); end |
|
500 |
|
501 recipients[username] = nil; |
|
502 end); |
|
503 |