examples/remote.lua
author Myhailo Danylenko <isbear@ukrpost.net>
Sun, 22 Mar 2009 04:14:36 +0200
changeset 49 95f3bf77c598
parent 44 bd66956cd397
child 51 a95a3a73482c
permissions -rw-r--r--
Forms in modular way


-- REMOTE CONTROLLING CLIENTS (XEP-0146)

-- library

require 'lm'
require 'iq'
require 'x_data'
require 'disco'

-- public

remote = { }

function remote.list ( conn, to, success, fail )
	disco.items ( conn, to, success, fail, 'http://jabber.org/protocol/commands' )
end

function remote.command ( conn, to, command, success, fail )
	iq.send ( conn, to, 'set',
		{
			command = { xmlns = 'http://jabber.org/protocol/commands', action = 'execute', node = command },
		},
		function ( mess )
			local c = mess:child ( 'command' )
			if c then
				local status = c:attribute ( 'status' )
				if status == 'completed' then
					success ()
				else
					local x = c:child ( 'x' )
					if x then
						local sid = c:attribute ( 'sessionid' )
						success ( x_data.parse ( x ),
							function ( form, success, fail )
								form.type = 'submit' -- XXX in standard there is 'form' :/
								iq.send ( conn, to, 'set',
									{
										command = form.format ( form, { xmlns = 'http://jabber.org/protocol/commands', node = command, sessionid = sid } )
									},
									function ( mess )
										local c = mess:child ( 'command' )
										if c and c:attribute ( 'status' ) == 'completed' then
											success ()
										else
											fail ( mess:xml () ) -- XXX more forms?
										end
									end, fail )
							end,
							function ( form, success, fail )
								success ()
							end )
					else
						fail ( mess:xml () ) -- XXX
					end
				end
			end
		end, fail )
end

-- mcabber

main.command ( 'remote',
	function ( args )
		local who
		if args.t then
			who = args.t
		else
			who = main.full_jid ()
		end
		local action = args[1]
		local conn   = lm.connection.bless ( main.connection () )
		if action then
			remote.command ( conn, who, action,
				function ( form, submit, reject )
					if not form then
						main.print_info ( who, ('Command %s completed'):format ( action ) )
					else
						local id = #forms + 1
						forms[id] = {
							form = form,
							submit =
								function ( form )
									submit ( form,
										function ()
											main.print_info ( who, ('Command %s completed'):format ( action ) )
										end,
										function ( mesg )
											main.print_info ( who, ('Command %s execution failed: %s'):format ( action, mesg ) )
										end )
								end,
							reject =
								function ( form )
									reject ( form,
										function ()
											main.print_info ( who, ('Command %s execution cancelled'):format ( action ) )
										end,
										function ( mesg )
											main.print_info ( who, ('Command %s execution cancellation failed: %s'):format ( action, mesg ) )
										end )
								end,
						}
						print ( 'You have new form ' .. id )
					end
				end,
				function ( mesg )
					main.print_info ( who, ('Command %s execution failed: %s'):format ( action, mesg ) )
				end )
		else
			remote.list ( conn, who,
				function ( items )
					local text = ''
					for index, item in ipairs ( items ) do
						text = text .. '\n - ' .. item.node
					end
					if text ~= '' then
						main.print_info ( who, 'Available commands:' .. text )
					else
						main.print_info ( who, 'No commands available.' )
					end
				end,
				function ( mesg )
					main.print_info ( who, ("Remote commands list for %s failed: %s"):format ( who, mesg ) )
				end )
		end
	end, true, 'jid' )

commands_help['remote'] = "[-t target_jid] [remote_command]\n\nPrints list of available remote command or requests execution of specified command."

-- vim: se ts=4: --