mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
- Some cleanups on templates.
- Make save_to_disk templates sanitize all fields except composites
This commit is contained in:
parent
232ce4748d
commit
1a782eb0ff
@ -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(
|
||||||
|
@ -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,
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user