author | Myhailo Danylenko <isbear@ukrpost.net> |
Fri, 27 Mar 2009 12:06:19 +0200 | |
changeset 66 | 542f61e113cb |
parent 60 | b9fd051c0d7c |
child 67 | d33ca5572e91 |
permissions | -rw-r--r-- |
49 | 1 |
|
2 |
-- DATA FORMS (XEP-0004) |
|
3 |
||
4 |
-- library |
|
5 |
||
66 | 6 |
local lm = require 'lm' |
49 | 7 |
|
8 |
-- public |
|
9 |
||
10 |
x_data = { } |
|
11 |
||
12 |
-- iq_register should encapsulate x_data in results, so, looks like we need callbacks again? |
|
13 |
-- though, it can redefine method... but it is not too pretty. for now it will be so. |
|
14 |
||
15 |
-- result needs separate routine? (reported & item's) |
|
16 |
||
17 |
function x_data.format ( form, root ) |
|
18 |
root.x = { xmlns = 'jabber:x:data', type = form.type } |
|
19 |
local fields = { } |
|
20 |
for i, field in ipairs ( form ) do |
|
21 |
if field.type ~= 'fixed' then |
|
22 |
local value |
|
23 |
if field.type == 'list-multi' or field.type == 'text-multi' or field.type == 'jid-multi' then |
|
24 |
value = { } |
|
25 |
for j, v in ipairs ( field.value ) do |
|
26 |
table.insert ( value, { v } ) |
|
27 |
end |
|
28 |
else |
|
29 |
value = { field.value } |
|
30 |
end |
|
31 |
table.insert ( fields, { type = field.type, var = field.var, value = value } ) |
|
32 |
end |
|
33 |
end |
|
34 |
root.x.field = fields |
|
35 |
return root |
|
36 |
end |
|
37 |
||
38 |
function x_data.parse ( x ) |
|
39 |
local f = { xmlns = 'jabber:x:data', type = x:attribute ( 'type' ) } |
|
40 |
||
41 |
local title = x:child ( 'title' ) |
|
42 |
if title then |
|
43 |
f.title = title:value () |
|
44 |
end |
|
45 |
local instructions = x:child ( 'instructions' ) |
|
46 |
if instructions then |
|
47 |
f.instructions = instructions:value () |
|
48 |
end |
|
49 |
||
66 | 50 |
local field = x:child () |
49 | 51 |
while field do |
52 |
if field:name () == 'field' then |
|
53 |
local ftype = field:attribute ( 'type' ) or 'text-single' |
|
54 |
local r = { |
|
55 |
type = ftype, |
|
56 |
var = field:attribute ( 'var' ), -- may be absent on 'fixed' fields |
|
57 |
label = field:attribute ( 'label' ), |
|
58 |
} |
|
59 |
||
60 |
local desc = field:child ( 'desc' ) |
|
61 |
if desc then |
|
62 |
r.decs = desc:value () |
|
63 |
end |
|
64 |
if field:child ( 'required' ) then |
|
65 |
r.required = true |
|
66 |
end |
|
67 |
||
68 |
if ftype == 'jid-multi' or ftype == 'list-multi' or ftype == 'text-multi' or ftype == 'list-single' then |
|
69 |
local values = { } |
|
70 |
local options = { } |
|
71 |
||
66 | 72 |
local item = field:child () |
49 | 73 |
while item do |
74 |
local name = item:name () |
|
75 |
if name == 'value' then |
|
76 |
table.insert ( values, item:value () ) |
|
77 |
elseif name == 'option' then |
|
78 |
table.insert ( options, item:child( 'value' ):value () ) -- FIXME labels |
|
79 |
end |
|
80 |
item = item:next () |
|
81 |
end |
|
82 |
||
83 |
if ftype == 'list-single' then |
|
84 |
local value = field:child ( 'value' ) |
|
85 |
if value then |
|
86 |
r.value = value:value () |
|
87 |
end |
|
88 |
else |
|
89 |
r.value = values |
|
90 |
end |
|
91 |
||
92 |
if ftype == 'list-multi' or ftype == 'list-single' then |
|
93 |
r.options = options |
|
94 |
end |
|
95 |
else |
|
96 |
local value = field:child ( 'value' ) |
|
97 |
if value then |
|
98 |
r.value = value:value () |
|
99 |
end |
|
100 |
end |
|
101 |
||
102 |
table.insert ( f, r ) |
|
103 |
end |
|
104 |
||
105 |
field = field:next () |
|
106 |
end |
|
107 |
||
108 |
f.format = x_data.format |
|
109 |
||
110 |
return f |
|
111 |
end |
|
112 |
||
113 |
function x_data.set ( f, name, value ) |
|
114 |
for i, field in ipairs ( f ) do |
|
115 |
if field.var == name then |
|
116 |
if field.type == 'jid-multi' or field.type == 'list-multi' or field.type == 'text-multi' then |
|
117 |
if value == nil then |
|
118 |
field.value = { } |
|
119 |
else |
|
120 |
table.insert ( field.value, value ) |
|
121 |
end |
|
122 |
else |
|
123 |
field.value = value |
|
124 |
end |
|
125 |
end |
|
126 |
end |
|
127 |
end |
|
128 |
||
129 |
-- mcabber |
|
130 |
||
131 |
local form_cid = main.add_category { 'del', 'send' } |
|
132 |
forms = { } |
|
133 |
||
134 |
function insert_form ( form ) |
|
135 |
table.insert ( forms, form ) |
|
136 |
main.add_completion ( form_cid, tostring(#forms) ) |
|
137 |
return #forms |
|
138 |
end |
|
139 |
||
140 |
main.command ( 'form', |
|
141 |
function ( args ) |
|
142 |
local id, action = tonumber (args[1]), args[2] |
|
143 |
if forms[id] then |
|
144 |
local form = forms[id].form |
|
145 |
if action == 'send' then |
|
146 |
forms[id].submit ( form ) |
|
147 |
elseif action == 'reject' then |
|
148 |
forms[id].reject ( form ) |
|
149 |
elseif action == 'del' then |
|
150 |
main.del_completion ( form_cid, id ) |
|
151 |
forms[id] = nil |
|
152 |
elseif action == 'set' then |
|
153 |
x_data.set ( form, args[3], args[4] ) |
|
154 |
elseif action then |
|
155 |
x_data.set ( form, action, args[3] ) |
|
156 |
else |
|
157 |
local desc = 'Form ' .. id |
|
158 |
local fields = 'Fields:' |
|
159 |
for index, field in pairs ( form ) do |
|
160 |
if type(index) == 'number' then |
|
161 |
fields = fields .. '\n - ' |
|
162 |
if field.required then |
|
163 |
fields = fields .. '* ' |
|
164 |
end |
|
165 |
if field.label then |
|
166 |
fields = fields .. field.label .. ' (' .. ( field.var or '' ) .. ')' |
|
167 |
else |
|
168 |
fields = fields .. ( field.var or '<no name>' ) |
|
169 |
end |
|
170 |
fields = fields .. ' [' .. field.type .. ']' |
|
171 |
if field.desc then |
|
172 |
fields = fields .. ': ' .. desc |
|
173 |
end |
|
174 |
if field.options then |
|
175 |
fields = fields .. '\n Options:' |
|
176 |
for i, opt in ipairs ( field.options ) do |
|
177 |
fields = fields .. ' ' .. opt |
|
178 |
end |
|
179 |
end |
|
180 |
if field.type == 'list-multi' or field.type == 'text-multi' or field.type == 'jid-multi' then |
|
181 |
fields = fields .. '\n Values: ' |
|
182 |
for vin, value in ipairs ( field.value ) do |
|
183 |
fields = fields .. '\n * ' .. value |
|
184 |
end |
|
185 |
else |
|
53
2162188b20cf
Fixes to form handling
Myhailo Danylenko <isbear@ukrpost.net>
parents:
49
diff
changeset
|
186 |
fields = fields .. '\n Value: ' .. ( field.value or '' ) |
49 | 187 |
end |
188 |
else |
|
189 |
if type(field) ~= 'function' then -- skip any methods |
|
190 |
desc = desc .. '\n - ' .. index .. ': ' .. field |
|
191 |
end |
|
192 |
end |
|
193 |
end |
|
194 |
print ( desc .. '\n' .. fields ) |
|
195 |
end |
|
196 |
else |
|
197 |
local text = '' |
|
198 |
for id, form in pairs ( forms ) do |
|
199 |
text = text .. '\n - ' .. id .. ' ' .. ( form.form.title or 'Untitled' ) .. ' [' .. form.form.xmlns .. ', ' .. form.form.type .. ']' |
|
200 |
end |
|
201 |
if text ~= '' then |
|
202 |
print ( 'Forms list:' .. text ) |
|
203 |
else |
|
204 |
print ( 'No forms' ) |
|
205 |
end |
|
206 |
end |
|
207 |
end, true, form_cid ) |
|
208 |
||
60 | 209 |
commands_help['form'] = "[form_id [send | reject | [set] fieldname [value]]]\n\nWithout arguments prints form list.\nWith bare form id prints info on that form.\nWhen setting multivalue field, new values are added, not replacing previous.\nWithout value unsets field, multivalue fields lose all their values." |
49 | 210 |
|
211 |
-- vim: se ts=4: -- |