SleekXMPP/sleekxmpp/plugins/xep_0004/stanza/field.py
Lance Stout 9b7ed73f95 Reorganize XEP-0004.
Changes:
    May now use underscored method names
    form.field is replaced by form['fields']
    form.get_fields no longer accepts use_dict parameter, it always
        returns an OrderedDict now
    form.set_fields will accept either an OrderedDict, or a list
        of (var, dict) tuples as before.
    Setting the form type to 'submit' will remove extra meta data
        from the form fields, leaving just the 'var' and 'value'
    Setting the form type to 'cancel' will remove all fields.
2011-08-11 21:59:55 -07:00

167 lines
5.5 KiB
Python

"""
SleekXMPP: The Sleek XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of SleekXMPP.
See the file LICENSE for copying permission.
"""
from sleekxmpp.xmlstream import ElementBase, ET
class FormField(ElementBase):
namespace = 'jabber:x:data'
name = 'field'
plugin_attrib = 'field'
interfaces = set(('answer', 'desc', 'required', 'value',
'options', 'label', 'type', 'var'))
sub_interfaces = set(('desc',))
plugin_tag_map = {}
plugin_attrib_map = {}
field_types = set(('boolean', 'fixed', 'hidden', 'jid-multi',
'jid-single', 'list-multi', 'list-single',
'text-multi', 'text-private', 'text-single'))
true_values = set((True, '1', 'true'))
option_types = set(('list-multi', 'list-single'))
multi_line_types = set(('hidden', 'text-multi'))
multi_value_types = set(('hidden', 'jid-multi',
'list-multi', 'text-multi'))
def add_option(self, label='', value=''):
if self['type'] in self.option_types:
opt = FieldOption(parent=self)
opt['label'] = label
opt['value'] = value
else:
raise ValueError("Cannot add options to " + \
"a %s field." % self['type'])
def del_options(self):
optsXML = self.xml.findall('{%s}option' % self.namespace)
for optXML in optsXML:
self.xml.remove(optXML)
def del_required(self):
reqXML = self.xml.find('{%s}required' % self.namespace)
if reqXML is not None:
self.xml.remove(reqXML)
def del_value(self):
valsXML = self.xml.findall('{%s}value' % self.namespace)
for valXML in valsXML:
self.xml.remove(valXML)
def get_answer(self):
return self['value']
def get_options(self):
options = []
optsXML = self.xml.findall('{%s}option' % self.namespace)
for optXML in optsXML:
opt = FieldOption(xml=optXML)
options.append({'label': opt['label'], 'value': opt['value']})
return options
def get_required(self):
reqXML = self.xml.find('{%s}required' % self.namespace)
return reqXML is not None
def get_value(self):
valsXML = self.xml.findall('{%s}value' % self.namespace)
if len(valsXML) == 0:
return None
elif self['type'] == 'boolean':
return valsXML[0].text in self.true_values
elif self['type'] in self.multi_value_types:
values = []
for valXML in valsXML:
if valXML.text is None:
valXML.text = ''
values.append(valXML.text)
if self['type'] == 'text-multi':
values = "\n".join(values)
return values
else:
return valsXML[0].text
def set_answer(self, answer):
self['value'] = answer
def set_false(self):
self['value'] = False
def set_options(self, options):
for value in options:
if isinstance(value, dict):
self.add_option(**value)
else:
self.add_option(value=value)
def set_required(self, required):
exists = self['required']
if not exists and required:
self.xml.append(ET.Element('{%s}required' % self.namespace))
elif exists and not required:
del self['required']
def set_true(self):
self['value'] = True
def set_value(self, value):
del self['value']
valXMLName = '{%s}value' % self.namespace
if self['type'] == 'boolean':
if value in self.true_values:
valXML = ET.Element(valXMLName)
valXML.text = '1'
self.xml.append(valXML)
else:
valXML = ET.Element(valXMLName)
valXML.text = '0'
self.xml.append(valXML)
elif self['type'] in self.multi_value_types or not self['type']:
if not isinstance(value, list):
if self['type'] in self.multi_line_types:
value = value.split('\n')
else:
value = [value]
for val in value:
if self['type'] in ['', None] and val in self.true_values:
val = '1'
valXML = ET.Element(valXMLName)
valXML.text = val
self.xml.append(valXML)
else:
if isinstance(value, list):
raise ValueError("Cannot add multiple values " + \
"to a %s field." % self['type'])
valXML = ET.Element(valXMLName)
valXML.text = value
self.xml.append(valXML)
class FieldOption(ElementBase):
namespace = 'jabber:x:data'
name = 'option'
plugin_attrib = 'option'
interfaces = set(('label', 'value'))
sub_interfaces = set(('value',))
FormField.addOption = FormField.add_option
FormField.delOptions = FormField.del_options
FormField.delRequired = FormField.del_required
FormField.delValue = FormField.del_value
FormField.getAnswer = FormField.get_answer
FormField.getOptions = FormField.get_options
FormField.getRequired = FormField.get_required
FormField.getValue = FormField.get_value
FormField.setAnswer = FormField.set_answer
FormField.setFalse = FormField.set_false
FormField.setOptions = FormField.set_options
FormField.setRequired = FormField.set_required
FormField.setTrue = FormField.set_true
FormField.setValue = FormField.set_value