summaryrefslogtreecommitdiff
path: root/ishtar_common/utils.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2020-11-18 16:46:37 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-28 12:15:21 +0100
commitb27fabdea6c6bfba75521dc84f5a321e61e6ef52 (patch)
tree2b4452bc7fec7de7a90e81d9055a8b9971b18c5c /ishtar_common/utils.py
parent4fa501cb189c61d94a2ca53a604f3db7a212153c (diff)
downloadIshtar-b27fabdea6c6bfba75521dc84f5a321e61e6ef52.tar.bz2
Ishtar-b27fabdea6c6bfba75521dc84f5a321e61e6ef52.zip
Complex index generation with JINJA2 templates
Diffstat (limited to 'ishtar_common/utils.py')
-rw-r--r--ishtar_common/utils.py92
1 files changed, 69 insertions, 23 deletions
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 70c374731..d86c94d86 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -26,6 +26,7 @@ from inspect import currentframe, getframeinfo
import hashlib
from importlib import import_module
import io
+from jinja2 import Template
import os
import random
import re
@@ -1764,6 +1765,8 @@ def get_current_profile(force=False):
PARSE_FORMULA = re.compile("{([^}]*)}")
+PARSE_JINJA = re.compile("{{([^}]*)}")
+PARSE_JINJA_IF = re.compile("{% if ([^}]*)}")
def _deduplicate(value):
@@ -1782,12 +1785,77 @@ FORMULA_FILTERS = {
'deduplicate': _deduplicate
}
+
+def _update_gen_id_dct(item, dct, initial_key, fkey=None, filters=None):
+ if not fkey:
+ fkey = initial_key[:]
+ if fkey.startswith('settings__'):
+ dct[fkey] = getattr(settings, fkey[len('settings__'):]) or ''
+ return
+ obj = item
+ for k in fkey.split('__'):
+ try:
+ obj = getattr(obj, k)
+ except (ObjectDoesNotExist, AttributeError):
+ obj = None
+ if hasattr(obj, 'all') and hasattr(obj, 'count'): # query manager
+ if not obj.count():
+ break
+ obj = obj.all()[0]
+ elif callable(obj):
+ obj = obj()
+ if obj is None:
+ break
+ if obj is None:
+ dct[initial_key] = ''
+ else:
+ dct[initial_key] = str(obj)
+ if filters:
+ for filtr in filters:
+ dct[initial_key] = filtr(dct[initial_key])
+
+
def get_generated_id(key, item):
profile = get_current_profile()
if not hasattr(profile, key):
return
formula = getattr(profile, key)
+
dct = {}
+ # jinja2 style
+ if "{{" in formula or "{%" in formula:
+ # naive parse - only simple jija2 is managed
+ key_list = []
+ for key in PARSE_JINJA.findall(formula):
+ key = key.strip().split("|")[0]
+ key_list.append(key)
+
+ for keys in PARSE_JINJA_IF.findall(formula):
+ sub_key_list = keys.split(" or ")
+ res = []
+ for keys2 in sub_key_list:
+ res += keys2.split(" and ")
+
+ key_list = map(lambda x: x.strip(), key_list)
+ new_keys = []
+ for key in key_list:
+ if key.startswith("not "):
+ key = key[len("not "):].strip()
+ key = key.split(".")[0]
+ if " % " in key:
+ keys = key.split(" % ")[1]
+ keys = [
+ i.replace("(", "").replace(")", "").split("|")[0].strip()
+ for i in keys.split(",")]
+ else:
+ keys = [key]
+ new_keys += keys
+ key_list = new_keys
+ for key in set(key_list):
+ _update_gen_id_dct(item, dct, key)
+ tpl = Template(formula)
+ return tpl.render(dct)
+
for fkey in PARSE_FORMULA.findall(formula):
filtered = fkey.split('|')
initial_key = fkey[:]
@@ -1796,29 +1864,7 @@ def get_generated_id(key, item):
for filtr in filtered[1:]:
if filtr in FORMULA_FILTERS:
filters.append(FORMULA_FILTERS[filtr])
- if fkey.startswith('settings__'):
- dct[fkey] = getattr(settings, fkey[len('settings__'):]) or ''
- continue
- obj = item
- for k in fkey.split('__'):
- try:
- obj = getattr(obj, k)
- except ObjectDoesNotExist:
- obj = None
- if hasattr(obj, 'all') and hasattr(obj, 'count'): # query manager
- if not obj.count():
- break
- obj = obj.all()[0]
- elif callable(obj):
- obj = obj()
- if obj is None:
- break
- if obj is None:
- dct[initial_key] = ''
- else:
- dct[initial_key] = str(obj)
- for filtr in filters:
- dct[initial_key] = filtr(dct[initial_key])
+ _update_gen_id_dct(item, dct, initial_key, fkey, filters=filters)
values = formula.format(**dct).split('||')
value = values[0]
for filtr in values[1:]: