coding standards

This commit is contained in:
Yann Leboulanger 2009-01-28 07:47:38 +00:00
parent 0b7f2c3fe7
commit 6d9ea872e8
1 changed files with 99 additions and 34 deletions

View File

@ -21,15 +21,18 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
""" This module contains wrappers for different parts of data forms (JEP 0004). For information
how to use them, read documentation. """
""" This module contains wrappers for different parts of data forms (JEP 0004).
For information how to use them, read documentation. """
import xmpp
# exceptions used in this module
class Error(Exception): pass # base class
class UnknownDataForm(Error): pass # when we get xmpp.Node which we do not understand
class WrongFieldValue(Error): pass # when we get xmpp.Node which contains bad fields
# base class
class Error(Exception): pass
# when we get xmpp.Node which we do not understand
class UnknownDataForm(Error): pass
# when we get xmpp.Node which contains bad fields
class WrongFieldValue(Error): pass
# helper class to change class of already existing object
class ExtendedNode(xmpp.Node, object):
@ -56,7 +59,8 @@ def Field(typ, **attrs):
''' Helper function to create a field of given type. '''
f = {
'boolean': BooleanField,
'fixed': TextMultiField, # not editable, still can have multiple lines of text
# not editable, still can have multiple lines of text
'fixed': TextMultiField,
'hidden': StringField,
'text-private': StringField,
'text-single': StringField,
@ -101,33 +105,40 @@ class DataField(ExtendedNode):
""" Keeps data about one field - var, field type, labels, instructions...
Base class for different kinds of fields. Use Field() function to
construct one of these. """
def __init__(self, typ=None, var=None, value=None, label=None, desc=None, required=False,
options=None, extend=None):
def __init__(self, typ=None, var=None, value=None, label=None, desc=None,
required=False, options=None, extend=None):
if extend is None:
ExtendedNode.__init__(self, 'field')
self.type = typ
self.var = var
if value is not None: self.value = value
if label is not None: self.label = label
if desc is not None: self.desc = desc
if value is not None:
self.value = value
if label is not None:
self.label = label
if desc is not None:
self.desc = desc
self.required = required
self.options = options
@nested_property
def type():
'''Type of field. Recognized values are: 'boolean', 'fixed', 'hidden', 'jid-multi',
'jid-single', 'list-multi', 'list-single', 'text-multi', 'text-private',
'text-single'. If you set this to something different, DataField will store
given name, but treat all data as text-single.'''
'''Type of field. Recognized values are: 'boolean', 'fixed', 'hidden',
'jid-multi', 'jid-single', 'list-multi', 'list-single', 'text-multi',
'text-private', 'text-single'. If you set this to something different,
DataField will store given name, but treat all data as text-single.'''
def fget(self):
t = self.getAttr('type')
if t is None: return 'text-single'
if t is None:
return 'text-single'
return t
def fset(self, value):
assert isinstance(value, basestring)
self.setAttr('type', value)
return locals()
@nested_property
@ -135,11 +146,14 @@ class DataField(ExtendedNode):
'''Field identifier.'''
def fget(self):
return self.getAttr('var')
def fset(self, value):
assert isinstance(value, basestring)
self.setAttr('var', value)
def fdel(self):
self.delAttr('var')
return locals()
@nested_property
@ -147,12 +161,15 @@ class DataField(ExtendedNode):
'''Human-readable field name.'''
def fget(self):
return self.getAttr('label')
def fset(self, value):
assert isinstance(value, basestring)
self.setAttr('label', value)
def fdel(self):
if self.getAttr('label'):
self.delAttr('label')
return locals()
@nested_property
@ -160,16 +177,19 @@ class DataField(ExtendedNode):
'''Human-readable description of field meaning.'''
def fget(self):
return self.getTagData('desc') or u''
def fset(self, value):
assert isinstance(value, basestring)
if value == '':
fdel(self)
else:
self.setTagData('desc', value)
def fdel(self):
t = self.getTag('desc')
if t is not None:
self.delChild(t)
return locals()
@nested_property
@ -177,12 +197,14 @@ class DataField(ExtendedNode):
'''Controls whether this field required to fill. Boolean.'''
def fget(self):
return bool(self.getTag('required'))
def fset(self, value):
t = self.getTag('required')
if t and not value:
self.delChild(t)
elif not t and value:
self.addChild('required')
return locals()
class BooleanField(DataField):
@ -191,16 +213,22 @@ class BooleanField(DataField):
'''Value of field. May contain True, False or None.'''
def fget(self):
v = self.getTagData('value')
if v in ('0', 'false'): return False
if v in ('1', 'true'): return True
if v is None: return False # default value is False
if v in ('0', 'false'):
return False
if v in ('1', 'true'):
return True
if v is None:
return False # default value is False
raise WrongFieldValue
def fset(self, value):
self.setTagData('value', value and '1' or '0')
def fdel(self, value):
t = self.getTag('value')
if t is not None:
self.delChild(t)
return locals()
class StringField(DataField):
@ -210,20 +238,23 @@ class StringField(DataField):
'''Value of field. May be any unicode string.'''
def fget(self):
return self.getTagData('value') or u''
def fset(self, value):
assert isinstance(value, basestring)
if value == '':
return fdel(self)
self.setTagData('value', value)
def fdel(self):
try:
self.delChild(self.getTag('value'))
except ValueError: # if there already were no value tag
pass
return locals()
class ListField(DataField):
''' Covers fields of types: jid-multi, jid-single, list-multi, list-single. '''
'''Covers fields of types: jid-multi, jid-single, list-multi, list-single.'''
@nested_property
def options():
'''Options.'''
@ -231,22 +262,27 @@ class ListField(DataField):
options = []
for element in self.getTags('option'):
v = element.getTagData('value')
if v is None: raise WrongFieldValue
if v is None:
raise WrongFieldValue
options.append((element.getAttr('label'), v))
return options
def fset(self, values):
fdel(self)
for value, label in values:
self.addChild('option', {'label': label}).setTagData('value', value)
def fdel(self):
for element in self.getTags('option'):
self.delChild(element)
return locals()
def iter_options(self):
for element in self.iterTags('option'):
v = element.getTagData('value')
if v is None: raise WrongFieldValue
if v is None:
raise WrongFieldValue
l = element.getAttr('label')
if not l:
l = v
@ -266,13 +302,16 @@ class ListMultiField(ListField):
for element in self.getTags('value'):
values.append(element.getData())
return values
def fset(self, values):
fdel(self)
for value in values:
self.addChild('value').setData(value)
def fdel(self):
for element in self.getTags('value'):
self.delChild(element)
return locals()
def iter_values(self):
@ -288,14 +327,18 @@ class TextMultiField(DataField):
for element in self.iterTags('value'):
value += '\n' + element.getData()
return value[1:]
def fset(self, value):
fdel(self)
if value == '': return
if value == '':
return
for line in value.split('\n'):
self.addChild('value').setData(line)
def fdel(self):
for element in self.getTags('value'):
self.delChild(element)
return locals()
class DataRecord(ExtendedNode):
@ -308,7 +351,8 @@ class DataRecord(ExtendedNode):
# we have to build this object from scratch
xmpp.Node.__init__(self)
if fields is not None: self.fields = fields
if fields is not None:
self.fields = fields
else:
# we already have xmpp.Node inside - try to convert all
# fields into DataField objects
@ -327,15 +371,18 @@ class DataRecord(ExtendedNode):
'''List of fields in this record.'''
def fget(self):
return self.getTags('field')
def fset(self, fields):
fdel(self)
for field in fields:
if not isinstance(field, DataField):
ExtendField(extend=field)
self.addChild(node=field)
def fdel(self):
for element in self.getTags('field'):
self.delChild(element)
return locals()
def iter_fields(self):
@ -359,9 +406,12 @@ class DataForm(ExtendedNode):
# we have to build form from scratch
xmpp.Node.__init__(self, 'x', attrs={'xmlns': xmpp.NS_DATA})
if type_ is not None: self.type_=type_
if title is not None: self.title=title
if instructions is not None: self.instructions=instructions
if type_ is not None:
self.type_=type_
if title is not None:
self.title=title
if instructions is not None:
self.instructions=instructions
@nested_property
def type():
@ -370,9 +420,11 @@ class DataForm(ExtendedNode):
filledform = DataForm(replyto=thisform)...'''
def fget(self):
return self.getAttr('type')
def fset(self, type_):
assert type_ in ('form', 'submit', 'cancel', 'result')
self.setAttr('type', type_)
return locals()
@nested_property
@ -380,13 +432,16 @@ class DataForm(ExtendedNode):
''' Title of the form. Human-readable, should not contain any \\r\\n.'''
def fget(self):
return self.getTagData('title')
def fset(self, title):
self.setTagData('title', title)
def fdel(self):
try:
self.delChild('title')
except ValueError:
pass
return locals()
@nested_property
@ -398,19 +453,24 @@ class DataForm(ExtendedNode):
for valuenode in self.getTags('instructions'):
value += '\n' + valuenode.getData()
return value[1:]
def fset(self, value):
fdel(self)
if value == '': return
for line in value.split('\n'):
self.addChild('instructions').setData(line)
def fdel(self):
for value in self.getTags('instructions'):
self.delChild(value)
return locals()
class SimpleDataForm(DataForm, DataRecord):
def __init__(self, type_=None, title=None, instructions=None, fields=None, extend=None):
DataForm.__init__(self, type_=type_, title=title, instructions=instructions, extend=extend)
def __init__(self, type_=None, title=None, instructions=None, fields=None, \
extend=None):
DataForm.__init__(self, type_=type_, title=title,
instructions=instructions, extend=extend)
DataRecord.__init__(self, fields=fields, extend=self, associated=self)
def get_purged(self):
@ -433,12 +493,14 @@ class SimpleDataForm(DataForm, DataRecord):
return c
class MultipleDataForm(DataForm):
def __init__(self, type_=None, title=None, instructions=None, items=None, extend=None):
DataForm.__init__(self, type_=type_, title=title, instructions=instructions, extend=extend)
def __init__(self, type_=None, title=None, instructions=None, items=None,
extend=None):
DataForm.__init__(self, type_=type_, title=title,
instructions=instructions, extend=extend)
# all records, recorded into DataRecords
if extend is None:
if items is not None: self.items = items
if items is not None:
self.items = items
else:
# we already have xmpp.Node inside - try to convert all
# fields into DataField objects
@ -449,22 +511,25 @@ class MultipleDataForm(DataForm):
self.delChild(item)
self.items = items
reported_tag = self.getTag('reported')
self.reported = DataRecord(extend = reported_tag)
self.reported = DataRecord(extend=reported_tag)
@nested_property
def items():
''' A list of all records. '''
def fget(self):
return list(self.iter_records())
def fset(self, records):
fdel(self)
for record in records:
if not isinstance(record, DataRecord):
DataRecord(extend=record)
self.addChild(node=record)
def fdel(self):
for record in self.getTags('item'):
self.delChild(record)
return locals()
def iter_records(self):