comparison mod_groups_muc_bookmarks/mod_groups_muc_bookmarks.lua @ 4861:5fadb991003d

mod_groups_muc_bookmarks: Switch to XEP-0402 Rationale: Look at the diffstat
author Kim Alvefur <zash@zash.se>
date Sat, 08 Jan 2022 02:57:36 +0100
parents 240fa534f586
children 9a8a43d0faed
comparison
equal deleted inserted replaced
4860:4a34ed2bb9a2 4861:5fadb991003d
3 local st = require "util.stanza"; 3 local st = require "util.stanza";
4 4
5 local mod_groups = module:depends("groups_internal") 5 local mod_groups = module:depends("groups_internal")
6 local mod_pep = module:depends("pep") 6 local mod_pep = module:depends("pep")
7 7
8 local PUBSUB_NODE_XEP0048 = "storage:bookmarks"; 8 local XMLNS_BM2 = "urn:xmpp:bookmarks:1";
9 local XMLNS_XEP0048 = "storage:bookmarks";
10 local XMLNS_XEP0060 = "http://jabber.org/protocol/pubsub"; 9 local XMLNS_XEP0060 = "http://jabber.org/protocol/pubsub";
11 10
12 local default_options = { 11 local default_options = {
13 ["persist_items"] = true; 12 ["persist_items"] = true;
13 ["max_items"] = "max";
14 ["send_last_published_item"] = "never";
14 ["access_model"] = "whitelist"; 15 ["access_model"] = "whitelist";
15 }; 16 };
16 17
17 local function get_current_bookmarks(jid, service) 18 local function get_current_bookmarks(jid, service)
18 local ok, id, item = service:get_last_item(PUBSUB_NODE_XEP0048, jid) 19 local ok, items = service:get_items(XMLNS_BM2, jid)
19 if not ok or id == nil then 20 if not ok then return nil, items; end
20 if id == "item-not-found" or id == nil then 21 return items or {};
21 -- return empty
22 return st.stanza("storage", { xmlns = XMLNS_XEP0048 });
23 end
24 return nil, result
25 end
26 -- first item is the actual storage element
27 local hit = item:get_child("storage", XMLNS_XEP0048);
28 if not hit then
29 return nil, "internal-server-error"
30 end
31 return hit
32 end 22 end
33 23
34 local function update_bookmarks(jid, service, storage) 24 local function update_bookmark(jid, service, room, bookmark)
35 local item = st.stanza("item", { xmlns = XMLNS_XEP0060, id = "current" }):add_child(storage) 25 local ok, err = service:publish(XMLNS_BM2, jid, room, bookmark, default_options);
36 module:log("debug", "updating bookmarks with %q", item) 26 if ok then
37 local ok, err = service:publish( 27 module:log("debug", "found existing matching bookmark, updated")
38 PUBSUB_NODE_XEP0048, 28 else
39 jid,
40 "current",
41 item,
42 default_options
43 )
44 if not ok then
45 module:log("error", "failed to update bookmarks: %s", err) 29 module:log("error", "failed to update bookmarks: %s", err)
46 end 30 end
47 end 31 end
48 32
49 local function find_matching_bookmark(storage, room) 33 local function find_matching_bookmark(storage, room)
50 for node in storage:childtags("conference") do 34 return storage[room];
51 if node.attr.jid == room then
52 return node
53 end
54 end
55 return nil
56 end 35 end
57 36
58 local function inject_bookmark(jid, room, autojoin, name) 37 local function inject_bookmark(jid, room, autojoin, name)
59 local pep_service = mod_pep.get_pep_service(jid_split(jid)) 38 local pep_service = mod_pep.get_pep_service(jid_split(jid))
60 39
61 autojoin = autojoin or false and true 40 local current, err = get_current_bookmarks(jid, pep_service);
62 local current = get_current_bookmarks(jid, pep_service) 41 if err then
63 local existing = find_matching_bookmark(current, room) 42 module:log("error", "Could not retrieve existing bookmarks for %s: %s", jid, err);
64 if existing then 43 return;
44 end
45 local found = find_matching_bookmark(current, room)
46 if found then
47 local existing = found:get_child("conference", XMLNS_BM2);
65 if autojoin ~= nil then 48 if autojoin ~= nil then
66 existing.attr.autojoin = autojoin and "true" or "false" 49 existing.attr.autojoin = autojoin and "true" or "false"
67 end 50 end
68 if name ~= nil then 51 if name ~= nil then
69 -- do not change already configured names 52 -- do not change already configured names
70 if not existing.attr.name then 53 if not existing.attr.name then
71 existing.attr.name = name 54 existing.attr.name = name
72 end 55 end
73 end 56 end
74 done = true
75 module:log("debug", "found existing matching bookmark, updated")
76 else 57 else
77 module:log("debug", "no existing bookmark found, adding new") 58 module:log("debug", "no existing bookmark found, adding new")
78 current:tag("conference", { 59 found = st.stanza("item", { xmlns = XMLNS_XEP0060; id = room })
79 name = name, 60 :tag("conference", { xmlns = XMLNS_BM2; name = name; autojoin = autojoin and "true" or "false"; })
80 autojoin = autojoin and "true" or "false",
81 jid = room,
82 xmlns = XMLNS_XEP0048,
83 })
84 end 61 end
85 62
86 update_bookmarks(jid, pep_service, current) 63 update_bookmark(jid, pep_service, current, room, found)
87 end 64 end
88 65
89 local function remove_bookmark(jid, room, autojoin, name) 66 local function remove_bookmark(jid, room, autojoin, name)
90 local pep_service = mod_pep.get_pep_service(jid_split(jid)) 67 local pep_service = mod_pep.get_pep_service(jid_split(jid))
91 68
92 autojoin = autojoin or false and true 69 return pep_service:retract(XMLNS_BM2, jid, room, st.stanza("retract", { id = room }));
93 local current = get_current_bookmarks(jid, pep_service)
94 if not current then
95 return
96 end
97 current:maptags(function (node)
98 if node.attr.xmlns and node.attr.xmlns ~= XMLNS_XEP0048 then
99 return node
100 end
101 if node.name ~= "conference" then
102 return node
103 end
104 if node.attr.jid == room then
105 -- remove matching bookmark
106 return nil
107 end
108 return node
109 end)
110
111 update_bookmarks(jid, pep_service, current)
112 end 70 end
113 71
114 local function handle_user_added(event) 72 local function handle_user_added(event)
115 if not event.group_info.muc_jid then 73 if not event.group_info.muc_jid then
116 module:log("debug", "ignoring user added event on group %s because it has no MUC", event.id) 74 module:log("debug", "ignoring user added event on group %s because it has no MUC", event.id)