appy.gen: use appy.shared.utils.formatNumber function; visual bugfix while displaying boolean fields; appy.shared.dav: error bugfix in error handling; appy.shared.utils: added french-accents-aware functions lower and upper; appy.shared.xml_parser: bugfix while managing 'any' tags.

This commit is contained in:
Gaetan Delannay 2011-11-03 16:14:23 +01:00
parent 331db304e7
commit 040cdafb8c
5 changed files with 64 additions and 35 deletions

View file

@ -10,7 +10,7 @@ from appy.gen.utils import sequenceTypes, GroupDescr, Keywords, FileWrapper, \
import appy.pod import appy.pod
from appy.pod.renderer import Renderer from appy.pod.renderer import Renderer
from appy.shared.data import countries from appy.shared.data import countries
from appy.shared.utils import Traceback, getOsTempFolder from appy.shared.utils import Traceback, getOsTempFolder, formatNumber
# Default Appy permissions ----------------------------------------------------- # Default Appy permissions -----------------------------------------------------
r, w, d = ('read', 'write', 'delete') r, w, d = ('read', 'write', 'delete')
@ -989,29 +989,7 @@ class Float(Type):
self.pythonType = float self.pythonType = float
def getFormattedValue(self, obj, value): def getFormattedValue(self, obj, value):
if self.isEmptyValue(value): return '' return formatNumber(value, sep=self.sep[0], precision=self.precision)
# Determine the field separator
sep = self.sep[0]
# Produce the rounded string representation
if self.precision == None:
res = str(value)
else:
format = '%%.%df' % self.precision
res = format % value
# Use the correct decimal separator
res = res.replace('.', sep)
# Remove the decimal part if = 0
splitted = res.split(sep)
if len(splitted) > 1:
try:
decPart = int(splitted[1])
if decPart == 0:
res = splitted[0]
except ValueError:
# This exception may occur when the float value has an "exp"
# part, like in this example: 4.345e-05.
pass
return res
def validateValue(self, obj, value): def validateValue(self, obj, value):
# Replace used separator with the Python separator '.' # Replace used separator with the Python separator '.'

View file

@ -11,10 +11,10 @@
checked python:contextObj.checkboxChecked(name, rawValue); checked python:contextObj.checkboxChecked(name, rawValue);
onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(this)' % (name, name); onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(this)' % (name, name);
class masterCss"/> class masterCss"/>
<input tal:attributes="name name; <input type="hidden"
tal:attributes="name name;
id string:${name}_hidden; id string:${name}_hidden;
value python: test(contextObj.checkboxChecked(name, rawValue), 'True', 'False')" value python: test(contextObj.checkboxChecked(name, rawValue), 'True', 'False')"/>
type="hidden" />&nbsp;
</metal:edit> </metal:edit>
<tal:comment replace="nothing">Cell macro for an Boolean.</tal:comment> <tal:comment replace="nothing">Cell macro for an Boolean.</tal:comment>

View file

@ -168,7 +168,7 @@ class Resource:
except socket.gaierror, sge: except socket.gaierror, sge:
raise ResourceError('Check your Internet connection (%s)'% str(sge)) raise ResourceError('Check your Internet connection (%s)'% str(sge))
except socket.error, se: except socket.error, se:
raise ResourceError('Connection error (%s)'% str(sge)) raise ResourceError('Connection error (%s)'% str(se))
# Tell what kind of HTTP request it will be. # Tell what kind of HTTP request it will be.
conn.putrequest(method, uri) conn.putrequest(method, uri)
# Add HTTP headers # Add HTTP headers

View file

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Appy is a framework for building applications in the Python language. # Appy is a framework for building applications in the Python language.
# Copyright (C) 2007 Gaetan Delannay # Copyright (C) 2007 Gaetan Delannay
@ -194,11 +195,59 @@ def normalizeString(s, usage='fileName'):
res = s res = s
return res return res
def formatNumber(n, sep=',', precision=2, tsep=' '):
'''Returns a string representation of number p_n, which can be a float
or integer. p_sep is the decimal separator to use. p_precision is the
number of digits to keep in the decimal part for producing a nice rounded
string representation. p_tsep is the "thousands" separator.'''
if n == None: return ''
# Manage precision
if precision == None:
res = str(n)
else:
format = '%%.%df' % precision
res = format % n
# Use the correct decimal separator
res = res.replace('.', sep)
# Format the integer part with tsep: TODO.
splitted = res.split(sep)
# Remove the decimal part if = 0
if len(splitted) > 1:
try:
decPart = int(splitted[1])
if decPart == 0:
res = splitted[0]
except ValueError:
# This exception may occur when the float value has an "exp"
# part, like in this example: 4.345e-05.
pass
return res
# ------------------------------------------------------------------------------
toLower = {'Ç':'ç','Ù':'ù','Û':'û','Ü':'ü','Î':'î','Ï':'ï','Ô':'ô','Ö':'ö',
'É':'é','È':'è','Ê':'ê','Ë':'ë','À':'à','Â':'â','Ä':'ä'}
toUpper = {'ç':'Ç','ù':'Ù','û':'Û','ü':'Ü','î':'Î','ï':'Ï','ô':'Ô','ö':'Ö',
'é':'É','è':'È','ê':'Ê','ë':'Ë','à':'À','â':'Â','ä':'Ä'}
def lower(s):
'''French-accents-aware variant of string.lower.'''
res = s.lower()
for upp, low in toLower.iteritems():
if upp in res: res = res.replace(upp, low)
return res
def upper(s):
'''French-accents-aware variant of string.upper.'''
res = s.upper()
for low, upp in toUpper.iteritems():
if low in res: res = res.replace(low, upp)
return res
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
typeLetters = {'b': bool, 'i': int, 'j': long, 'f':float, 's':str, 'u':unicode, typeLetters = {'b': bool, 'i': int, 'j': long, 'f':float, 's':str, 'u':unicode,
'l': list, 'd': dict} 'l': list, 'd': dict}
exts = {'py': ('.py', '.vpy', '.cpy'), 'pt': ('.pt', '.cpt')} exts = {'py': ('.py', '.vpy', '.cpy'), 'pt': ('.pt', '.cpt')}
# ------------------------------------------------------------------------------
class CodeAnalysis: class CodeAnalysis:
'''This class holds information about some code analysis (line counts) that '''This class holds information about some code analysis (line counts) that
spans some folder hierarchy.''' spans some folder hierarchy.'''

View file

@ -580,7 +580,9 @@ class XmlMarshaller:
# As a preamble, manage special case of p_fieldName == "_any". In that # As a preamble, manage special case of p_fieldName == "_any". In that
# case, p_fieldValue corresponds to a previously marshalled string that # case, p_fieldValue corresponds to a previously marshalled string that
# must be included as is here, without dumping the tag name. # must be included as is here, without dumping the tag name.
if fieldName == '_any': self.dumpValue(res, fieldValue, None) if fieldName == '_any':
res.write(value)
return
# Now, dump "normal" fields. # Now, dump "normal" fields.
fieldTag = self.getTagName(fieldName) fieldTag = self.getTagName(fieldName)
res.write('<'); res.write(fieldTag) res.write('<'); res.write(fieldTag)