Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Project: TechnoCloud
Views: 149
1
"""
2
technocloud.sage -- TechnoCloud server emulator
3
Functions: techno_vars(input_raw), techno_result(res)
4
5
techno_vars(input_raw) -- process variables dict as TechnoCloud server does
6
e.g.:
7
input_raw = {
8
'L': ('30', 'number', ''),
9
'material': ('steel;wood', 'array_string', ';'),
10
'd': (['16', '45'], 'array_number', ''),
11
}
12
input_data = techno_vars(input_raw)
13
14
techno_result(res) -- generate html of calculation result
15
16
"""
17
18
# Author: Nikita Konovalov
19
20
def htmlescape(text):
21
return str(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;');
22
23
def techno_vars(input_raw):
24
input_data = {}
25
try:
26
for varname, vardata in input_raw.iteritems():
27
val = None
28
valraw, vartype, delim = vardata
29
if vartype == 'number':
30
val = RR(valraw.replace(',', '.').strip())
31
elif vartype == 'string':
32
val = str(valraw)
33
elif vartype == 'boolean':
34
val = bool(valraw)
35
elif vartype == 'array_number':
36
if not isinstance(valraw, list):
37
if delim == 'NEW_LINE':
38
valraw = valraw.split("\r\n")
39
elif delim:
40
valraw = valraw.split(delim)
41
else:
42
valraw = [valraw]
43
val = [RR(v.replace(',', '.').strip()) for v in valraw]
44
elif vartype == 'array_string':
45
if not isinstance(valraw, list):
46
if delim == 'NEW_LINE':
47
valraw = valraw.split("\r\n")
48
elif delim:
49
valraw = valraw.split(delim)
50
else:
51
valraw = [valraw]
52
val = [v for v in valraw]
53
else:
54
raise Exception("Unexpected variable type '{0}'".format(vartype))
55
input_data[varname] = val
56
except TypeError:
57
raise Exception("Wrong value of variable '{0}' (expected {1})".format(varname, vartype))
58
return input_data
59
60
def techno_result(res):
61
tabs = []
62
titles = []
63
for tab, data in enumerate(res):
64
title = data['title'] if 'title' in data else 'Таблица #' + str(tab)
65
titles.append('<li role="presentation" ' + ('class="active"' if tab == 0 else '') + '><a href="#restab' + str(tab) + '" aria-controls="restab' + str(tab) + '" role="tab" data-toggle="tab">' + htmlescape(title) + '</a></li>')
66
html1 = ''
67
if 'text' in data:
68
html1 += '<div class="text">' + (htmlescape(data['text'])).replace('\n', '<br>') + '</div>'
69
if 'html' in data:
70
html1 += '<div class="text">' + data['html'] + '</div>'
71
if 'table' in data:
72
bads = {}
73
if 'bads' in data and len(data['bads']) > 0:
74
for i, baddata in enumerate(data['bads']):
75
if not baddata[0] in bads:
76
bads[baddata[0]] = {}
77
bads[baddata[0]][baddata[1]] = baddata[2]
78
if len(bads) > 0 and 'errors' in data and len(data['errors']) > 0:
79
html1 += '<div class="errors">'
80
for eid, error in enumerate(data['errors']):
81
html1 += '<div data-id="' + str(eid) + '">' + htmlescape(error) + '</div>'
82
html1 += '</div>'
83
export = False
84
if 'export' in data and len(data['export']) > 0:
85
export = True
86
html1 += '<div class="btnsExport"><div class="btn-group"><button type="button" class="btn btn-default btnSelectall">Выбрать все</button><button type="button" class="btn btn-default btnSelectgood">Выбрать подходящие</button><button type="button" class="btn btn-default btnClear">Очистить выбор</button></div>'
87
for typ, exp in enumerate(data['export']):
88
title = exp['title'] if 'title' in exp and len(exp['title']) > 0 else exp['filename']
89
html1 += '<button type="button" class="btn btn-primary" data-type="' + str(typ) + '" data-loading-text="Экспорт...">Экспорт в ' + htmlescape(title) + '</button>'
90
html1 += '</div>'
91
html1 += '<table class="table table-bordered table-condensed">'
92
if 'head' in data['table']:
93
maxrows = 1
94
for i, th in enumerate(data['table']['head']):
95
if isinstance(th, list) and len(th) > maxrows:
96
maxrows = len(th)
97
html1 += '<thead><tr>'
98
if export:
99
html1 += '<th' + (' rowspan="' + str(maxrows) + '"' if maxrows > 1 else '') + '></th>'
100
adds = []
101
for i, th in enumerate(data['table']['head']):
102
if isinstance(th, list):
103
second = th[1]
104
th = th[0]
105
if not isinstance(second, list):
106
second = [second]
107
span = ' colspan="' + str(len(second)) + '"'
108
adds += second
109
else:
110
span = ' rowspan="' + str(maxrows) + '"'
111
html1 += '<th' + span + '>' + htmlescape(th) + '</th>'
112
if len(adds) > 0:
113
html1 += '</tr><tr>'
114
for i, add in enumerate(adds):
115
html1 += '<th>' + htmlescape(add) + '</th>'
116
html1 += '</tr></thead>'
117
if 'body' in data['table']:
118
html1 += '<tbody>'
119
for row, tr in enumerate(data['table']['body']):
120
html1 += '<tr' + (' class="bad"' if row in bads else '') + '>'
121
if export:
122
html1 += '<td><input type="checkbox" checked="checked" data-id="' + str(row) + '"></td>'
123
for col, td in enumerate(tr):
124
html1 += '<td'
125
if row in bads and col in bads[row]:
126
html1 += ' class="bad" data-error="' + str(bads[row][col]) + '"'
127
html1 += '>' + htmlescape(td) + '</td>'
128
html1 += '</tr>'
129
html1 += '</tbody>'
130
html1 += '</table>'
131
if 'text_after' in data:
132
html1 += '<div class="text">' + (htmlescape(data['text_after'])).replace('\n', '<br>') + '</div>'
133
if 'html_after' in data:
134
html1 += '<div class="text">' + data['html_after'] + '</div>'
135
tabs.append(html1)
136
result = '<div class="resheader"><h3>Результат<a id="btnHidebad" class="btn" data-show-text="Показать неподходящие результаты">Скрыть неподходящие результаты</a></h3></div>'
137
if len(tabs) > 1:
138
result += '<div role="tabpanel"><ul class="nav nav-tabs" role="tablist" id="restabs">'
139
result += ''.join(titles)
140
result += '</ul><div class="tab-content">'
141
for tab, html1 in enumerate(tabs):
142
result += '<div role="tabpanel" class="rescontainer tab-pane' + (' active' if tab == 0 else '') + '" id="restab' + str(tab) + '">' + html1 + '</div>'
143
result += '</div></div>'
144
else:
145
result += '<div class="rescontainer">' + tabs.pop(0) + '</div>'
146
return result
147
148