summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2020-11-06 12:05:11 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2020-11-06 12:06:43 +0100
commit38feb7f2d40dfd1e05b81314b15c52ccb95fc870 (patch)
tree02f9abfc37c78c31ed53185d10ac28e24f551918 /ishtar_common/models.py
parent17cbbc926a186d517d9683c33b3265b6b4b578f0 (diff)
downloadIshtar-38feb7f2d40dfd1e05b81314b15c52ccb95fc870.tar.bz2
Ishtar-38feb7f2d40dfd1e05b81314b15c52ccb95fc870.zip
Label generation: optimize template evaluation
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py117
1 files changed, 88 insertions, 29 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 94d8744e5..f4d898dc5 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -42,6 +42,7 @@ from ooopy.OOoPy import OOoPy
from ooopy.Transformer import Transformer as OOTransformer
import ooopy.Transforms as OOTransforms
import uuid
+import zipfile
from django import forms
from django.apps import apps
@@ -93,7 +94,7 @@ from ishtar_common.models_imports import ImporterModel, ImporterType, \
from ishtar_common.templatetags.link_to_window import simple_link_to_window
from ishtar_common.utils import get_cache, disable_for_loaddata, create_slug, \
get_all_field_names, merge_tsvectors, cached_label_changed, post_save_geo, \
- generate_relation_graph, max_size_help, task, SecretaryRenderer
+ generate_relation_graph, max_size_help, task
__all__ = [
'ImporterModel', 'ImporterType', 'ImporterDefault', 'ImporterDefaultValues',
@@ -136,25 +137,38 @@ class ValueGetter(object):
GET_VALUES_EXTRA_TYPES = [
'preservation_to_considers', 'alterations', 'alteration_causes']
- def _get_values_documents(self, prefix=""):
+ def _get_values_documents(self, prefix="", filtr=None):
values = {}
if not hasattr(self, 'documents'):
return values
- values[prefix + "documents"] = [
- doc.get_values(no_values=True)
- for doc in self.documents.all()
- ]
+ if not filtr or prefix + "documents" in filtr:
+ values[prefix + "documents"] = [
+ doc.get_values(no_values=True)
+ for doc in self.documents.all()
+ ]
+ if filtr and prefix + "main_image" not in filtr:
+ return values
if hasattr(self, "main_image") and self.main_image and hasattr(
self.main_image, "get_values"):
values[prefix + "main_image"] = self.main_image.get_values(
no_values=True)
return values
- def get_values(self, prefix='', no_values=False):
+ def _get_values_update_sub_filter(self, filtr, prefix):
+ if not filtr:
+ return
+ new_filtr = []
+ for k in filtr:
+ if k.startswith(prefix):
+ new_filtr.append(k[len(prefix):])
+ return new_filtr
+
+ def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
if not prefix:
prefix = self._prefix
values = {}
- if hasattr(self, "qrcode"):
+ if hasattr(self, "qrcode") and (not filtr
+ or 'qrcode_path' in filtr):
values['qrcode_path'] = self.qrcode_path
for field_name in get_all_field_names(self):
try:
@@ -163,15 +177,27 @@ class ValueGetter(object):
continue
if field_name in self.GET_VALUES_EXCLUDE_FIELDS:
continue
+ if filtr and prefix + field_name not in filtr:
+ if hasattr(value, 'get_values'):
+ new_prefix = prefix + field_name + '_'
+ new_filtr = self._get_values_update_sub_filter(filtr,
+ new_prefix)
+ values.update(
+ value.get_values(new_prefix, filtr=new_filtr, **kwargs))
+ continue
if hasattr(self, "get_values_for_" + field_name):
values[prefix + field_name] = getattr(
self, "get_values_for_" + field_name)()
else:
if hasattr(value, 'get_values'):
- values.update(value.get_values(prefix + field_name + '_'))
+ new_prefix = prefix + field_name + '_'
+ new_filtr = self._get_values_update_sub_filter(filtr,
+ new_prefix)
+ values.update(
+ value.get_values(new_prefix, filtr=new_filtr, **kwargs))
else:
values[prefix + field_name] = value
- values.update(self._get_values_documents(prefix=prefix))
+ values.update(self._get_values_documents(prefix=prefix, filtr=filtr))
for extra_field in self.GET_VALUES_EXTRA:
values[prefix + extra_field] = getattr(self, extra_field) or ''
for key in values.keys():
@@ -3645,6 +3671,23 @@ class DocumentTemplate(models.Model):
output.write(result)
return output_name
+ def get_filter(self, template, regexp_list=None):
+ if not regexp_list:
+ return None
+ z = zipfile.ZipFile(template)
+ content = z.open('content.xml')
+ full_content = content.read().decode("utf-8")
+ filtr = []
+ for regexp in regexp_list:
+ iter = re.finditer(
+ regexp,
+ full_content)
+ for s in iter:
+ key = s.groups()[0]
+ if key not in filtr:
+ filtr.append(key)
+ return filtr
+
def publish_labels(self, objects):
if not objects:
return
@@ -3655,6 +3698,13 @@ class DocumentTemplate(models.Model):
suffix = "." + self.template.name.split('.')[-1]
len_objects = len(objects)
names = []
+
+ filtr = self.get_filter(
+ self.template,
+ # e.g.: {{items.4.key}}
+ [r'{{ *items\.\d\.([A-Za-z0-9_.]*)(\|[A-Za-z0-9_.-]*)* *}}']
+ )
+
for idx in range(int(len(objects) / self.label_per_page) + 1):
if idx * self.label_per_page >= len_objects:
break
@@ -3664,7 +3714,7 @@ class DocumentTemplate(models.Model):
if c_idx >= len_objects:
break
obj = objects[c_idx]
- values["items"].append(obj.get_values())
+ values["items"].append(obj.get_values(filtr=filtr))
engine = IshtarSecretaryRenderer()
try:
result = engine.render(self.template, **values)
@@ -3808,12 +3858,18 @@ class Town(Imported, models.Model):
'year': self.year or ""}
return values
- def get_values(self, prefix='', no_values=False, no_base_finds=True):
- return {
- prefix or "label": str(self),
- prefix + "name": self.name,
- prefix + "numero_insee": self.numero_insee
- }
+ def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ values = {}
+ if not filtr or prefix in filtr or "label" in filtr:
+ if prefix:
+ values[prefix] = str(self)
+ else:
+ values['label'] = str(self)
+ if not filtr or prefix + "name" in filtr:
+ values[prefix + "name"] = self.name
+ if not filtr or prefix + "numero_insee" in filtr:
+ values[prefix + "numero_insee"] = self.numero_insee
+ return values
@classmethod
def history_decompress(cls, full_value, create=False):
@@ -4579,9 +4635,9 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
values.append(attached_to)
return " ".join(values)
- def get_values(self, prefix='', no_values=False):
- values = super(Person, self).get_values(prefix=prefix,
- no_values=no_values)
+ def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ values = super(Person, self).get_values(
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
if not self.attached_to:
values.update(
Person.get_empty_values(prefix=prefix + 'attached_to_'))
@@ -5051,10 +5107,11 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
return Q(user=ishtaruser) | Q(
shared_write_with=ishtaruser)
- def get_values(self, prefix='', no_values=False):
- values = super(Basket, self).get_values(prefix=prefix,
- no_values=no_values)
- values["items"] = [item.get_values() for item in self.items.all()]
+ def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ values = super(Basket, self).get_values(
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
+ if not filtr or "items" in filtr:
+ values["items"] = [item.get_values() for item in self.items.all()]
return values
def duplicate(self, label=None, ishtaruser=None):
@@ -5552,11 +5609,13 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,
return ""
return self.image.path
- def get_values(self, prefix="", no_values=False):
- values = super(Document, self).get_values(prefix=prefix,
- no_values=no_values)
- values[prefix + "image_path"] = self.image_path
- values[prefix + "thumbnail_path"] = self.thumbnail_path
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
+ values = super(Document, self).get_values(
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
+ if not filtr or prefix + "image_path" in filtr:
+ values[prefix + "image_path"] = self.image_path
+ if not filtr or prefix + "thumbnail_path" in filtr:
+ values[prefix + "thumbnail_path"] = self.thumbnail_path
return values
@property