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.
Files changed (52) hide show
  1. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/PKG-INFO +4 -3
  2. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/pyproject.toml +2 -2
  3. tricc_oo-1.4.9/tricc_oo/converters/utils.py +65 -0
  4. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/xml_to_tricc.py +15 -8
  5. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/base.py +3 -3
  6. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/calculate.py +1 -1
  7. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/tricc.py +1 -1
  8. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/base_input_strategy.py +2 -2
  9. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/tricc.py +64 -36
  10. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/PKG-INFO +2 -2
  11. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/requires.txt +1 -1
  12. tricc_oo-1.4.7/tricc_oo/converters/utils.py +0 -57
  13. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/LICENSE +0 -0
  14. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/README.md +0 -0
  15. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/setup.cfg +0 -0
  16. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/build.py +0 -0
  17. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/test_cql.py +0 -0
  18. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tests/to_ocl.py +0 -0
  19. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/__init__.py +0 -0
  20. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/__init__.py +0 -0
  21. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  22. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  23. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlListener.py +0 -0
  24. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlParser.py +0 -0
  25. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  26. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/cql_to_operation.py +0 -0
  27. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/datadictionnary.py +0 -0
  28. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/drawio_type_map.py +0 -0
  29. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  30. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/__init__.py +0 -0
  31. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/lang.py +0 -0
  32. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/ocl.py +0 -0
  33. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/models/ordered_set.py +0 -0
  34. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/parsers/__init__.py +0 -0
  35. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/parsers/xml.py +0 -0
  36. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/__init__.py +0 -0
  37. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/planuml.py +0 -0
  38. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/serializers/xls_form.py +0 -0
  39. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/__init__.py +0 -0
  40. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/__init__.py +0 -0
  41. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/input/drawio.py +0 -0
  42. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  43. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/spice.py +0 -0
  44. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xls_form.py +0 -0
  45. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  46. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
  47. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  48. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/__init__.py +0 -0
  49. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo/visitors/xform_pd.py +0 -0
  50. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/SOURCES.txt +0 -0
  51. {tricc_oo-1.4.7 → tricc_oo-1.4.9}/tricc_oo.egg-info/dependency_links.txt +0 -0
  52. {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.4
1
+ Metadata-Version: 2.3
2
2
  Name: tricc-oo
3
- Version: 1.4.7
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: html2text
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"
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
- "html2text",
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
- calc_id = generate_id()
490
- calc_name = "path_" + calc_id
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
- elif attributes in ("parent", "id", "source", "target"):
757
- param[attributes] = attribute_value
761
+
758
762
  elif attribute_value is not None:
759
- param[attributes] = remove_html(attribute_value.strip())
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())
@@ -102,7 +102,7 @@ class TriccRhombusMixIn():
102
102
  exit(1)
103
103
  instance.reference = reference
104
104
  instance.expression_reference = expression_reference
105
- instance.name = get_rand_name()
105
+ instance.name = get_rand_name(self.id)
106
106
  return instance
107
107
 
108
108
 
@@ -224,7 +224,7 @@ class TriccNodeActivity(TriccNodeBaseModel):
224
224
  TriccNodeEnd,
225
225
  TriccNodeActivityEnd,
226
226
  )
227
- return list(filter(lambda x: issubclass(x.__class__, (TriccNodeEnd,TriccNodeActivityEnd)), self.nodes.values()))
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
- last_version = get_last_version(node.name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase)) and not isinstance(node, TriccNodeSelectOption) else None
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
- node_name = node.name if not isinstance(node, TriccNodeEnd) else 'tricc_end'
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 = "ar_"+generate_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("looped nodes")
1117
- for es_node in looped:
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 es_node in waited:
1126
- logger.info("Stashed node {}:{}|{} {}".format(
1127
- es_node.activity.get_name() if hasattr(es_node,'activity') else '' ,
1128
- es_node.activity.instance if hasattr(es_node,'activity') else '',
1129
- es_node.__class__,
1130
- es_node.get_name()))
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=[] , looped=[]):
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.append(d)
1188
+ waited = add_to_tree(waited, n, d)
1160
1189
  else :
1161
- looped.append(d)
1190
+ looped = add_to_tree(looped, n, d)
1162
1191
 
1163
1192
  elif d not in processed_nodes:
1164
-
1165
- if d not in stashed_nodes:
1166
- waited.append(d)
1193
+ if d in stashed_nodes:
1194
+ looped = add_to_tree(looped, n, d)
1167
1195
  else :
1168
- looped.append(d)
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.7
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: html2text
14
+ Requires-Dist: markdownify
15
15
  Requires-Dist: pydantic
16
16
  Requires-Dist: babel
17
17
  Requires-Dist: xlsxwriter
@@ -1,5 +1,5 @@
1
1
  lxml
2
- html2text
2
+ markdownify
3
3
  pydantic
4
4
  babel
5
5
  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