mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Improve performance of the recent changes to support per-library user template functions. The original implementation created a copy of the template functions dict every time a template was evaluated. The new implementation creates that dict when the library is opened and passes it to the formatter.
This commit is contained in:
parent
66a0b28b93
commit
b21abb1147
@ -33,7 +33,8 @@ from calibre.utils.filenames import (
|
|||||||
from calibre.utils.img import save_cover_data_to
|
from calibre.utils.img import save_cover_data_to
|
||||||
from calibre.utils.formatter_functions import (load_user_template_functions,
|
from calibre.utils.formatter_functions import (load_user_template_functions,
|
||||||
unload_user_template_functions,
|
unload_user_template_functions,
|
||||||
compile_user_template_functions)
|
compile_user_template_functions,
|
||||||
|
formatter_functions)
|
||||||
from calibre.db.tables import (OneToOneTable, ManyToOneTable, ManyToManyTable,
|
from calibre.db.tables import (OneToOneTable, ManyToOneTable, ManyToManyTable,
|
||||||
SizeTable, FormatsTable, AuthorsTable, IdentifiersTable, PathTable,
|
SizeTable, FormatsTable, AuthorsTable, IdentifiersTable, PathTable,
|
||||||
CompositeTable, UUIDTable, RatingTable)
|
CompositeTable, UUIDTable, RatingTable)
|
||||||
@ -413,11 +414,16 @@ class DB(object):
|
|||||||
if load_user_formatter_functions:
|
if load_user_formatter_functions:
|
||||||
set_global_state(self)
|
set_global_state(self)
|
||||||
|
|
||||||
|
def get_template_functions(self):
|
||||||
|
return self._template_functions
|
||||||
|
|
||||||
def get_user_template_functions(self):
|
def get_user_template_functions(self):
|
||||||
return self._user_template_functions
|
return self._user_template_functions
|
||||||
|
|
||||||
def set_user_template_functions(self, user_formatter_functions):
|
def set_user_template_functions(self, user_formatter_functions):
|
||||||
self._user_template_functions = user_formatter_functions
|
self._user_template_functions = user_formatter_functions
|
||||||
|
self._template_functions = formatter_functions().get_builtins()
|
||||||
|
self._template_functions.update(user_formatter_functions)
|
||||||
|
|
||||||
def initialize_prefs(self, default_prefs, restore_all_prefs, progress_callback): # {{{
|
def initialize_prefs(self, default_prefs, restore_all_prefs, progress_callback): # {{{
|
||||||
self.prefs = DBPrefs(self)
|
self.prefs = DBPrefs(self)
|
||||||
|
@ -356,13 +356,13 @@ class Cache(object):
|
|||||||
|
|
||||||
for field, table in self.backend.tables.iteritems():
|
for field, table in self.backend.tables.iteritems():
|
||||||
self.fields[field] = create_field(field, table, bools_are_tristate,
|
self.fields[field] = create_field(field, table, bools_are_tristate,
|
||||||
self.backend.get_user_template_functions)
|
self.backend.get_template_functions)
|
||||||
if table.metadata['datatype'] == 'composite':
|
if table.metadata['datatype'] == 'composite':
|
||||||
self.composites[field] = self.fields[field]
|
self.composites[field] = self.fields[field]
|
||||||
|
|
||||||
self.fields['ondevice'] = create_field('ondevice',
|
self.fields['ondevice'] = create_field('ondevice',
|
||||||
VirtualTable('ondevice'), bools_are_tristate,
|
VirtualTable('ondevice'), bools_are_tristate,
|
||||||
self.backend.get_user_template_functions)
|
self.backend.get_template_functions)
|
||||||
|
|
||||||
for name, field in self.fields.iteritems():
|
for name, field in self.fields.iteritems():
|
||||||
if name[0] == '#' and name.endswith('_index'):
|
if name[0] == '#' and name.endswith('_index'):
|
||||||
|
@ -41,7 +41,7 @@ class Field(object):
|
|||||||
is_many_many = False
|
is_many_many = False
|
||||||
is_composite = False
|
is_composite = False
|
||||||
|
|
||||||
def __init__(self, name, table, bools_are_tristate, get_user_formatter_functions):
|
def __init__(self, name, table, bools_are_tristate, get_template_functions):
|
||||||
self.name, self.table = name, table
|
self.name, self.table = name, table
|
||||||
dt = self.metadata['datatype']
|
dt = self.metadata['datatype']
|
||||||
self.has_text_data = dt in {'text', 'comments', 'series', 'enumeration'}
|
self.has_text_data = dt in {'text', 'comments', 'series', 'enumeration'}
|
||||||
@ -88,7 +88,7 @@ class Field(object):
|
|||||||
self.category_formatter = calibre_langcode_to_name
|
self.category_formatter = calibre_langcode_to_name
|
||||||
self.writer = Writer(self)
|
self.writer = Writer(self)
|
||||||
self.series_field = None
|
self.series_field = None
|
||||||
self.get_user_formatter_functions = get_user_formatter_functions
|
self.get_template_functions = get_template_functions
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def metadata(self):
|
def metadata(self):
|
||||||
@ -204,8 +204,8 @@ class CompositeField(OneToOneField):
|
|||||||
is_composite = True
|
is_composite = True
|
||||||
SIZE_SUFFIX_MAP = {suffix:i for i, suffix in enumerate(('', 'K', 'M', 'G', 'T', 'P', 'E'))}
|
SIZE_SUFFIX_MAP = {suffix:i for i, suffix in enumerate(('', 'K', 'M', 'G', 'T', 'P', 'E'))}
|
||||||
|
|
||||||
def __init__(self, name, table, bools_are_tristate, get_user_formatter_functions):
|
def __init__(self, name, table, bools_are_tristate, get_template_functions):
|
||||||
OneToOneField.__init__(self, name, table, bools_are_tristate, get_user_formatter_functions)
|
OneToOneField.__init__(self, name, table, bools_are_tristate, get_template_functions)
|
||||||
|
|
||||||
self._render_cache = {}
|
self._render_cache = {}
|
||||||
self._lock = Lock()
|
self._lock = Lock()
|
||||||
@ -266,7 +266,7 @@ class CompositeField(OneToOneField):
|
|||||||
ans = formatter.safe_format(
|
ans = formatter.safe_format(
|
||||||
self.metadata['display']['composite_template'], mi, _('TEMPLATE ERROR'),
|
self.metadata['display']['composite_template'], mi, _('TEMPLATE ERROR'),
|
||||||
mi, column_name=self._composite_name, template_cache=template_cache,
|
mi, column_name=self._composite_name, template_cache=template_cache,
|
||||||
user_functions=self.get_user_formatter_functions()).strip()
|
template_functions=self.get_template_functions()).strip()
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self._render_cache[book_id] = ans
|
self._render_cache[book_id] = ans
|
||||||
return ans
|
return ans
|
||||||
@ -349,7 +349,7 @@ class CompositeField(OneToOneField):
|
|||||||
|
|
||||||
class OnDeviceField(OneToOneField):
|
class OnDeviceField(OneToOneField):
|
||||||
|
|
||||||
def __init__(self, name, table, bools_are_tristate, get_user_formatter_functions):
|
def __init__(self, name, table, bools_are_tristate, get_template_functions):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.book_on_device_func = None
|
self.book_on_device_func = None
|
||||||
self.is_multiple = False
|
self.is_multiple = False
|
||||||
@ -735,7 +735,7 @@ class TagsField(ManyToManyField):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def create_field(name, table, bools_are_tristate, get_user_formatter_functions):
|
def create_field(name, table, bools_are_tristate, get_template_functions):
|
||||||
cls = {
|
cls = {
|
||||||
ONE_ONE: OneToOneField,
|
ONE_ONE: OneToOneField,
|
||||||
MANY_ONE: ManyToOneField,
|
MANY_ONE: ManyToOneField,
|
||||||
@ -755,5 +755,5 @@ def create_field(name, table, bools_are_tristate, get_user_formatter_functions):
|
|||||||
cls = CompositeField
|
cls = CompositeField
|
||||||
elif table.metadata['datatype'] == 'series':
|
elif table.metadata['datatype'] == 'series':
|
||||||
cls = SeriesField
|
cls = SeriesField
|
||||||
return cls(name, table, bools_are_tristate, get_user_formatter_functions)
|
return cls(name, table, bools_are_tristate, get_template_functions)
|
||||||
|
|
||||||
|
@ -359,15 +359,16 @@ class TemplateFormatter(string.Formatter):
|
|||||||
|
|
||||||
def safe_format(self, fmt, kwargs, error_value, book,
|
def safe_format(self, fmt, kwargs, error_value, book,
|
||||||
column_name=None, template_cache=None,
|
column_name=None, template_cache=None,
|
||||||
strip_results=True, user_functions=None):
|
strip_results=True, template_functions=None):
|
||||||
self.strip_results = strip_results
|
self.strip_results = strip_results
|
||||||
self.column_name = column_name
|
self.column_name = column_name
|
||||||
self.template_cache = template_cache
|
self.template_cache = template_cache
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.book = book
|
self.book = book
|
||||||
if user_functions:
|
if template_functions:
|
||||||
self.funcs = formatter_functions().get_builtins().copy()
|
self.funcs = template_functions
|
||||||
self.funcs.update(user_functions)
|
else:
|
||||||
|
self.funcs = formatter_functions().get_functions()
|
||||||
self.composite_values = {}
|
self.composite_values = {}
|
||||||
self.locals = {}
|
self.locals = {}
|
||||||
try:
|
try:
|
||||||
|
@ -861,7 +861,7 @@ class BuiltinFormatNumber(BuiltinFormatterFunction):
|
|||||||
def evaluate(self, formatter, kwargs, mi, locals, val, template):
|
def evaluate(self, formatter, kwargs, mi, locals, val, template):
|
||||||
if val == '' or val == 'None':
|
if val == '' or val == 'None':
|
||||||
return ''
|
return ''
|
||||||
if not '{' in template:
|
if '{' not in template:
|
||||||
template = '{0:' + template + '}'
|
template = '{0:' + template + '}'
|
||||||
try:
|
try:
|
||||||
v1 = float(val)
|
v1 = float(val)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user