examples/disco.lua
author Myhailo Danylenko <isbear@ukrpost.net>
Sat, 21 Mar 2009 14:06:42 +0200
changeset 46 c2210e9b3e34
parent 44 bd66956cd397
child 64 bf7521ed96eb
permissions -rw-r--r--
Pep in library style


-- SERVICE DISCOVERY (XEP-0030)

-- library

require 'lm'
require 'iq'

-- public

disco = { }

function disco.items ( conn, to, success, fail, node )
	iq.send ( conn, to, 'get',
		{
			query = { xmlns = 'http://jabber.org/protocol/disco#items', node = node }
		},
		function ( mess )
			local item  = mess:child( 'query' ):children ()
			local items = { }
			while item do
				if item:name () == 'item' then
					table.insert ( items, { jid = item:attribute ( 'jid' ), node = item:attribute ( 'node' ), name = item:attribute ( 'name' ) } )
				end
				item = item:next ()
			end
			success ( items )
		end,
		fail )
end

function disco.info ( conn, to, success, fail )
	iq.send ( conn, to, 'get',
		{
			query = { xmlns='http://jabber.org/protocol/disco#info' }
		},
		function ( mess )
			local identities = { }
			local features   = { }
			local item       = mess:child( 'query' ):children ()
			while item do
				local name  = item:name ()
				if name == 'identity' then
					table.insert ( identities, { category = item:attribute ( 'category' ), type = item:attribute ( 'type' ), name = item:attribute ( 'name' ) } )
				elseif name == 'feature' then
					table.insert ( features, item:attribute ( 'var' ) )
				end
				item = item:next ()
			end
			success ( identities, features )
		end,
		fail )
end

-- mcabber

main.command ( 'disco',
	function ( args )
		local who
		local conn = lm.connection.bless ( main.connection () )
		if args.t then
			who = args.t
		else
			who = main.full_jid ()
		end
		if args[1] == 'items' then
			local node = args[2]
			disco.items ( conn, who,
				function ( items )
					local text = ''
					for index, item in ipairs ( items ) do
						text = text .. ("\n    [%s (%s)] %s"):format ( item.jid or '', item.node or '', item.name or '' )
					end
					if text ~= '' then
						main.print_info ( who, ("Items service discovery result for %s (%s):%s"):format ( who, node or '', text ) )
					else
						main.print_info ( who, ("No items in discovery result for %s (%s)"):format ( who, node or '' ) )
					end
				end,
				function ( mesg )
					main.print_info ( who, ("Items service discovery for %s (%s) failed: %s"):format ( who, node or '', mesg ) )
				end, node )
		else
			disco.info ( conn, who,
				function ( identities, features )
					main.print_info ( who, ("Service info discovery result for %s:"):format ( who ) )
					local text = ''
					for index, identity in ipairs ( identities ) do
						text = text .. ("\n    [%s (%s)] %s"):format ( identity.category or '', identity.type or '', identity.name or '' )
					end
					if text ~= '' then
						main.print_info ( who, "  Identities:" .. text )
					else
						main.print_info ( who, "  No identities" )
					end
					text = ''
					for index, feature in ipairs ( features ) do
						text = text .. ("\n    [%s]"):format ( feature or '' )
					end
					if text ~= '' then
						main.print_info ( who, "  Features:" .. text )
					else
						main.print_info ( who, "  No features" )
					end
				end,
				function ( mesg )
					main.print_info ( who, ("Info service discovery for %s failed: %s"):format ( who, mesg ) )
				end )
		end
	end, true, 'jid' )

commands_help['disco'] = "[-t target_jid] [info | items] [node]\n\nService discovery request.\nInfo is sent if omitted."

-- vim: se ts=4: --