examples/xep0004.lua
author Myhailo Danylenko <isbear@ukrpost.net>
Mon, 16 Mar 2009 18:54:16 +0200
changeset 34 8206d7cb1447
parent 27 92b254b64360
permissions -rw-r--r--
Args auto-parsing, use main.binding


forms = { }
form_cid = main.add_category { 'del', 'send' }

function insert_form ( form )
	table.insert ( forms, form )
	main.add_completion ( form_cid, tostring(#forms) )
	return #forms
end

-- expects lm node   x = { xmlns = 'jabber:x:data', type = 'form', ... }
-- returns form index in forms table, you can do whatever you want to upper level table, except exp and val fields.
function parse_form ( node )
	local form = { title = 'unknown', exp = '', val = { } }
	if node:child ( 'title' ) then
		form.title = node:child( 'title' ):value ()
	end
	if node:child ( 'instructions' ) then
		form.exp = form.exp .. 'Instructions: ' .. node:child( 'instructions' ):value () .. '\n'
	end
	form.exp = form.exp .. 'Fields:\n'
	local field = node:children ()
	while field do
		if field:name () == 'field' then
			local field_type  = field:attribute ( 'type' ) or 'text-single'
			local field_var   = field:attribute ( 'var' ) or ''
			form.exp = form.exp .. ' - ' .. field_var .. '\n   Type: ' .. field_type .. '\n'
			if field:attribute ( 'label' ) then
				form.exp = form.exp .. '   Label: ' .. ( field:attribute ( 'label' ) or '' ) .. '\n'
			end
			if field:child ( 'desc' ) then
				form.exp = form.exp .. '   Description: ' .. field:child( 'desc' ):value () .. '\n'
			end
			if field:child ( 'required' ) then
				form.exp = form.exp .. '   Required: yes\n'
			end

			local field_value
			if field_type == 'jid-multi' or field_type == 'list-multi' or field_type == 'text-multi' then
				field_value = { }
				local value = field:children ()
				form.exp = form.exp .. '   Default values:\n'
				while value do
					if value:name () == 'value' then
						table.insert ( field_value, { value:value () } )
						form.exp = form.exp .. '    - ' .. value:value () .. '\n'
					end
					value = value:next ()
				end
			else
				if field:child ( 'value' ) then
					field_value = field:child( 'value' ):value ()
					form.exp = form.exp .. '   Default value: ' .. (field_value or '') .. '\n'
				end
			end

			if field_type == 'list-single' or field_type == 'list-multi' then
				form.exp = form.exp .. '   List options:\n'
				local option = field:children ()
				while option do
					if option:name () == 'option' then
						form.exp = form.exp .. '    - ' .. ( option:child( 'value' ):value () or '' ) .. ': ' .. ( option:attribute ( 'label' ) or '' ) .. '\n'
					end
					option = option:next ()
				end
			end

			if field_type == 'boolean' then
				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '0' } } )
			elseif field_type == 'fixed' then
			elseif field_type == 'hidden' then
				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
			elseif field_type == 'list-single' then
				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
			elseif field_type == 'list-multi' then
				table.insert ( form.val, { type = field_type, var = field_var, value = field_value or { } } )
			elseif field_type == 'jid-multi' or field_type == 'text-multi' then
				table.insert ( form.val, { type = field_type, var = field_var, value = field_value or { } } )
			elseif field_type == 'jid-single' or field_type == 'text-single' then
				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
			elseif field_type == 'text-private' then
				table.insert ( form.val, { type = field_type, var = field_var, value = { field_value or '' } } )
			end
		end
		field = field:next ()
	end
	return insert_form ( form )
end

function form_set ( id, name, value )
	if forms[id] then
		for index, field in ipairs ( forms[id].val ) do
			if field.var == name then
				if value == nil then
					field.value = { }
				else
					if field.type == 'jid-multi' or field.type == 'list-multi' or field.type == 'text-multi' then
						table.insert ( field.value, { value } )
					else
						field.value = { value }
					end
				end
			end
		end
	end
end

main.command ( 'form',
	function ( args )
		local action = args[1]
		local id = tonumber (args[1])
		if forms[id] then
			local field = args[2]
			if field then
				local value = args[3]
				if value == 'clear' then
					value = nil
				elseif value == 'set' then
					value = args[4]
				end
				form_set ( id, field, value )
			else
				print ( 'Form: ' .. ( forms[id].title or '' ) .. '\n' .. forms[id].exp )
				local text = 'Fields:'
				for index, field in ipairs ( forms[id].val ) do -- this should not be here, but setting up callback just for this...
					if field.type == 'jid-multi' or field.type == 'list-multi' or field.type == 'text-multi' then
						text = text .. '\n - ' .. field.var .. ' [' .. field.type .. ']:'
						for vin, value in ipairs ( field.value ) do
							text = text .. '\n    * ' .. value[1]
						end
					else
						text = text .. '\n - ' .. field.var .. ' [' .. field.type .. ']: ' .. field.value[1]
					end
				end
				print ( text )
			end
		elseif action == 'del' then
			forms[tonumber(args[2])] = nil
			main.del_completion ( form_cid, tostring(args[2]) )
		elseif action == 'send' then
			local form = forms[tonumber(args[2])]
			if form then
				form.send ( form )
			end
		else
			local text = ''
			for id, form in pairs ( forms ) do
				text = text .. '\n - ' .. id .. ' ' .. form.title .. ' [' .. ( form.status or 'unknown' ) .. ']'
			end
			if text ~= '' then
				print ( 'Forms list:' .. text )
			else
				print ( 'No forms' )
			end
		end
	end, true, form_cid )

commands_help['form'] = "[del form_id | send form_id | form_id [field_name {clear | [set] value}]\n\nWith bare form id prints info on that form.\nWith field name sets or clears field value. Set subcommand is optional, just to allow values, starting with 'clear'.\nWithout arguments prints form list."

-- vim: se ts=4: --