tricc-oo 1.0.1__py3-none-any.whl → 1.4.15__py3-none-any.whl
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.
- tests/build.py +213 -0
- tests/test_cql.py +197 -0
- tests/to_ocl.py +51 -0
- {tricc → tricc_oo}/__init__.py +3 -1
- tricc_oo/converters/codesystem_to_ocl.py +169 -0
- tricc_oo/converters/cql/cqlLexer.py +822 -0
- tricc_oo/converters/cql/cqlListener.py +1632 -0
- tricc_oo/converters/cql/cqlParser.py +11204 -0
- tricc_oo/converters/cql/cqlVisitor.py +913 -0
- tricc_oo/converters/cql_to_operation.py +402 -0
- tricc_oo/converters/datadictionnary.py +115 -0
- tricc_oo/converters/drawio_type_map.py +222 -0
- tricc_oo/converters/tricc_to_xls_form.py +61 -0
- tricc_oo/converters/utils.py +65 -0
- tricc_oo/converters/xml_to_tricc.py +1003 -0
- tricc_oo/models/__init__.py +4 -0
- tricc_oo/models/base.py +732 -0
- tricc_oo/models/calculate.py +216 -0
- tricc_oo/models/ocl.py +281 -0
- tricc_oo/models/ordered_set.py +125 -0
- tricc_oo/models/tricc.py +418 -0
- tricc_oo/parsers/xml.py +138 -0
- tricc_oo/serializers/__init__.py +0 -0
- tricc_oo/serializers/xls_form.py +745 -0
- tricc_oo/strategies/__init__.py +0 -0
- tricc_oo/strategies/input/__init__.py +0 -0
- tricc_oo/strategies/input/base_input_strategy.py +111 -0
- tricc_oo/strategies/input/drawio.py +317 -0
- tricc_oo/strategies/output/base_output_strategy.py +148 -0
- tricc_oo/strategies/output/spice.py +365 -0
- tricc_oo/strategies/output/xls_form.py +697 -0
- tricc_oo/strategies/output/xlsform_cdss.py +189 -0
- tricc_oo/strategies/output/xlsform_cht.py +200 -0
- tricc_oo/strategies/output/xlsform_cht_hf.py +334 -0
- tricc_oo/visitors/__init__.py +0 -0
- tricc_oo/visitors/tricc.py +2198 -0
- tricc_oo/visitors/utils.py +17 -0
- tricc_oo/visitors/xform_pd.py +264 -0
- tricc_oo-1.4.15.dist-info/METADATA +219 -0
- tricc_oo-1.4.15.dist-info/RECORD +46 -0
- {tricc_oo-1.0.1.dist-info → tricc_oo-1.4.15.dist-info}/WHEEL +1 -1
- tricc_oo-1.4.15.dist-info/top_level.txt +2 -0
- tricc/converters/mc_to_tricc.py +0 -542
- tricc/converters/tricc_to_xls_form.py +0 -553
- tricc/converters/utils.py +0 -44
- tricc/converters/xml_to_tricc.py +0 -740
- tricc/models/tricc.py +0 -1093
- tricc/parsers/xml.py +0 -81
- tricc/serializers/xls_form.py +0 -364
- tricc/strategies/input/base_input_strategy.py +0 -80
- tricc/strategies/input/drawio.py +0 -246
- tricc/strategies/input/medalcreator.py +0 -168
- tricc/strategies/output/base_output_strategy.py +0 -92
- tricc/strategies/output/xls_form.py +0 -194
- tricc/strategies/output/xlsform_cdss.py +0 -46
- tricc/strategies/output/xlsform_cht.py +0 -106
- tricc/visitors/tricc.py +0 -375
- tricc_oo-1.0.1.dist-info/LICENSE +0 -78
- tricc_oo-1.0.1.dist-info/METADATA +0 -229
- tricc_oo-1.0.1.dist-info/RECORD +0 -26
- tricc_oo-1.0.1.dist-info/top_level.txt +0 -2
- venv/bin/vba_extract.py +0 -78
- {tricc → tricc_oo}/converters/__init__.py +0 -0
- {tricc → tricc_oo}/models/lang.py +0 -0
- {tricc/serializers → tricc_oo/parsers}/__init__.py +0 -0
- {tricc → tricc_oo}/serializers/planuml.py +0 -0
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
|
|
3
|
+
from tricc_oo.models import (
|
|
4
|
+
TriccNodeMainStart,
|
|
5
|
+
TriccNodeActivity,
|
|
6
|
+
TriccEdge,
|
|
7
|
+
)
|
|
8
|
+
from tricc_oo.converters.utils import generate_id
|
|
9
|
+
from tricc_oo.visitors.tricc import (
|
|
10
|
+
get_activity_wait,
|
|
11
|
+
stashed_node_func,
|
|
12
|
+
set_prev_next_node,
|
|
13
|
+
export_proposed_diags,
|
|
14
|
+
create_determine_diagnosis_activity
|
|
15
|
+
)
|
|
16
|
+
from itertools import chain
|
|
17
|
+
import logging
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("default")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BaseInputStrategy:
|
|
23
|
+
input_path = None
|
|
24
|
+
project = None
|
|
25
|
+
processes = ["main"]
|
|
26
|
+
|
|
27
|
+
def execute_linked_process(self, project):
|
|
28
|
+
# create an overall activity only if not specified
|
|
29
|
+
if "main" not in project.start_pages:
|
|
30
|
+
page_processes = [(p.root.process, p,) for p in list(project.pages.values()) if getattr(p.root, 'process', None)]
|
|
31
|
+
sorted_pages = {}
|
|
32
|
+
diags = []
|
|
33
|
+
for a in project.pages.values():
|
|
34
|
+
diags += export_proposed_diags(a, [])
|
|
35
|
+
seen_diags = set()
|
|
36
|
+
unique_diags = []
|
|
37
|
+
for diag in diags:
|
|
38
|
+
if diag.name not in seen_diags:
|
|
39
|
+
unique_diags.append(diag)
|
|
40
|
+
seen_diags.add(diag.name)
|
|
41
|
+
severity_order = { "severe": 3, "moderate": 2, "mild":1, 'light': 0}
|
|
42
|
+
unique_diags = sorted(unique_diags, key=lambda x: (-getattr(severity_order, x.severity or 'light', 0), x.label))
|
|
43
|
+
for process in self.processes:
|
|
44
|
+
if process in [p[0] for p in page_processes]:
|
|
45
|
+
sorted_pages[process] = [
|
|
46
|
+
p[1] for p in page_processes if p[0] == process
|
|
47
|
+
]
|
|
48
|
+
elif process == 'determine-diagnosis' and diags:
|
|
49
|
+
diags_activity = create_determine_diagnosis_activity(unique_diags)
|
|
50
|
+
sorted_pages[process] = [
|
|
51
|
+
diags_activity
|
|
52
|
+
]
|
|
53
|
+
project.start_pages['determine-diagnosis'] = diags_activity
|
|
54
|
+
root_process = sorted_pages[list(sorted_pages.keys())[0]][0].root
|
|
55
|
+
root = TriccNodeMainStart(
|
|
56
|
+
id=generate_id('s-determine-diagnosis'),
|
|
57
|
+
form_id=root_process.form_id,
|
|
58
|
+
label=root_process.label,
|
|
59
|
+
process='main'
|
|
60
|
+
)
|
|
61
|
+
nodes = {}
|
|
62
|
+
nodes[root.id] = root
|
|
63
|
+
app = TriccNodeActivity(
|
|
64
|
+
id=generate_id('a-determine-diagnosis'),
|
|
65
|
+
name=root_process.name,
|
|
66
|
+
root=root,
|
|
67
|
+
nodes=nodes
|
|
68
|
+
)
|
|
69
|
+
root.activity = app
|
|
70
|
+
# loop back to app to avoid None
|
|
71
|
+
app.activity = app
|
|
72
|
+
app.group = app
|
|
73
|
+
# setting the activity/group to main
|
|
74
|
+
prev_bridge = root
|
|
75
|
+
prev_process = None
|
|
76
|
+
for process in sorted_pages:
|
|
77
|
+
nodes = {page.id: page for page in sorted_pages[process]}
|
|
78
|
+
if prev_process:
|
|
79
|
+
prev_bridge = get_activity_wait(
|
|
80
|
+
prev_bridge,
|
|
81
|
+
sorted_pages[prev_process],
|
|
82
|
+
nodes.values(),
|
|
83
|
+
activity=app,
|
|
84
|
+
)
|
|
85
|
+
else:
|
|
86
|
+
for a in nodes:
|
|
87
|
+
set_prev_next_node(
|
|
88
|
+
prev_bridge,
|
|
89
|
+
a,
|
|
90
|
+
edge_only=True
|
|
91
|
+
)
|
|
92
|
+
app.nodes[prev_bridge.id] = prev_bridge
|
|
93
|
+
|
|
94
|
+
for n in nodes.values():
|
|
95
|
+
n.activity = app
|
|
96
|
+
n.group = app
|
|
97
|
+
app.nodes[n.id] = n
|
|
98
|
+
prev_process = process
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
return app
|
|
102
|
+
else:
|
|
103
|
+
return project.start_pages["main"]
|
|
104
|
+
|
|
105
|
+
def __init__(self, input_path):
|
|
106
|
+
self.input_path = input_path
|
|
107
|
+
|
|
108
|
+
### walking function
|
|
109
|
+
@abc.abstractmethod
|
|
110
|
+
def execute(in_filepath, media_path):
|
|
111
|
+
pass
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import json
|
|
4
|
+
from copy import copy
|
|
5
|
+
|
|
6
|
+
from tricc_oo.converters.xml_to_tricc import create_activity
|
|
7
|
+
from tricc_oo.visitors.tricc import (
|
|
8
|
+
process_calculate,
|
|
9
|
+
set_prev_next_node,
|
|
10
|
+
replace_node,
|
|
11
|
+
stashed_node_func,
|
|
12
|
+
TriccProject
|
|
13
|
+
)
|
|
14
|
+
from tricc_oo.visitors.utils import PROCESSES
|
|
15
|
+
from tricc_oo.converters.codesystem_to_ocl import transform_fhir_to_ocl
|
|
16
|
+
|
|
17
|
+
from tricc_oo.models import *
|
|
18
|
+
from tricc_oo.strategies.input.base_input_strategy import BaseInputStrategy
|
|
19
|
+
from tricc_oo.parsers.xml import read_drawio
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger("default")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DrawioStrategy(BaseInputStrategy):
|
|
25
|
+
|
|
26
|
+
processes = PROCESSES
|
|
27
|
+
|
|
28
|
+
def process_pages(self, start_page, project):
|
|
29
|
+
# create the graph
|
|
30
|
+
self.linking_nodes(start_page.root, start_page, project.pages)
|
|
31
|
+
# Save the calculate list [node]
|
|
32
|
+
calculates = {}
|
|
33
|
+
# save when a calcualte is used dict[name, Dict[id, node]]
|
|
34
|
+
used_calculates = {}
|
|
35
|
+
|
|
36
|
+
# save the node that are processed dict[id, node]
|
|
37
|
+
|
|
38
|
+
# add save nodes and merge nodes
|
|
39
|
+
stashed_node_func(
|
|
40
|
+
start_page.root,
|
|
41
|
+
process_calculate,
|
|
42
|
+
used_calculates=used_calculates,
|
|
43
|
+
calculates=calculates,
|
|
44
|
+
recursive=False,
|
|
45
|
+
codesystems=project.code_systems,
|
|
46
|
+
process=[start_page.root.process]
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
logger.info("# check if all edges (arrow) where used")
|
|
50
|
+
for key, page in project.pages.items():
|
|
51
|
+
if page.unused_edges is not None and len(page.unused_edges) > 0:
|
|
52
|
+
logger.warning(
|
|
53
|
+
"Page {0} has still {1}/{2} edges that were not used:".format(
|
|
54
|
+
page.label, len(page.unused_edges), len(page.edges)
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
# refresh the edges (were remove by previous code)
|
|
58
|
+
|
|
59
|
+
def execute(self, file_content, media_path):
|
|
60
|
+
project = TriccProject()
|
|
61
|
+
files = []
|
|
62
|
+
diagrams = []
|
|
63
|
+
# read all project.pages
|
|
64
|
+
logger.info("# Create the activities from diagram project.pages")
|
|
65
|
+
# if os.path.isdir(in_filepath):
|
|
66
|
+
# files = [f for f in os.listdir(in_filepath) if f.endswith('.drawio')]
|
|
67
|
+
# elif os.path.isfile(in_filepath):
|
|
68
|
+
# files = [in_filepath]
|
|
69
|
+
# else:
|
|
70
|
+
# logger.critical(f"no input file found at {in_filepath}")
|
|
71
|
+
# exit(1)
|
|
72
|
+
# for file in files:
|
|
73
|
+
images_diagram = []
|
|
74
|
+
for f in file_content:
|
|
75
|
+
file_diagrams = read_drawio(f)
|
|
76
|
+
diagrams += file_diagrams
|
|
77
|
+
for diagram in file_diagrams:
|
|
78
|
+
old_page_len = len(project.pages)
|
|
79
|
+
id_tab = diagram.attrib.get("id")
|
|
80
|
+
name_tab = diagram.attrib.get("name")
|
|
81
|
+
if id_tab in project.pages:
|
|
82
|
+
logger.critical(f"{id_tab} diagram (drawio tab) already loaded (Duplicate diagram ID ?)")
|
|
83
|
+
exit(1)
|
|
84
|
+
logger.info("Create the activity {0}::{1}".format(
|
|
85
|
+
id_tab, name_tab))
|
|
86
|
+
|
|
87
|
+
create_activity(
|
|
88
|
+
diagram, media_path, project)
|
|
89
|
+
if len(project.pages) == old_page_len:
|
|
90
|
+
logger.error(f"diagram {id_tab}::{name_tab} was not loaded properly")
|
|
91
|
+
logger.info("# Create the graph from the start node")
|
|
92
|
+
for k, v in project.code_systems.items():
|
|
93
|
+
with open(os.path.join(os.path.dirname(media_path), f"{k}_codesystem.json"), "w", encoding='utf-8') as file:
|
|
94
|
+
file.write(v.json(indent=4))
|
|
95
|
+
|
|
96
|
+
for k, v in project.value_sets.items():
|
|
97
|
+
with open(os.path.join(os.path.dirname(media_path), f"{k}_valueset.json"), "w") as file:
|
|
98
|
+
file.write(v.json(indent=4))
|
|
99
|
+
app = self.execute_linked_process(project)
|
|
100
|
+
if app:
|
|
101
|
+
project.start_pages["main"] = app
|
|
102
|
+
project.pages[app.id] = app
|
|
103
|
+
self.process_pages(app, project)
|
|
104
|
+
|
|
105
|
+
return project
|
|
106
|
+
elif project.start_pages:
|
|
107
|
+
for process in project.start_pages:
|
|
108
|
+
if isinstance(project.start_pages[process], list):
|
|
109
|
+
for page_to_process in project.start_pages[process]:
|
|
110
|
+
self.process_pages(page_to_process, project.pages)
|
|
111
|
+
else:
|
|
112
|
+
self.process_pages(project.start_pages[process], project.pages)
|
|
113
|
+
return project
|
|
114
|
+
return None
|
|
115
|
+
# Q. how to handle graph output
|
|
116
|
+
# hardlink with out edge: create a fake node
|
|
117
|
+
# or should we always create that fake node
|
|
118
|
+
# *** or should we enfore "next activity node" ****
|
|
119
|
+
#
|
|
120
|
+
|
|
121
|
+
# do the calculation, expression ...
|
|
122
|
+
|
|
123
|
+
def linking_nodes(self, node, page, pages, processed_nodes=OrderedSet(), path=[]):
|
|
124
|
+
# get the edges that have that node as source
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
node_edge = list(
|
|
128
|
+
filter(lambda x: (
|
|
129
|
+
(x.source_external_id and x.source_external_id == node.external_id) or
|
|
130
|
+
( x.source and x.source == node.id) or
|
|
131
|
+
x.source == node
|
|
132
|
+
), page.edges)
|
|
133
|
+
)
|
|
134
|
+
node.activity = page
|
|
135
|
+
# build current path
|
|
136
|
+
current_path = path + [node.id]
|
|
137
|
+
# don't stop the walkthroug by default
|
|
138
|
+
for edge in node_edge:
|
|
139
|
+
# get target node
|
|
140
|
+
if edge.target in page.nodes:
|
|
141
|
+
target_node = page.nodes[edge.target]
|
|
142
|
+
# link perv / next nodes
|
|
143
|
+
# walk only if the target node was not processed already
|
|
144
|
+
if target_node not in processed_nodes:
|
|
145
|
+
if isinstance(target_node, TriccNodeActivity):
|
|
146
|
+
self.linking_nodes(
|
|
147
|
+
target_node.root,
|
|
148
|
+
target_node,
|
|
149
|
+
pages,
|
|
150
|
+
processed_nodes,
|
|
151
|
+
current_path,
|
|
152
|
+
)
|
|
153
|
+
for c in target_node.calculates:
|
|
154
|
+
if len(c.prev_nodes) == 0:
|
|
155
|
+
self.linking_nodes(
|
|
156
|
+
c,
|
|
157
|
+
target_node,
|
|
158
|
+
pages,
|
|
159
|
+
processed_nodes,
|
|
160
|
+
current_path,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
elif isinstance(target_node, TriccNodeGoTo):
|
|
164
|
+
next_page = self.walkthrough_goto_node(
|
|
165
|
+
target_node, page, pages, processed_nodes, current_path
|
|
166
|
+
)
|
|
167
|
+
for n in page.nodes:
|
|
168
|
+
sn = page.nodes[n]
|
|
169
|
+
if (
|
|
170
|
+
issubclass(sn.__class__, TriccRhombusMixIn)
|
|
171
|
+
and isinstance(sn.reference, list)
|
|
172
|
+
and target_node in sn.reference
|
|
173
|
+
):
|
|
174
|
+
sn.reference.remove(target_node)
|
|
175
|
+
sn.reference.append(next_page)
|
|
176
|
+
# set next page as node to link the next_node of the activity
|
|
177
|
+
if next_page is not None:
|
|
178
|
+
target_node = next_page
|
|
179
|
+
elif isinstance(target_node, TriccNodeLinkOut):
|
|
180
|
+
link_out = self.walkthrough_link_out_node(
|
|
181
|
+
target_node, page, pages, processed_nodes, current_path
|
|
182
|
+
)
|
|
183
|
+
if link_out is not None:
|
|
184
|
+
target_node = link_out
|
|
185
|
+
elif isinstance(node, TriccNodeMoreInfo):
|
|
186
|
+
|
|
187
|
+
if target_node.name == node.parent.name:
|
|
188
|
+
node.parent = target_node
|
|
189
|
+
if issubclass(target_node.__class__, TriccNodeSelect):
|
|
190
|
+
for key, option in target_node.options.items():
|
|
191
|
+
self.linking_nodes(
|
|
192
|
+
option, page, pages, processed_nodes, current_path
|
|
193
|
+
)
|
|
194
|
+
processed_nodes.add(target_node)
|
|
195
|
+
logger.debug("{}::{}: processed ({})".format(
|
|
196
|
+
'linking_nodes', target_node.get_name(), len(processed_nodes)))
|
|
197
|
+
self.linking_nodes(
|
|
198
|
+
target_node, page, pages, processed_nodes, current_path
|
|
199
|
+
)
|
|
200
|
+
elif edge.target in current_path:
|
|
201
|
+
logger.error(
|
|
202
|
+
"possible loop detected for node {0} in page {1}; path:".format(
|
|
203
|
+
node.get_name(), page.label
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
for node_id in current_path:
|
|
207
|
+
node = get_node_from_list(processed_nodes, node_id)
|
|
208
|
+
if node is not None:
|
|
209
|
+
logger.warning(node.get_name())
|
|
210
|
+
if isinstance(node, TriccNodeSelectNotAvailable):
|
|
211
|
+
set_prev_next_node(node.options[0], target_node)
|
|
212
|
+
else:
|
|
213
|
+
set_prev_next_node(node, target_node)
|
|
214
|
+
else:
|
|
215
|
+
logger.error(
|
|
216
|
+
"target not found {0} for node {1}".format(
|
|
217
|
+
edge.target, node.get_name()
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
# page.edges.remove(edge)
|
|
221
|
+
|
|
222
|
+
def walkthrough_goto_node(self, node, page, pages, processed_nodes, current_path):
|
|
223
|
+
# find the page
|
|
224
|
+
if node.link in pages:
|
|
225
|
+
next_page = pages[node.link]
|
|
226
|
+
# walk thought the next page
|
|
227
|
+
max_instance = 1
|
|
228
|
+
if node.instance == 0 or next_page.root.instance == 0:
|
|
229
|
+
for other_page in next_page.instances.values():
|
|
230
|
+
if int(other_page.instance) > int(max_instance):
|
|
231
|
+
max_instance = other_page.instance
|
|
232
|
+
# auto instance starts at 101
|
|
233
|
+
next_page = next_page.make_instance(max(100, max_instance) + 1)
|
|
234
|
+
else:
|
|
235
|
+
# return existing instance if any
|
|
236
|
+
next_page = next_page.make_instance(node.instance)
|
|
237
|
+
if next_page.id not in pages:
|
|
238
|
+
pages[next_page.id] = next_page
|
|
239
|
+
logger.debug(
|
|
240
|
+
"jumping to page {0}::{1} from {2}".format(
|
|
241
|
+
next_page.label, next_page.instance, node.get_name()
|
|
242
|
+
)
|
|
243
|
+
)
|
|
244
|
+
if next_page not in processed_nodes:
|
|
245
|
+
self.linking_nodes(
|
|
246
|
+
next_page.root, next_page, pages, processed_nodes, current_path
|
|
247
|
+
)
|
|
248
|
+
for c in next_page.calculates:
|
|
249
|
+
if len(c.prev_nodes) == 0:
|
|
250
|
+
self.linking_nodes(
|
|
251
|
+
c,
|
|
252
|
+
next_page,
|
|
253
|
+
pages,
|
|
254
|
+
processed_nodes,
|
|
255
|
+
current_path,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
processed_nodes.add(next_page)
|
|
259
|
+
|
|
260
|
+
replace_node(node, next_page, page)
|
|
261
|
+
|
|
262
|
+
# continue on the initial page
|
|
263
|
+
return next_page
|
|
264
|
+
else:
|
|
265
|
+
logger.critical(
|
|
266
|
+
"node {0} from page {1} doesnot have a valid link: {2}".format(
|
|
267
|
+
node.label, page.label, node.link
|
|
268
|
+
)
|
|
269
|
+
)
|
|
270
|
+
exit(1)
|
|
271
|
+
|
|
272
|
+
def walkthrough_link_out_node(
|
|
273
|
+
self, node, page, pages, processed_nodes, current_path
|
|
274
|
+
):
|
|
275
|
+
if node.reference is not None:
|
|
276
|
+
link_in_list = []
|
|
277
|
+
link_in_page = None
|
|
278
|
+
for page in pages:
|
|
279
|
+
link_in_list += list(
|
|
280
|
+
filter(lambda x: (x.name == node.reference), page.nodes)
|
|
281
|
+
)
|
|
282
|
+
# save the first page where a link is found to continue the walktrhough
|
|
283
|
+
if len(link_in_list) > 0 and link_in_page is None:
|
|
284
|
+
link_in_page = page
|
|
285
|
+
if len(link_in_list) == 0:
|
|
286
|
+
logger.warning(
|
|
287
|
+
"link in {0} not found for link out {1} in page {2}".format(
|
|
288
|
+
node.reference, node.name, page.label
|
|
289
|
+
)
|
|
290
|
+
)
|
|
291
|
+
elif len(link_in_list) > 1:
|
|
292
|
+
logger.warning(
|
|
293
|
+
"more than one link in {0} found for link out {1} in page {2}".format(
|
|
294
|
+
node.reference, node.name, page.label
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
else:
|
|
298
|
+
# all good, only one target node found
|
|
299
|
+
linked_target_node = link_in_list[0]
|
|
300
|
+
# steal the edges
|
|
301
|
+
replace_node(node, linked_target_node, page)
|
|
302
|
+
|
|
303
|
+
if linked_target_node not in processed_nodes:
|
|
304
|
+
self.linking_nodes(
|
|
305
|
+
linked_target_node,
|
|
306
|
+
link_in_page,
|
|
307
|
+
project.pages,
|
|
308
|
+
processed_nodes,
|
|
309
|
+
current_path,
|
|
310
|
+
)
|
|
311
|
+
return linked_target_node
|
|
312
|
+
else:
|
|
313
|
+
logger.warning(
|
|
314
|
+
"link out {0} in page {1} : reference not found".format(
|
|
315
|
+
node.name, page.label
|
|
316
|
+
)
|
|
317
|
+
)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import logging
|
|
3
|
+
from tricc_oo.visitors.tricc import stashed_node_func
|
|
4
|
+
import datetime
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger('default')
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseOutPutStrategy:
|
|
10
|
+
processes = ['main']
|
|
11
|
+
project = None
|
|
12
|
+
output_path = None
|
|
13
|
+
# list of supported processes for the strategy,
|
|
14
|
+
# the order of the list will be apply
|
|
15
|
+
|
|
16
|
+
def __init__(self, project, output_path):
|
|
17
|
+
self.output_path = output_path
|
|
18
|
+
self.project = project
|
|
19
|
+
|
|
20
|
+
def get_tricc_operation_expression(self, operation):
|
|
21
|
+
raise NotImplemented("get_tricc_operation_expression not implemented")
|
|
22
|
+
|
|
23
|
+
def execute(self):
|
|
24
|
+
|
|
25
|
+
version = datetime.datetime.now().strftime("%Y%m%d%H%M")
|
|
26
|
+
logger.info(f"build version: {version}")
|
|
27
|
+
if 'main' in self.project.start_pages:
|
|
28
|
+
self.process_base(self.project.start_pages, pages=self.project.pages, version=version)
|
|
29
|
+
else:
|
|
30
|
+
logger.critical("Main process required")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
logger.info("generate the relevance based on edges")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# create relevance Expression
|
|
38
|
+
|
|
39
|
+
# create calculate Expression
|
|
40
|
+
self.process_calculate(self.project.start_pages, pages=self.project.pages)
|
|
41
|
+
logger.info("generate the export format")
|
|
42
|
+
# create calculate Expression
|
|
43
|
+
self.process_export(self.project.start_pages, pages=self.project.pages)
|
|
44
|
+
|
|
45
|
+
logger.info("print the export")
|
|
46
|
+
|
|
47
|
+
self.export(self.project.start_pages, version=version)
|
|
48
|
+
|
|
49
|
+
### walking function
|
|
50
|
+
def process_base(self, start_pages, **kwargs):
|
|
51
|
+
# for each node, check if condition is required issubclass(TriccNodeDisplayModel)
|
|
52
|
+
# process name
|
|
53
|
+
stashed_node_func(start_pages[self.processes[0]].root, self.generate_base, **{**self.get_kwargs(),**kwargs} )
|
|
54
|
+
self.do_clean( **{**self.get_kwargs(),**kwargs})
|
|
55
|
+
|
|
56
|
+
def process_relevance(self, start_pages, **kwargs):
|
|
57
|
+
|
|
58
|
+
stashed_node_func(start_pages[self.processes[0]].root, self.generate_relevance, **{**self.get_kwargs(),**kwargs} )
|
|
59
|
+
self.do_clean( **{**self.get_kwargs(),**kwargs})
|
|
60
|
+
|
|
61
|
+
def process_calculate(self, start_pages, **kwargs):
|
|
62
|
+
# call the strategy specific code
|
|
63
|
+
stashed_node_func(start_pages[self.processes[0]].root, self.generate_calculate, **{**self.get_kwargs(),**kwargs} )
|
|
64
|
+
self.do_clean(**{**self.get_kwargs(),**kwargs})
|
|
65
|
+
|
|
66
|
+
def process_export(self, start_pages, **kwargs):
|
|
67
|
+
stashed_node_func(start_pages[self.processes[0]].root, self.generate_export, **{**self.get_kwargs(),**kwargs} )
|
|
68
|
+
self.do_clean(**{**self.get_kwargs(),**kwargs})
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# node function
|
|
72
|
+
@abc.abstractmethod
|
|
73
|
+
def generate_calculate(self, node, **kwargs ):
|
|
74
|
+
pass
|
|
75
|
+
@abc.abstractmethod
|
|
76
|
+
def generate_base(self, node, **kwargs):
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@abc.abstractmethod
|
|
81
|
+
def generate_relevance(self, node, **kwargs):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@abc.abstractmethod
|
|
86
|
+
def generate_export(self, node, **kwargs):
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
@abc.abstractmethod
|
|
90
|
+
def export(self, **kwargs):
|
|
91
|
+
pass
|
|
92
|
+
def tricc_operation_equal(self, ref_expressions):
|
|
93
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
94
|
+
def tricc_operation_not_equal(self, ref_expressions):
|
|
95
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
96
|
+
def tricc_operation_not(self, ref_expressions):
|
|
97
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
98
|
+
def tricc_operation_and(self, ref_expressions):
|
|
99
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
100
|
+
def tricc_operation_or(self, ref_expressions):
|
|
101
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
102
|
+
def tricc_operation_or_and(self, ref_expressions):
|
|
103
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
104
|
+
def tricc_operation_native(self, ref_expressions):
|
|
105
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
106
|
+
def tricc_operation_istrue(self, ref_expressions):
|
|
107
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
108
|
+
def tricc_operation_isfalse(self, ref_expressions):
|
|
109
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
110
|
+
def tricc_operation_selected(self, ref_expressions):
|
|
111
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
112
|
+
def tricc_operation_more_or_equal(self, ref_expressions):
|
|
113
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
114
|
+
def tricc_operation_less_or_equal(self, ref_expressions):
|
|
115
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
116
|
+
def tricc_operation_more(self, ref_expressions):
|
|
117
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
118
|
+
def tricc_operation_less(self, ref_expressions):
|
|
119
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
120
|
+
def tricc_operation_between(self, ref_expressions):
|
|
121
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
122
|
+
def tricc_operation_case(self, ref_expressions):
|
|
123
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
124
|
+
def tricc_operation_if(self, ref_expressions):
|
|
125
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
126
|
+
def tricc_operation_contains(self, ref_expressions):
|
|
127
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
128
|
+
def tricc_operation_exists(self, ref_expressions):
|
|
129
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
130
|
+
def tricc_operation_has_qualifier(self, ref_expressions):
|
|
131
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
132
|
+
def tricc_operation_zscore(self, ref_expressions):
|
|
133
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
134
|
+
def tricc_operation_izscore(self, ref_expressions):
|
|
135
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
136
|
+
def tricc_operation_age_day(self, ref_expressions):
|
|
137
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
138
|
+
def tricc_operation_age_month(self, ref_expressions):
|
|
139
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
140
|
+
def tricc_operation_age_year(self, ref_expressions):
|
|
141
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
142
|
+
def tricc_operation_concatenate(self, ref_expressions):
|
|
143
|
+
raise NotImplementedError(f"This type of opreration is not supported in this strategy")
|
|
144
|
+
## Utils
|
|
145
|
+
def do_clean(self, **kwargs):
|
|
146
|
+
pass
|
|
147
|
+
def get_kwargs(self):
|
|
148
|
+
return {}
|