plugins/mod_bookmarks.lua
changeset 12174 750abaf99baf
parent 12160 17cffaa78f48
child 12175 b2923a3b4e02
equal deleted inserted replaced
12173:866d06644956 12174:750abaf99baf
    10 local private_storage = module:open_store("private", "map");
    10 local private_storage = module:open_store("private", "map");
    11 
    11 
    12 local namespace = "urn:xmpp:bookmarks:1";
    12 local namespace = "urn:xmpp:bookmarks:1";
    13 local namespace_private = "jabber:iq:private";
    13 local namespace_private = "jabber:iq:private";
    14 local namespace_legacy = "storage:bookmarks";
    14 local namespace_legacy = "storage:bookmarks";
       
    15 local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
    15 
    16 
    16 local default_options = {
    17 local default_options = {
    17 	["persist_items"] = true;
    18 	["persist_items"] = true;
    18 	["max_items"] = "max";
    19 	["max_items"] = "max";
    19 	["send_last_published_item"] = "never";
    20 	["send_last_published_item"] = "never";
    22 
    23 
    23 module:hook("account-disco-info", function (event)
    24 module:hook("account-disco-info", function (event)
    24 	-- This Time it’s Serious!
    25 	-- This Time it’s Serious!
    25 	event.reply:tag("feature", { var = namespace.."#compat" }):up();
    26 	event.reply:tag("feature", { var = namespace.."#compat" }):up();
    26 	event.reply:tag("feature", { var = namespace.."#compat-pep" }):up();
    27 	event.reply:tag("feature", { var = namespace.."#compat-pep" }):up();
       
    28 
       
    29 	-- COMPAT XEP-0411
       
    30 	event.reply:tag("feature", { var = "urn:xmpp:bookmarks-conversion:0" }):up();
    27 end);
    31 end);
    28 
    32 
    29 -- This must be declared on the domain JID, not the account JID.  Note that
    33 -- This must be declared on the domain JID, not the account JID.  Note that
    30 -- this isn’t defined in the XEP.
    34 -- this isn’t defined in the XEP.
    31 module:add_feature(namespace_private);
    35 module:add_feature(namespace_private);
       
    36 
    32 
    37 
    33 local function generate_legacy_storage(items)
    38 local function generate_legacy_storage(items)
    34 	local storage = st.stanza("storage", { xmlns = namespace_legacy });
    39 	local storage = st.stanza("storage", { xmlns = namespace_legacy });
    35 	for _, item_id in ipairs(items) do
    40 	for _, item_id in ipairs(items) do
    36 		local item = items[item_id];
    41 		local item = items[item_id];
   415 	end
   420 	end
   416 end, 1);
   421 end, 1);
   417 if module:get_option_boolean("upgrade_legacy_bookmarks", true) then
   422 if module:get_option_boolean("upgrade_legacy_bookmarks", true) then
   418 	module:hook("resource-bind", migrate_legacy_bookmarks);
   423 	module:hook("resource-bind", migrate_legacy_bookmarks);
   419 end
   424 end
       
   425 -- COMPAT XEP-0411 Broadcast as per XEP-0048 + PEP
       
   426 local function legacy_broadcast(event)
       
   427 	local service = event.service;
       
   428 	local ok, bookmarks = service:get_items(namespace, event.actor);
       
   429 	if bookmarks == "item-not-found" then ok, bookmarks = true, {} end
       
   430 	if not ok then return end
       
   431 	local legacy_bookmarks_item = st.stanza("item", { xmlns = xmlns_pubsub; id = "current" })
       
   432 		:add_child(generate_legacy_storage(bookmarks));
       
   433 	-- FIXME This broadcasts to any and all contacts who sent +notify because the node does not exist, so defaults apply.
       
   434 	service:broadcast("items", namespace_legacy, { --[[ no subscribers ]] }, legacy_bookmarks_item, event.actor);
       
   435 end
       
   436 local function broadcast_legacy_removal(event)
       
   437 	if event.node ~= namespace then return end
       
   438 	return legacy_broadcast(event);
       
   439 end
       
   440 module:hook("presence/initial", function (event)
       
   441 	-- Broadcasts to all clients with legacy+notify, not just the one coming online.
       
   442 	-- Upgrade to XEP-0402 to avoid it
       
   443 	local service = mod_pep.get_pep_service(event.origin.username);
       
   444 	legacy_broadcast({ service = service, actor = event.origin.full_jid });
       
   445 end);
   420 module:handle_items("pep-service", function (event)
   446 module:handle_items("pep-service", function (event)
   421 	local service = event.item.service;
   447 	local service = event.item.service;
   422 	module:hook_object_event(service.events, "node-created", on_node_created);
   448 	module:hook_object_event(service.events, "node-created", on_node_created);
       
   449 	module:hook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast);
       
   450 	module:hook_object_event(service.events, "item-retracted", broadcast_legacy_removal);
       
   451 	module:hook_object_event(service.events, "node-purged", broadcast_legacy_removal);
       
   452 	module:hook_object_event(service.events, "node-deleted", broadcast_legacy_removal);
   423 end, function (event)
   453 end, function (event)
   424 	local service = event.item.service;
   454 	local service = event.item.service;
   425 	module:unhook_object_event(service.events, "node-created", on_node_created);
   455 	module:unhook_object_event(service.events, "node-created", on_node_created);
       
   456 	module:unhook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast);
       
   457 	module:unhook_object_event(service.events, "item-retracted", broadcast_legacy_removal);
       
   458 	module:unhook_object_event(service.events, "node-purged", broadcast_legacy_removal);
       
   459 	module:unhook_object_event(service.events, "node-deleted", broadcast_legacy_removal);
   426 end, true);
   460 end, true);