- Some cleanups on templates.

- Make save_to_disk templates sanitize all fields except composites
This commit is contained in:
Charles Haley 2010-09-23 20:36:52 +01:00
parent 232ce4748d
commit 1a782eb0ff
3 changed files with 51 additions and 42 deletions

View File

@ -34,9 +34,10 @@ NULL_VALUES = {
field_metadata = FieldMetadata() field_metadata = FieldMetadata()
class SafeFormat(TemplateFormatter): class SafeFormat(TemplateFormatter):
def get_value(self, key, args, mi):
def get_value(self, key, args, kwargs):
try: try:
ign, v = mi.format_field(key.lower(), series_with_index=False) ign, v = self.book.format_field(key.lower(), series_with_index=False)
if v is None: if v is None:
return '' return ''
if v == '': if v == '':
@ -100,7 +101,9 @@ class Metadata(object):
cf['#value#'] = 'RECURSIVE_COMPOSITE FIELD ' + field cf['#value#'] = 'RECURSIVE_COMPOSITE FIELD ' + field
cf['#value#'] = composite_formatter.safe_format( cf['#value#'] = composite_formatter.safe_format(
cf['display']['composite_template'], cf['display']['composite_template'],
self, _('TEMPLATE ERROR')).strip() self,
_('TEMPLATE ERROR'),
self).strip()
return d['#value#'] return d['#value#']
raise AttributeError( raise AttributeError(

View File

@ -108,8 +108,12 @@ class SafeFormat(TemplateFormatter):
''' '''
def get_value(self, key, args, kwargs): def get_value(self, key, args, kwargs):
try: try:
if kwargs[key.lower()]: b = self.book.get_user_metadata(key, False)
return kwargs[key.lower()] key = key.lower()
if b is not None and b['datatype'] == 'composite':
return self.vformat(b['display']['composite_template'], [], kwargs)
if kwargs[key]:
return self.sanitize(kwargs[key.lower()])
return '' return ''
except: except:
return '' return ''
@ -159,9 +163,9 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
elif custom_metadata[key]['datatype'] == 'bool': elif custom_metadata[key]['datatype'] == 'bool':
format_args[key] = _('yes') if format_args[key] else _('no') format_args[key] = _('yes') if format_args[key] else _('no')
components = safe_formatter.safe_format(template, format_args, '') components = safe_formatter.safe_format(template, format_args, '', mi,
sanitize=sanitize_func)
components = [x.strip() for x in components.split('/') if x.strip()] components = [x.strip() for x in components.split('/') if x.strip()]
components = [sanitize_func(x) for x in components if x]
if not components: if not components:
components = [str(id)] components = [str(id)]
components = [x.encode(filesystem_encoding, 'replace') if isinstance(x, components = [x.encode(filesystem_encoding, 'replace') if isinstance(x,

View File

@ -6,25 +6,30 @@ Created on 23 Sep 2010
import re, string import re, string
def _lookup(val, mi, field_if_set, field_not_set): class TemplateFormatter(string.Formatter):
if hasattr(mi, 'format_field'): '''
if val: Provides a format function that substitutes '' for any missing value
return mi.format_field(field_if_set.strip())[1] '''
else:
return mi.format_field(field_not_set.strip())[1]
else:
if val:
return mi.get(field_if_set.strip(), '')
else:
return mi.get(field_not_set.strip(), '')
def _ifempty(val, mi, value_if_empty): def __init__(self):
string.Formatter.__init__(self)
self.book = None
self.kwargs = None
self.sanitize = None
def _lookup(self, val, field_if_set, field_not_set):
if val:
return self.vformat('{'+field_if_set.strip()+'}', [], self.kwargs)
else:
return self.vformat('{'+field_not_set.strip()+'}', [], self.kwargs)
def _ifempty(self, val, value_if_empty):
if val: if val:
return val return val
else: else:
return value_if_empty return value_if_empty
def _shorten(val, mi, leading, center_string, trailing): def _shorten(self, val, leading, center_string, trailing):
l = int(leading) l = int(leading)
t = int(trailing) t = int(trailing)
if len(val) > l + len(center_string) + t: if len(val) > l + len(center_string) + t:
@ -32,22 +37,17 @@ def _shorten(val, mi, leading, center_string, trailing):
else: else:
return val return val
class TemplateFormatter(string.Formatter):
'''
Provides a format function that substitutes '' for any missing value
'''
functions = { functions = {
'uppercase' : (0, lambda x: x.upper()), 'uppercase' : (0, lambda s,x: x.upper()),
'lowercase' : (0, lambda x: x.lower()), 'lowercase' : (0, lambda s,x: x.lower()),
'titlecase' : (0, lambda x: x.title()), 'titlecase' : (0, lambda s,x: x.title()),
'capitalize' : (0, lambda x: x.capitalize()), 'capitalize' : (0, lambda s,x: x.capitalize()),
'ifempty' : (1, _ifempty), 'ifempty' : (1, _ifempty),
'lookup' : (2, _lookup), 'lookup' : (2, _lookup),
'shorten' : (3, _shorten), 'shorten' : (3, _shorten),
} }
def get_value(self, key, args, mi): def get_value(self, key, args):
raise Exception('get_value must be implemented in the subclass') raise Exception('get_value must be implemented in the subclass')
format_string_re = re.compile(r'^(.*)\|(.*)\|(.*)$') format_string_re = re.compile(r'^(.*)\|(.*)\|(.*)$')
@ -75,9 +75,9 @@ class TemplateFormatter(string.Formatter):
(func[0] > 0 and func[0] != len(args)): (func[0] > 0 and func[0] != len(args)):
raise Exception ('Incorrect number of arguments for function '+ fmt[0:p]) raise Exception ('Incorrect number of arguments for function '+ fmt[0:p])
if func[0] == 0: if func[0] == 0:
val = func[1](val, self.mi) val = func[1](self, val)
else: else:
val = func[1](val, self.mi, *args) val = func[1](self, val, *args)
else: else:
val = string.Formatter.format_field(self, val, fmt) val = string.Formatter.format_field(self, val, fmt)
if not val: if not val:
@ -87,11 +87,13 @@ class TemplateFormatter(string.Formatter):
compress_spaces = re.compile(r'\s+') compress_spaces = re.compile(r'\s+')
def vformat(self, fmt, args, kwargs): def vformat(self, fmt, args, kwargs):
self.mi = kwargs
ans = string.Formatter.vformat(self, fmt, args, kwargs) ans = string.Formatter.vformat(self, fmt, args, kwargs)
return self.compress_spaces.sub(' ', ans).strip() return self.compress_spaces.sub(' ', ans).strip()
def safe_format(self, fmt, kwargs, error_value): def safe_format(self, fmt, kwargs, error_value, book, sanitize=None):
self.kwargs = kwargs
self.book = book
self.sanitize = sanitize
try: try:
ans = self.vformat(fmt, [], kwargs).strip() ans = self.vformat(fmt, [], kwargs).strip()
except: except: