tricc-oo 1.4.7__tar.gz → 1.4.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/PKG-INFO +4 -3
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/pyproject.toml +2 -2
- tricc_oo-1.4.9/tricc_oo/converters/utils.py +65 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/xml_to_tricc.py +15 -8
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/base.py +3 -3
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/calculate.py +1 -1
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/tricc.py +1 -1
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/base_input_strategy.py +2 -2
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/tricc.py +64 -36
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/PKG-INFO +2 -2
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/requires.txt +1 -1
- tricc_oo-1.4.7/tricc_oo/converters/utils.py +0 -57
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/LICENSE +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/README.md +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/setup.cfg +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/build.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/test_cql.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/to_ocl.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlLexer.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlListener.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlParser.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql_to_operation.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/datadictionnary.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/drawio_type_map.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/lang.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/ocl.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/ordered_set.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/parsers/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/parsers/xml.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/planuml.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/xls_form.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/drawio.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/spice.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xls_form.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/__init__.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/xform_pd.py +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/SOURCES.txt +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/dependency_links.txt +0 -0
- {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: tricc-oo
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.9
|
|
4
4
|
Summary: Python library that converts CDSS L2 in L3
|
|
5
5
|
Project-URL: Homepage, https://github.com/SwissTPH/tricc
|
|
6
6
|
Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
|
|
@@ -9,8 +9,9 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
10
|
Requires-Python: >=3.8
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
12
13
|
Requires-Dist: lxml
|
|
13
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: markdownify
|
|
14
15
|
Requires-Dist: pydantic
|
|
15
16
|
Requires-Dist: babel
|
|
16
17
|
Requires-Dist: xlsxwriter
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tricc-oo"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.9"
|
|
8
8
|
description = "Python library that converts CDSS L2 in L3"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license-files = ["LICENSE"]
|
|
@@ -16,7 +16,7 @@ classifiers = [
|
|
|
16
16
|
]
|
|
17
17
|
dependencies = [
|
|
18
18
|
"lxml",
|
|
19
|
-
"
|
|
19
|
+
"markdownify",
|
|
20
20
|
"pydantic",
|
|
21
21
|
"babel",
|
|
22
22
|
"xlsxwriter",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import re
|
|
3
|
+
import random
|
|
4
|
+
import string
|
|
5
|
+
import hashlib
|
|
6
|
+
from markdownify import markdownify as md
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger("default")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def replace_all(text, list_char, replacement):
|
|
13
|
+
for i in list_char:
|
|
14
|
+
text = text.replace(i, replacement)
|
|
15
|
+
return text
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def clean_str(name, replace_dots=False):
|
|
19
|
+
replacement_list = ["-", " ", ",", "."] if replace_dots else ["-", " ", ","]
|
|
20
|
+
return replace_all(name, replacement_list, "_")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def clean_name(name, prefix="", replace_dots=False):
|
|
24
|
+
name = clean_str(name, replace_dots)
|
|
25
|
+
if name[0].isdigit():
|
|
26
|
+
name = "id_" + name
|
|
27
|
+
elif name[0].isdigit() == "_":
|
|
28
|
+
name = name[1:]
|
|
29
|
+
return name
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def generate_id(name=None, length=18):
|
|
33
|
+
if name:
|
|
34
|
+
h = hashlib.blake2b(digest_size=length)
|
|
35
|
+
h.update(name.encode("utf-8") if isinstance(name, str) else name)
|
|
36
|
+
return h.hexdigest()
|
|
37
|
+
else:
|
|
38
|
+
return "".join(
|
|
39
|
+
random.choices(
|
|
40
|
+
string.ascii_lowercase + string.digits + string.ascii_uppercase,
|
|
41
|
+
k=length,
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_rand_name(name=None, length=8):
|
|
47
|
+
return "n" + generate_id(name=name, length=length)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# the soup.text strips off the html formatting also
|
|
51
|
+
def remove_html(string):
|
|
52
|
+
placeholders = {}
|
|
53
|
+
|
|
54
|
+
def replace_placeholders(match):
|
|
55
|
+
key = f"__PLACEHOLDER_{len(placeholders)}__"
|
|
56
|
+
placeholders[key] = match.group(0)
|
|
57
|
+
return key
|
|
58
|
+
|
|
59
|
+
protected_text = re.sub(r"\${.*?\}", replace_placeholders, string)
|
|
60
|
+
|
|
61
|
+
text = md(protected_text, strip=["img", "table", "a"])
|
|
62
|
+
|
|
63
|
+
for key, original in placeholders.items():
|
|
64
|
+
text = text.replace(key, original)
|
|
65
|
+
return text
|
|
@@ -29,7 +29,11 @@ TRICC_FOLLOW_LABEL = ["follow", "suivre", "continue"]
|
|
|
29
29
|
NO_LABEL = "NO_LABEL"
|
|
30
30
|
TRICC_LIST_NAME = "list_{0}"
|
|
31
31
|
import logging
|
|
32
|
-
|
|
32
|
+
DISPLAY_ATTRIBUTES = [
|
|
33
|
+
'label',
|
|
34
|
+
'hint',
|
|
35
|
+
'help'
|
|
36
|
+
]
|
|
33
37
|
logger = logging.getLogger("default")
|
|
34
38
|
|
|
35
39
|
|
|
@@ -182,7 +186,7 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
182
186
|
if image is not None:
|
|
183
187
|
images.append({"file_path": enriched, "image_content": image})
|
|
184
188
|
|
|
185
|
-
elif isinstance(nodes[edge.target], (TriccNodeActivityEnd, TriccNodeEnd)):
|
|
189
|
+
elif isinstance(nodes[edge.target], (TriccNodeActivityEnd)) or (isinstance(nodes[edge.target], (TriccNodeEnd)) and isinstance(activity.root, TriccNodeMainStart )):
|
|
186
190
|
end_found = True
|
|
187
191
|
if (
|
|
188
192
|
edge.target in nodes
|
|
@@ -236,7 +240,7 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
236
240
|
)
|
|
237
241
|
)
|
|
238
242
|
if not end_found:
|
|
239
|
-
fake_end = TriccNodeActivityEnd(id=generate_id(), activity=activity, group=activity)
|
|
243
|
+
fake_end = TriccNodeActivityEnd(id=generate_id(f"e{activity.name}"), activity=activity, group=activity)
|
|
240
244
|
last_nodes = [
|
|
241
245
|
n for n in list(activity.nodes.values())
|
|
242
246
|
if (
|
|
@@ -486,8 +490,9 @@ def get_max_named_version(calculates, name):
|
|
|
486
490
|
|
|
487
491
|
|
|
488
492
|
def inject_bridge_path(node, nodes):
|
|
489
|
-
|
|
490
|
-
|
|
493
|
+
calc_name = "p" + node.id
|
|
494
|
+
calc_id = generate_id(calc_name)
|
|
495
|
+
|
|
491
496
|
data = {
|
|
492
497
|
"id": calc_id,
|
|
493
498
|
"group": node.group,
|
|
@@ -753,10 +758,12 @@ def set_mandatory_attribute(elm, mandatory_attributes, diagram=None):
|
|
|
753
758
|
exit(1)
|
|
754
759
|
if attributes == "link":
|
|
755
760
|
param[attributes] = clean_link(attribute_value)
|
|
756
|
-
|
|
757
|
-
param[attributes] = attribute_value
|
|
761
|
+
|
|
758
762
|
elif attribute_value is not None:
|
|
759
|
-
|
|
763
|
+
if attributes in DISPLAY_ATTRIBUTES:
|
|
764
|
+
param[attributes] = remove_html(attribute_value.strip())
|
|
765
|
+
else:
|
|
766
|
+
param[attributes] = attribute_value.strip() if isinstance(attribute_value, str) else attribute_value
|
|
760
767
|
return param
|
|
761
768
|
|
|
762
769
|
|
|
@@ -116,7 +116,7 @@ class TriccBaseModel(BaseModel):
|
|
|
116
116
|
def make_instance(self, nb_instance, **kwargs):
|
|
117
117
|
instance = self.copy()
|
|
118
118
|
# change the id to avoid collision of name
|
|
119
|
-
instance.id = generate_id()
|
|
119
|
+
instance.id = generate_id(f"{self.id}{nb_instance}")
|
|
120
120
|
instance.instance = int(nb_instance)
|
|
121
121
|
instance.base_instance = self
|
|
122
122
|
|
|
@@ -149,7 +149,7 @@ class TriccBaseModel(BaseModel):
|
|
|
149
149
|
|
|
150
150
|
def __init__(self, **data):
|
|
151
151
|
if 'id' not in data:
|
|
152
|
-
data['id'] = generate_id()
|
|
152
|
+
data['id'] = generate_id(str(data))
|
|
153
153
|
super().__init__(**data)
|
|
154
154
|
|
|
155
155
|
|
|
@@ -181,7 +181,7 @@ class TriccGroup(TriccBaseModel):
|
|
|
181
181
|
def __init__(self, **data):
|
|
182
182
|
super().__init__(**data)
|
|
183
183
|
if self.name is None:
|
|
184
|
-
self.name = generate_id()
|
|
184
|
+
self.name = generate_id(str(data))
|
|
185
185
|
|
|
186
186
|
def get_name(self):
|
|
187
187
|
result = str(super().get_name())
|
|
@@ -224,7 +224,7 @@ class TriccNodeActivity(TriccNodeBaseModel):
|
|
|
224
224
|
TriccNodeEnd,
|
|
225
225
|
TriccNodeActivityEnd,
|
|
226
226
|
)
|
|
227
|
-
return list(filter(lambda x:
|
|
227
|
+
return list(filter(lambda x: isinstance(x, (TriccNodeActivityEnd)) or (isinstance(x, (TriccNodeEnd)) and isinstance(self.root, TriccNodeMainStart )), self.nodes.values()))
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
|
|
@@ -53,14 +53,14 @@ class BaseInputStrategy:
|
|
|
53
53
|
project.start_pages['determine-diagnosis'] = diags_activity
|
|
54
54
|
root_process = sorted_pages[list(sorted_pages.keys())[0]][0].root
|
|
55
55
|
root = TriccNodeMainStart(
|
|
56
|
-
id=generate_id(),
|
|
56
|
+
id=generate_id('s-determine-diagnosis'),
|
|
57
57
|
form_id=root_process.form_id,
|
|
58
58
|
label=root_process.label
|
|
59
59
|
)
|
|
60
60
|
nodes = {}
|
|
61
61
|
nodes[root.id] = root
|
|
62
62
|
app = TriccNodeActivity(
|
|
63
|
-
id=generate_id(),
|
|
63
|
+
id=generate_id('a-determine-diagnosis'),
|
|
64
64
|
name=root_process.name,
|
|
65
65
|
root=root,
|
|
66
66
|
nodes=nodes
|
|
@@ -115,7 +115,8 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
|
|
|
115
115
|
):
|
|
116
116
|
if kwargs.get('warn', True):
|
|
117
117
|
logger.debug('Processing relevance for node {0}'.format(node.get_name()))
|
|
118
|
-
|
|
118
|
+
node_name = node.name if not isinstance(node, TriccNodeEnd) else 'tricc_end'
|
|
119
|
+
last_version = get_last_version(node_name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase)) and not isinstance(node, TriccNodeSelectOption) else None
|
|
119
120
|
#last_version = processed_nodes.find_prev(node, lambda item: hasattr(item, 'name') and item.name == node.name)
|
|
120
121
|
if last_version:
|
|
121
122
|
# 0-100 for manually specified instance. 100-200 for auto instance
|
|
@@ -128,9 +129,7 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
|
|
|
128
129
|
if (
|
|
129
130
|
issubclass(node.__class__, (TriccNodeDisplayCalculateBase )) and node.name is not None
|
|
130
131
|
):
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
#logger.debug("set last to false for node {} and add its link it to next one".format(last_used_calc.get_name()))
|
|
132
|
+
#logger.debug("set last to false for node {} and add its link it to next one".format(last_used_calc.get_name()))
|
|
134
133
|
if node.prev_nodes:
|
|
135
134
|
set_prev_next_node(last_version, node)
|
|
136
135
|
else:
|
|
@@ -163,7 +162,7 @@ def process_calculate(node,processed_nodes, stashed_nodes, calculates, used_calc
|
|
|
163
162
|
|
|
164
163
|
|
|
165
164
|
calc = TriccNodeCalculate(
|
|
166
|
-
id=generate_id(),
|
|
165
|
+
id=generate_id(f"save{node.id}"),
|
|
167
166
|
name=node.name,
|
|
168
167
|
path_len=node.path_len+1,
|
|
169
168
|
version=last_version.version + 2,
|
|
@@ -305,7 +304,7 @@ def get_max_named_version(calculates,name):
|
|
|
305
304
|
return max
|
|
306
305
|
|
|
307
306
|
def get_count_node(node):
|
|
308
|
-
count_id = generate_id()
|
|
307
|
+
count_id = generate_id(f"count{node.id}")
|
|
309
308
|
count_name = "cnt_"+count_id
|
|
310
309
|
return TriccNodeCount(
|
|
311
310
|
id = count_id,
|
|
@@ -332,7 +331,7 @@ def get_activity_wait(prev_nodes, nodes_to_wait, next_nodes, replaced_node = Non
|
|
|
332
331
|
|
|
333
332
|
activity = activity or prev_node.activity
|
|
334
333
|
calc_node = TriccNodeWait(
|
|
335
|
-
id =
|
|
334
|
+
id = generate_id(f"ar{''.join([x.id for x in nodes_to_wait])}{activity.id}"),
|
|
336
335
|
reference = nodes_to_wait,
|
|
337
336
|
activity = activity,
|
|
338
337
|
group = activity,
|
|
@@ -360,7 +359,7 @@ def get_bridge_path(prev_nodes, node=None,edge_only=False):
|
|
|
360
359
|
p_p_node = next(iterator)
|
|
361
360
|
if node is None:
|
|
362
361
|
node = p_p_node
|
|
363
|
-
calc_id = generate_id()
|
|
362
|
+
calc_id = generate_id(f"br{''.join([x.id for x in prev_nodes])}{node.id}")
|
|
364
363
|
calc_name = "path_"+calc_id
|
|
365
364
|
data = {
|
|
366
365
|
'id': calc_id,
|
|
@@ -479,7 +478,7 @@ def generate_calculates(node,calculates, used_calculates,processed_nodes):
|
|
|
479
478
|
calc_node.name=calculate_name
|
|
480
479
|
calc_node.label = "save select: " +node.get_name()
|
|
481
480
|
else:
|
|
482
|
-
calc_id = generate_id()
|
|
481
|
+
calc_id = generate_id(f"autosave{node.id}")
|
|
483
482
|
calc_node = TriccNodeCalculate(
|
|
484
483
|
name=calculate_name,
|
|
485
484
|
id = calc_id,
|
|
@@ -736,7 +735,7 @@ def add_used_calculate(node, prev_node, calculates, used_calculates, processed_n
|
|
|
736
735
|
|
|
737
736
|
def get_select_not_available_options(node,group,label):
|
|
738
737
|
return {0:TriccNodeSelectOption(
|
|
739
|
-
id = generate_id(),
|
|
738
|
+
id = generate_id(f"notavaialble{node.id}"),
|
|
740
739
|
name="1",
|
|
741
740
|
label=label,
|
|
742
741
|
select = node,
|
|
@@ -746,7 +745,7 @@ def get_select_not_available_options(node,group,label):
|
|
|
746
745
|
|
|
747
746
|
def get_select_yes_no_options(node, group):
|
|
748
747
|
yes = TriccNodeSelectOption(
|
|
749
|
-
id = generate_id(),
|
|
748
|
+
id = generate_id(f'yes{node.id}'),
|
|
750
749
|
name=f"{TRICC_TRUE_VALUE}",
|
|
751
750
|
label="Yes",
|
|
752
751
|
select = node,
|
|
@@ -754,7 +753,7 @@ def get_select_yes_no_options(node, group):
|
|
|
754
753
|
list_name = node.list_name
|
|
755
754
|
)
|
|
756
755
|
no = TriccNodeSelectOption(
|
|
757
|
-
id = generate_id(),
|
|
756
|
+
id = generate_id(f'no{node.id}'),
|
|
758
757
|
name=f"{TRICC_FALSE_VALUE}",
|
|
759
758
|
label="No",
|
|
760
759
|
select = node,
|
|
@@ -1113,21 +1112,38 @@ def check_stashed_loop(stashed_nodes, prev_stashed_nodes, processed_nodes, len_p
|
|
|
1113
1112
|
logger.critical("Stashed node list was unchanged: loop likely or unresolved dependence")
|
|
1114
1113
|
waited, looped = get_all_dependant(stashed_nodes, stashed_nodes, processed_nodes)
|
|
1115
1114
|
logger.debug(f"{len(looped)} nodes waiting stashed nodes")
|
|
1116
|
-
logger.info("
|
|
1117
|
-
for es_node in
|
|
1115
|
+
logger.info("unresolved reference")
|
|
1116
|
+
for es_node in [n for n in stashed_nodes if isinstance(n, TriccReference)]:
|
|
1118
1117
|
logger.info("Stashed node {}:{}|{} {}".format(
|
|
1119
1118
|
es_node.activity.get_name() if hasattr(es_node,'activity') else '' ,
|
|
1120
1119
|
es_node.activity.instance if hasattr(es_node,'activity') else '',
|
|
1121
1120
|
es_node.__class__,
|
|
1122
1121
|
es_node.get_name()))
|
|
1122
|
+
logger.info("looped nodes")
|
|
1123
|
+
for dep_list in looped:
|
|
1124
|
+
for d in looped[dep_list]:
|
|
1125
|
+
if d.get_name() == dep_list:
|
|
1126
|
+
logger.critical("[{}] depends on itself".format(
|
|
1127
|
+
dep_list,
|
|
1128
|
+
))
|
|
1129
|
+
logger.error("[{}] depends on [{}]".format(
|
|
1130
|
+
dep_list, str(d)
|
|
1131
|
+
))
|
|
1132
|
+
if dep_list in waited:
|
|
1133
|
+
for d in waited[dep_list]:
|
|
1134
|
+
logger.warning("[{}] depends on [{}]".format(
|
|
1135
|
+
dep_list, str(d)
|
|
1136
|
+
))
|
|
1137
|
+
|
|
1123
1138
|
#reverse_walkthrough(es_node, es_node, print_trace, processed_nodes, stashed_nodes)
|
|
1124
1139
|
logger.info("waited nodes")
|
|
1125
|
-
for
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1140
|
+
for dep_list in waited:
|
|
1141
|
+
if dep_list not in looped:
|
|
1142
|
+
for d in waited[dep_list]:
|
|
1143
|
+
logger.warning("[{}] depends on [{}]".format(
|
|
1144
|
+
dep_list, d.get_name()
|
|
1145
|
+
))
|
|
1146
|
+
|
|
1131
1147
|
if len(stashed_nodes) == len(prev_stashed_nodes):
|
|
1132
1148
|
exit(1)
|
|
1133
1149
|
else:
|
|
@@ -1136,12 +1152,25 @@ def check_stashed_loop(stashed_nodes, prev_stashed_nodes, processed_nodes, len_p
|
|
|
1136
1152
|
loop_count = 0
|
|
1137
1153
|
return loop_count
|
|
1138
1154
|
|
|
1155
|
+
|
|
1156
|
+
def add_to_tree(tree, n, d):
|
|
1157
|
+
n_str = str(n)
|
|
1158
|
+
if n_str not in tree:
|
|
1159
|
+
tree[n_str] = []
|
|
1160
|
+
if d not in tree[n_str]:
|
|
1161
|
+
tree[n_str].append(d)
|
|
1162
|
+
return tree
|
|
1163
|
+
|
|
1139
1164
|
|
|
1140
|
-
def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=
|
|
1165
|
+
def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=None , looped=None):
|
|
1166
|
+
if looped is None:
|
|
1167
|
+
looped = {}
|
|
1168
|
+
if waited is None:
|
|
1169
|
+
waited = {}
|
|
1141
1170
|
for n in loop:
|
|
1142
1171
|
dependant = OrderedSet()
|
|
1143
1172
|
i=0
|
|
1144
|
-
logger.critical(f"{i}: {n.__class__}::{n.get_name()}::{getattr(n,'instance','')}::{process_reference(n, processed_nodes, [])}")
|
|
1173
|
+
#logger.critical(f"{i}: {n.__class__}::{n.get_name()}::{getattr(n,'instance','')}::{process_reference(n, processed_nodes, [])}")
|
|
1145
1174
|
i += 1
|
|
1146
1175
|
if hasattr(n, 'prev_nodes') and n.prev_nodes:
|
|
1147
1176
|
dependant = dependant | n.prev_nodes
|
|
@@ -1156,16 +1185,15 @@ def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=[] ,
|
|
|
1156
1185
|
if isinstance(d, TriccReference):
|
|
1157
1186
|
if not any(n.name == d.value for n in processed_nodes):
|
|
1158
1187
|
if not any(n.name == d.value for n in stashed_nodes):
|
|
1159
|
-
waited
|
|
1188
|
+
waited = add_to_tree(waited, n, d)
|
|
1160
1189
|
else :
|
|
1161
|
-
looped
|
|
1190
|
+
looped = add_to_tree(looped, n, d)
|
|
1162
1191
|
|
|
1163
1192
|
elif d not in processed_nodes:
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
waited.append(d)
|
|
1193
|
+
if d in stashed_nodes:
|
|
1194
|
+
looped = add_to_tree(looped, n, d)
|
|
1167
1195
|
else :
|
|
1168
|
-
|
|
1196
|
+
waited = add_to_tree(waited, n, d)
|
|
1169
1197
|
if depth < MAX_DRILL:
|
|
1170
1198
|
return get_all_dependant(waited, stashed_nodes, processed_nodes, depth+1, waited , looped)
|
|
1171
1199
|
|
|
@@ -1556,7 +1584,7 @@ def export_proposed_diags(activity, diags=None, **kwargs):
|
|
|
1556
1584
|
|
|
1557
1585
|
def get_accept_diagnostic_node(code, display, severity, activity):
|
|
1558
1586
|
node = TriccNodeAcceptDiagnostic(
|
|
1559
|
-
id=generate_id(),
|
|
1587
|
+
id=generate_id("pre_final." + code),
|
|
1560
1588
|
name="pre_final." + code,
|
|
1561
1589
|
label=display,
|
|
1562
1590
|
list_name="acc_rej",
|
|
@@ -1569,7 +1597,7 @@ def get_accept_diagnostic_node(code, display, severity, activity):
|
|
|
1569
1597
|
|
|
1570
1598
|
def get_diagnostic_node(code, display, severity, activity):
|
|
1571
1599
|
node = TriccNodeAcceptDiagnostic(
|
|
1572
|
-
id=generate_id(),
|
|
1600
|
+
id=generate_id("final." + code),
|
|
1573
1601
|
name="final." + code,
|
|
1574
1602
|
label=display,
|
|
1575
1603
|
list_name="acc_rej",
|
|
@@ -1582,7 +1610,7 @@ def get_diagnostic_node(code, display, severity, activity):
|
|
|
1582
1610
|
|
|
1583
1611
|
def get_select_accept_reject_options(node, group):
|
|
1584
1612
|
yes = TriccNodeSelectOption(
|
|
1585
|
-
id = generate_id(),
|
|
1613
|
+
id = generate_id(f'accept{node.id}'),
|
|
1586
1614
|
name=f"{TRICC_TRUE_VALUE}",
|
|
1587
1615
|
label="Accept",
|
|
1588
1616
|
select = node,
|
|
@@ -1590,7 +1618,7 @@ def get_select_accept_reject_options(node, group):
|
|
|
1590
1618
|
list_name = node.list_name
|
|
1591
1619
|
)
|
|
1592
1620
|
no = TriccNodeSelectOption(
|
|
1593
|
-
id = generate_id(),
|
|
1621
|
+
id = generate_id(f'reject{node.id}'),
|
|
1594
1622
|
name=f"{TRICC_FALSE_VALUE}",
|
|
1595
1623
|
label="Reject",
|
|
1596
1624
|
select = node,
|
|
@@ -1601,13 +1629,13 @@ def get_select_accept_reject_options(node, group):
|
|
|
1601
1629
|
|
|
1602
1630
|
def create_determine_diagnosis_activity(diags):
|
|
1603
1631
|
start = TriccNodeActivityStart(
|
|
1604
|
-
id=generate_id(),
|
|
1632
|
+
id=generate_id('start.determine-diagnosis'),
|
|
1605
1633
|
name="start.determine-diagnosis"
|
|
1606
1634
|
)
|
|
1607
1635
|
|
|
1608
1636
|
|
|
1609
1637
|
activity = TriccNodeActivity(
|
|
1610
|
-
id=generate_id(),
|
|
1638
|
+
id=generate_id('activity-determine-diagnosis'),
|
|
1611
1639
|
name='determine-diagnosis',
|
|
1612
1640
|
label='Diagnosis',
|
|
1613
1641
|
root=start,
|
|
@@ -1619,7 +1647,7 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1619
1647
|
diags_conf = []
|
|
1620
1648
|
r_diags_conf = []
|
|
1621
1649
|
end = TriccNodeActivityEnd(
|
|
1622
|
-
id=generate_id(),
|
|
1650
|
+
id=generate_id("end.determine-diagnosis"),
|
|
1623
1651
|
name="end.determine-diagnosis",
|
|
1624
1652
|
activity=activity,
|
|
1625
1653
|
group=activity,
|
|
@@ -1629,7 +1657,7 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1629
1657
|
d = get_diagnostic_node(proposed.name, proposed.label, proposed.severity, activity)
|
|
1630
1658
|
diags_conf.append(d)
|
|
1631
1659
|
r = TriccNodeRhombus(
|
|
1632
|
-
id=generate_id(),
|
|
1660
|
+
id=generate_id(f"proposed-rhombus{proposed.id}"),
|
|
1633
1661
|
expression_reference=TriccOperation(
|
|
1634
1662
|
TriccOperator.ISTRUE,
|
|
1635
1663
|
[TriccReference(proposed.name)]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tricc-oo
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.9
|
|
4
4
|
Summary: Python library that converts CDSS L2 in L3
|
|
5
5
|
Project-URL: Homepage, https://github.com/SwissTPH/tricc
|
|
6
6
|
Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
|
|
@@ -11,7 +11,7 @@ Requires-Python: >=3.8
|
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: lxml
|
|
14
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: markdownify
|
|
15
15
|
Requires-Dist: pydantic
|
|
16
16
|
Requires-Dist: babel
|
|
17
17
|
Requires-Dist: xlsxwriter
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import random
|
|
3
|
-
import string
|
|
4
|
-
import hashlib
|
|
5
|
-
import html2text
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger("default")
|
|
10
|
-
|
|
11
|
-
def replace_all(text, list_char, replacement):
|
|
12
|
-
for i in list_char:
|
|
13
|
-
text = text.replace(i, replacement)
|
|
14
|
-
return text
|
|
15
|
-
|
|
16
|
-
def clean_str(name, replace_dots=False):
|
|
17
|
-
replacement_list = ['-', ' ', ',', '.'] if replace_dots else ['-', ' ', ',']
|
|
18
|
-
return replace_all(name, replacement_list,'_')
|
|
19
|
-
|
|
20
|
-
def clean_name( name, prefix='', replace_dots=False):
|
|
21
|
-
name = clean_str(name, replace_dots)
|
|
22
|
-
if name[0].isdigit():
|
|
23
|
-
name = 'id_' + name
|
|
24
|
-
elif name[0].isdigit() == '_':
|
|
25
|
-
name = name[1:]
|
|
26
|
-
return name
|
|
27
|
-
|
|
28
|
-
def generate_id(name=None, length=18):
|
|
29
|
-
if name:
|
|
30
|
-
h = hashlib.blake2b(digest_size=length)
|
|
31
|
-
h.update(name.encode('utf-8') if isinstance(name, str) else name)
|
|
32
|
-
return h.hexdigest()
|
|
33
|
-
else:
|
|
34
|
-
return ''.join(random.choices(string.ascii_lowercase + string.digits + string.ascii_uppercase, k=length))
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_rand_name(name=None, length=8):
|
|
38
|
-
return "n" + generate_id(name=name, length=length)
|
|
39
|
-
|
|
40
|
-
# the soup.text strips off the html formatting also
|
|
41
|
-
def remove_html(string):
|
|
42
|
-
h = html2text.HTML2Text()
|
|
43
|
-
h.body_width = 0 # Prevents line wrapping
|
|
44
|
-
h.ignore_links = True # Ignores any link processing
|
|
45
|
-
h.ignore_images = True # Ignores image processing
|
|
46
|
-
h.ignore_tables = True # Ignores table formatting
|
|
47
|
-
text = h.handle(string).rstrip() # rstrip()
|
|
48
|
-
text = text.strip('\n') # get rid of empty lines at the end (and beginning)
|
|
49
|
-
text = text.split('\n') # split string into a list at new lines
|
|
50
|
-
text = '\n'.join([i.strip(' ') for i in text if i]) # in each element in that list strip empty space (at the end of line)
|
|
51
|
-
# and delete empty lines
|
|
52
|
-
return text
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|