-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScriptResult.py
261 lines (230 loc) · 10.4 KB
/
ScriptResult.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import json
import traceback
EXECUTION_STATE_COMPLETED = 0
EXECUTION_STATE_INPROGRESS = 1
EXECUTION_STATE_FAILED = 2
EXECUTION_STATE_TIMEDOUT = 3
class ScriptResult:
MAX_TOTAL_ATTACHMENT_SIZE = 5 * 1024 * 1024
MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024
def __init__(self, entities, support_old_entities = False):
self._message = None
self._result_value = None
self._result_object = {}
self._total_attachment_size = 0
self._execution_state = EXECUTION_STATE_COMPLETED
self._entities = entities
self.support_old_entities = support_old_entities
@property
def message(self):
return self._message
@message.setter
def message(self, value):
self._message = value
@property
def result_value(self):
return self._result_value
@result_value.setter
def result_value(self, value):
self._result_value = value
@property
def execution_state(self):
return self._execution_state
@execution_state.setter
def execution_state(self, value):
self._execution_state = value
def add_entity_json(self, entity_identifier, json_data, entity_type=None):
"""
add json result with entity identifier as json title
:param entity_identifier: {string} entity identifier
:param json_data: {dict} json data
:param entity_type: {string} entity type
"""
self.add_json(entity_identifier, json_data, entity_type)
def add_result_json(self, json_data):
"""
add json result
:param json_data: {dict} json data
"""
# Must match Siemplify.Common.Consts.ScriptsDynamicResultFirstName
# This is a prepation for dynamic results. In the begining, we have only one, called 'ResultJson'.
# In the future, the names will come from the IDE Screen, like the "Output name", only dynamic
self.add_json("JsonResult", json_data)
def add_json(self, entity_identifier, json_data, entity_type=None):
"""
add json result
:param entity_identifier: {string} entity identifier
:param json_data: {string}/{dict}/{list} If input is json string object, it will be validated. If it's a dictionary or list, it will be json dumped
:param entity_type: {string} entity type
"""
entity_data = self._get_entity_data(entity_identifier, entity_type)
if isinstance(json_data, dict) or isinstance(json_data, list):
# In case we received a list or dict, turn it into json string
try:
json_data = json.dumps(json_data)
except Exception as e:
try:
# try a more lenient approach for serilization. This is not fool proof and may fail as well - str() can have errors
json_data = json.dumps(json_data, default=str)
except Exception as e:
tb = traceback.format_exc()
msg = "Failed to dump json_data with default serilizier and str() as serilizier"
raise Exception(msg, e, tb)
else:
try:
# In case we recevied a string, validate it's JSON serializable
json.loads(json_data)
except ValueError as err:
raise Exception("Passed value is mot JSON serializable, Error: {0}".format(err.message))
except TypeError as err:
raise Exception(
"Expected dictionary, array or JSON serializable string, Error: {0}".format(err.message))
entity_data["RawJson"] = json_data
def add_entity_content(self, entity_identifier, content, entity_type=None):
"""
add content
:param entity_identifier: {string} entity identifier
:param content:
:param entity_type: {string} entity type
"""
self.add_content(entity_identifier, content, entity_type)
def add_content(self, entity_identifier, content, entity_type=None):
"""
add content
:param entity_identifier: {string} entity identifier
:param content:
:param entity_type: {string} entity type
"""
entity_data = self._get_entity_data(entity_identifier, entity_type)
entity_data["Content"] = content
def add_entity_table(self, entity_identifier, data_table, entity_type=None):
"""
add data table with entity identifier as table title
:param entity_identifier: {string} entity identifier
:param data_table: {list} csv formatted list
:param entity_type: {string} entity type
"""
self.add_data_table(entity_identifier, data_table, entity_type)
def add_data_table(self, title, data_table, entity_type=None):
"""
add data table
:param title: {string} table title
:param data_table: {list} csv formatted list
:param entity_type: {string} entity type
"""
entity_data = self._get_entity_data(title, entity_type)
entity_data["CSVLines"] = data_table
def add_entity_attachment(self, entity_identifier, filename, file_contents, additional_data=None, entity_type=None):
"""
add attachment with entity identifier as title
:param entity_identifier: {string} entity identifier
:param filename: {string} file name
:param file_contents: {base64} file content
:param additional_data:
:param entity_type: {string} entity type
"""
self.add_attachment(entity_identifier, filename, file_contents, additional_data, entity_type)
def add_attachment(self, title, filename, file_contents, additional_data=None, entity_type=None):
"""
add attachment
:param title: {string} attachment title
:param filename: {string} file name
:param file_contents: {base64} file content
:param additional_data:
:param entity_type: {string} entity type
:return:
"""
self._validate_attachment_size(len(file_contents))
file_dict = {}
if additional_data is not None:
file_dict.update(additional_data)
file_dict["filename"] = filename
file_dict["file_contents"] = file_contents
entity_data = self._get_entity_data(title, entity_type)
entity_data["Attachments"][filename] = file_contents
self._total_attachment_size += len(file_contents)
def add_entity_html_report(self, entity_identifier, report_name, report_contents, entity_type=None):
"""
add html data with entity identifier as title
:param entity_identifier: {string} entity identifier
:param report_name:{string} html report name
:param report_contents: html content
:param entity_type: {string} entity type
:return:
"""
self.add_html(entity_identifier, report_name, report_contents, entity_type)
def add_html(self, title, report_name, report_contents, entity_type=None):
"""
add html data
:param title: {string} title
:param report_name: {string} html report name
:param report_contents: html content
:param entity_type: {string} entity type
"""
self._validate_attachment_size(len(report_contents))
entity_data = self._get_entity_data(title, entity_type)
entity_data["Htmls"][report_name] = report_contents
def add_entity_link(self, entity_identifier, link, entity_type=None):
"""
add web link with entity identifier as title
:param entity_identifier: {string} entity identifier
:param link: {string} link
:param entity_type: {string} entity type
"""
self.add_link(entity_identifier, link, entity_type)
def add_link(self, title, link, entity_type=None):
"""
add web link
:param title: {string} link title
:param link: {string} link
:param entity_type: {string} entity type
"""
entity_data = self._get_entity_data(title, entity_type)
if "Links" not in entity_data:
entity_data["Links"] = []
entity_data["Links"].append(link)
def _get_entity_data(self, title, entity_type=None):
"""
get entity data
:param title: {string} entity identifier
:return: entity data
:param entity_type: {string} entity type
"""
if not self.support_old_entities:
if not (title, entity_type) in self._result_object:
is_entity = False
if title in [entity[0] for entity in self._entities]:
is_entity = True
self._result_object[(title, entity_type)] = {"Title": title,
"Type": entity_type,
"IsForEntity": is_entity,
"Content": "",
"RawJson": "",
"CSVLines": "",
"Attachments": {},
"Htmls": {}}
return self._result_object[(title, entity_type)]
else:
if title not in self._result_object:
is_entity = False
if title in self._entities:
is_entity = True
self._result_object[title] = {"Title": title,
"IsForEntity": is_entity,
"Content": "",
"RawJson": "",
"CSVLines": "",
"Attachments": {},
"Htmls": {}}
return self._result_object[title]
def _validate_attachment_size(self, attachment_size):
"""
Validate attachment size - limit to 5 MB.
:param attachment_size: {int} attachment file size
"""
if attachment_size > self.MAX_ATTACHMENT_SIZE:
raise EnvironmentError(
"Attachment cannot be larger than %d MB" % int(self.MAX_ATTACHMENT_SIZE / 1024 / 1024))
if attachment_size + self._total_attachment_size > self.MAX_TOTAL_ATTACHMENT_SIZE:
raise EnvironmentError("Total entity attachments cannot be larger than %d MB" % int(
self.MAX_TOTAL_ATTACHMENT_SIZE / 1024 / 1024))