examples/lm/pubsub.lua
changeset 68 742878c74b8e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/lm/pubsub.lua	Tue Mar 31 18:35:34 2009 +0300
@@ -0,0 +1,222 @@
+
+-- PUBLISH-SUBSCRIBE (BEP-0060)
+
+-- library
+
+local iq     = require 'lm.iq'
+local x_data = require 'lm.x_data'
+
+--
+
+local O = {
+	handlers = { },
+}
+
+local F = { }
+
+function F.handler ( xmlns, handler )
+	O.handlers[xmlns] = handler
+end
+
+function F.message_handler ( conn, mess )
+	local e = mess:child ( 'event' )
+	if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/pubsub#event' then
+		local is = e:child ( 'items' )
+		if is then
+			local from = mess:attribute ( 'from' )
+			local node = is:attribute ( 'node' )
+			local item = is:child ()
+			while item do
+				local id = item:attribute ( 'id' )
+				local n  = item:child ()
+				while n do
+					local xmlns = n:attribute ( 'xmlns' )
+					if O.handlers[xmlns] then
+						O.handlers[xmlns] ( from, node, n, id )
+					end
+					n = n:next ()
+				end
+				item = item:next ()
+			end
+			return true
+		end
+	end
+	return false
+end
+
+-- SUBSCRIBER USE CASES
+
+function F.subscribe ( conn, to, node, success, fail )
+	local jid = conn:jid():gsub ( '/.*', '' )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
+				subscribe = { node = node, jid = jid },
+			},
+		},
+		function ( mess )
+			local s = mess:path ( 'pubsub', 'subscription' )
+			if s then
+				success ( s:attribute ( 'subid' ) )
+			else
+				success ()
+			end
+		end,
+		fail )
+end
+
+function F.unsubscribe ( conn, to, node, success, fail )
+	local jid = conn:jid():gsub ( '/.*', '' )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
+				unsubscribe = { node = node, jid = jid },
+			},
+		}, success, fail )
+end
+
+-- I found no servers with subscription options support thus it is not implemented.
+
+-- untested :(
+function F.retrieve ( conn, to, node, success, fail, max, ids )
+	local items = { node = node, max_items = max }
+	if ids then
+		items.item = { }
+		for k, id in pairs ( ids ) do
+			table.insert ( items.item, { id = id } )
+		end
+	end
+	iq.send ( conn, to, 'get',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
+				items = items,
+			},
+		},
+		function ( mess )
+			local items = mess:path ( 'pubsub', 'items' )
+			if items then
+				local from = mess:attribute ( 'from' )
+				local node = items:attribute ( 'node' )
+				local item = items:child ()
+				while item do
+					success ( from, node, item ) -- XXX use registered xmlns handlers for that?
+					item = item:next ()
+				end
+			else
+				-- XXX
+			end
+		end, fail )
+end
+
+-- OWNER USE CASES
+
+-- node may be nil
+function F.create_node ( conn, to, node, success, fail )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub',
+				create = { node = node },
+			},
+		},
+		function ( mess )
+			if node then
+				success ()
+			else
+				local create = mess:path ( 'pubsub', 'create' )
+				if create then
+					success ( create:attribute ( 'node' ) )
+				else
+					success ()
+				end
+			end
+		end, fail )
+end
+
+function F.delete_node ( conn, to, node, success, fail )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+				delete = { node = node },
+			},
+		}, success, fail )
+end
+
+function F.purge_node ( conn, to, node, success, fail )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+				purge = { node = node },
+			},
+		}, success, fail )
+end
+
+function F.configure_node ( conn, to, node, success, fail )
+	iq.send ( conn, to, 'get',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+				configure = { node = node },
+			},
+		},
+		function ( mess )
+			local x = mess:path ( 'pubsub', 'configure', 'x' )
+			if x then
+				success ( x_data.parse ( x ),
+					function ( form, success, fail )
+						iq.send ( conn, to, 'set',
+							{
+								pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+									configure = form:format ( { node = node }, 'submit' ),
+								},
+							}, success, fail )
+					end,
+					function ( form, success, fail )
+						iq.send ( conn, to, 'set',
+							{
+								pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+									configure = form:format ( { node = node }, 'cancel' ),
+								},
+							}, success, fail )
+					end )
+			else
+				fail ( mess:xml () ) -- XXX
+			end
+		end, fail )
+end
+
+function F.list_subscriptions ( conn, to, node, success, fail )
+	iq.send ( conn, to, 'get',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+				subscriptions = { node = node },
+			},
+		},
+		function ( mess )
+			local s = mess:path ( 'pubsub', 'subscriptions' )
+			if s then
+				local sub = s:child ()
+				local ret = { }
+				while sub do
+					table.insert ( ret, { jid = sub:attribute ( 'jid' ), subscription = sub:attribute ( 'subscription' ), subid = sub:attribute ( 'subid' ) } )
+					sub = sub:next ()
+				end
+				success ( ret )
+			else
+				fail ( mess:xml () ) -- XXX
+			end
+		end, fail )
+end
+
+function F.modify_subscription ( conn, to, node, jid, state, success, fail, id )
+	iq.send ( conn, to, 'set',
+		{
+			pubsub = { xmlns = 'http://jabber.org/protocol/pubsub#owner',
+				subscriptions = { node = node,
+					subscription = { jid = jid, subscription = state, id = id },
+				},
+			},
+		}, success, fail )
+end
+
+return F
+
+-- vim: se ts=4: --