diff options
Diffstat (limited to 'plugins/mod_pubsub/mod_pubsub.lua')
-rw-r--r-- | plugins/mod_pubsub/mod_pubsub.lua | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua index 8e7bfc53..5b01d1d1 100644 --- a/plugins/mod_pubsub/mod_pubsub.lua +++ b/plugins/mod_pubsub/mod_pubsub.lua @@ -2,6 +2,7 @@ local pubsub = require "util.pubsub"; local st = require "util.stanza"; local jid_bare = require "util.jid".bare; local usermanager = require "core.usermanager"; +local new_id = require "util.id".medium; local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event"; @@ -15,29 +16,23 @@ local expose_publisher = module:get_option_boolean("expose_publisher", false) local service; local lib_pubsub = module:require "pubsub"; -local handlers = lib_pubsub.handlers; -local pubsub_error_reply = lib_pubsub.pubsub_error_reply; module:depends("disco"); module:add_identity("pubsub", "service", pubsub_disco_name); module:add_feature("http://jabber.org/protocol/pubsub"); function handle_pubsub_iq(event) - local origin, stanza = event.origin, event.stanza; - local pubsub = stanza.tags[1]; - local action = pubsub.tags[1]; - if not action then - origin.send(st.error_reply(stanza, "cancel", "bad-request")); - return true; - end - local handler = handlers[stanza.attr.type.."_"..action.name]; - if handler then - handler(origin, stanza, action, service); - return true; - end + return lib_pubsub.handle_pubsub_iq(event, service); +end + +local node_store = module:open_store(module.name.."_nodes"); + +local function create_simple_itemstore(node_config, node_name) + local archive = module:open_store("pubsub_"..node_name, "archive"); + return lib_pubsub.archive_itemstore(archive, node_config, nil, node_name); end -function simple_broadcast(kind, node, jids, item, actor) +function simple_broadcast(kind, node, jids, item, actor, node_obj) if item then item = st.clone(item); item.attr.xmlns = nil; -- Clear the pubsub namespace @@ -45,77 +40,75 @@ function simple_broadcast(kind, node, jids, item, actor) item.attr.publisher = actor end end - local message = st.message({ from = module.host, type = "headline" }) + + local id = new_id(); + local msg_type = node_obj and node_obj.config.message_type or "headline"; + local message = st.message({ from = module.host, type = msg_type, id = id }) :tag("event", { xmlns = xmlns_pubsub_event }) :tag(kind, { node = node }) - :add_child(item); - for jid in pairs(jids) do - module:log("debug", "Sending notification to %s", jid); - message.attr.to = jid; - module:send(message); + + if item then + message:add_child(item); end -end -module:hook("iq/host/"..xmlns_pubsub..":pubsub", handle_pubsub_iq); -module:hook("iq/host/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq); + local summary; + -- Compose a sensible textual representation of at least Atom payloads + if item and item.tags[1] then + local payload = item.tags[1]; + summary = module:fire_event("pubsub-summary/"..payload.attr.xmlns, { + kind = kind, node = node, jids = jids, actor = actor, item = item, payload = payload, + }); + end -local feature_map = { - create = { "create-nodes", "instant-nodes", "item-ids" }; - retract = { "delete-items", "retract-items" }; - purge = { "purge-nodes" }; - publish = { "publish", autocreate_on_publish and "auto-create" }; - delete = { "delete-nodes" }; - get_items = { "retrieve-items" }; - add_subscription = { "subscribe" }; - get_subscriptions = { "retrieve-subscriptions" }; - set_configure = { "config-node" }; - get_default = { "retrieve-default" }; -}; - -local function add_disco_features_from_service(service) - for method, features in pairs(feature_map) do - if service[method] then - for _, feature in ipairs(features) do - if feature then - module:add_feature(xmlns_pubsub.."#"..feature); - end - end + for jid, options in pairs(jids) do + local new_stanza = st.clone(message); + if summary and type(options) == "table" and options["pubsub#include_body"] then + new_stanza:body(summary); end + new_stanza.attr.to = jid; + module:send(new_stanza); end - for affiliation in pairs(service.config.capabilities) do - if affiliation ~= "none" and affiliation ~= "owner" then - module:add_feature(xmlns_pubsub.."#"..affiliation.."-affiliation"); +end + +function is_item_stanza(item) + return st.is_stanza(item) and item.attr.xmlns == xmlns_pubsub and item.name == "item"; +end + +module:hook("pubsub-summary/http://www.w3.org/2005/Atom", function (event) + local payload = event.item; + local title = payload:get_child_text("title"); + local summary = payload:get_child_text("summary"); + if not summary and title then + local author = payload:find("author/name#"); + summary = title; + if author then + summary = author .. " posted " .. summary; end end + return summary; +end); + +module:hook("iq/host/"..xmlns_pubsub..":pubsub", handle_pubsub_iq); +module:hook("iq/host/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq); + +local function add_disco_features_from_service(service) --luacheck: ignore 431/service + for feature in lib_pubsub.get_feature_set(service) do + module:add_feature(xmlns_pubsub.."#"..feature); + end end module:hook("host-disco-info-node", function (event) - local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node; - local ok, ret = service:get_nodes(stanza.attr.from); - if not ok or not ret[node] then - return; - end - event.exists = true; - reply:tag("identity", { category = "pubsub", type = "leaf" }); + return lib_pubsub.handle_disco_info_node(event, service); end); module:hook("host-disco-items-node", function (event) - local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node; - local ok, ret = service:get_items(node, stanza.attr.from); - if not ok then - return; - end - - for _, id in ipairs(ret) do - reply:tag("item", { jid = module.host, name = id }):up(); - end - event.exists = true; + return lib_pubsub.handle_disco_items_node(event, service); end); module:hook("host-disco-items", function (event) - local stanza, origin, reply = event.stanza, event.origin, event.reply; - local ok, ret = service:get_nodes(event.stanza.attr.from); + local stanza, reply = event.stanza, event.reply; + local ok, ret = service:get_nodes(stanza.attr.from); if not ok then return; end @@ -225,7 +218,10 @@ function module.load() autocreate_on_publish = autocreate_on_publish; autocreate_on_subscribe = autocreate_on_subscribe; + nodestore = node_store; + itemstore = create_simple_itemstore; broadcaster = simple_broadcast; + itemcheck = is_item_stanza; get_affiliation = get_affiliation; normalize_jid = jid_bare; |