diff options
Diffstat (limited to 'ishtar_common/utils.py')
-rw-r--r-- | ishtar_common/utils.py | 92 |
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:]: |