"""
technocloud.sage -- TechnoCloud server emulator
Functions: techno_vars(input_raw), techno_result(res)
techno_vars(input_raw) -- process variables dict as TechnoCloud server does
e.g.:
input_raw = {
'L': ('30', 'number', ''),
'material': ('steel;wood', 'array_string', ';'),
'd': (['16', '45'], 'array_number', ''),
}
input_data = techno_vars(input_raw)
techno_result(res) -- generate html of calculation result
"""
def htmlescape(text):
return str(text).replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"');
def techno_vars(input_raw):
input_data = {}
try:
for varname, vardata in input_raw.iteritems():
val = None
valraw, vartype, delim = vardata
if vartype == 'number':
val = RR(valraw.replace(',', '.').strip())
elif vartype == 'string':
val = str(valraw)
elif vartype == 'boolean':
val = bool(valraw)
elif vartype == 'array_number':
if not isinstance(valraw, list):
if delim == 'NEW_LINE':
valraw = valraw.split("\r\n")
elif delim:
valraw = valraw.split(delim)
else:
valraw = [valraw]
val = [RR(v.replace(',', '.').strip()) for v in valraw]
elif vartype == 'array_string':
if not isinstance(valraw, list):
if delim == 'NEW_LINE':
valraw = valraw.split("\r\n")
elif delim:
valraw = valraw.split(delim)
else:
valraw = [valraw]
val = [v for v in valraw]
else:
raise Exception("Unexpected variable type '{0}'".format(vartype))
input_data[varname] = val
except TypeError:
raise Exception("Wrong value of variable '{0}' (expected {1})".format(varname, vartype))
return input_data
def techno_result(res):
tabs = []
titles = []
for tab, data in enumerate(res):
title = data['title'] if 'title' in data else 'Таблица #' + str(tab)
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>')
html1 = ''
if 'text' in data:
html1 += '<div class="text">' + (htmlescape(data['text'])).replace('\n', '<br>') + '</div>'
if 'html' in data:
html1 += '<div class="text">' + data['html'] + '</div>'
if 'table' in data:
bads = {}
if 'bads' in data and len(data['bads']) > 0:
for i, baddata in enumerate(data['bads']):
if not baddata[0] in bads:
bads[baddata[0]] = {}
bads[baddata[0]][baddata[1]] = baddata[2]
if len(bads) > 0 and 'errors' in data and len(data['errors']) > 0:
html1 += '<div class="errors">'
for eid, error in enumerate(data['errors']):
html1 += '<div data-id="' + str(eid) + '">' + htmlescape(error) + '</div>'
html1 += '</div>'
export = False
if 'export' in data and len(data['export']) > 0:
export = True
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>'
for typ, exp in enumerate(data['export']):
title = exp['title'] if 'title' in exp and len(exp['title']) > 0 else exp['filename']
html1 += '<button type="button" class="btn btn-primary" data-type="' + str(typ) + '" data-loading-text="Экспорт...">Экспорт в ' + htmlescape(title) + '</button>'
html1 += '</div>'
html1 += '<table class="table table-bordered table-condensed">'
if 'head' in data['table']:
maxrows = 1
for i, th in enumerate(data['table']['head']):
if isinstance(th, list) and len(th) > maxrows:
maxrows = len(th)
html1 += '<thead><tr>'
if export:
html1 += '<th' + (' rowspan="' + str(maxrows) + '"' if maxrows > 1 else '') + '></th>'
adds = []
for i, th in enumerate(data['table']['head']):
if isinstance(th, list):
second = th[1]
th = th[0]
if not isinstance(second, list):
second = [second]
span = ' colspan="' + str(len(second)) + '"'
adds += second
else:
span = ' rowspan="' + str(maxrows) + '"'
html1 += '<th' + span + '>' + htmlescape(th) + '</th>'
if len(adds) > 0:
html1 += '</tr><tr>'
for i, add in enumerate(adds):
html1 += '<th>' + htmlescape(add) + '</th>'
html1 += '</tr></thead>'
if 'body' in data['table']:
html1 += '<tbody>'
for row, tr in enumerate(data['table']['body']):
html1 += '<tr' + (' class="bad"' if row in bads else '') + '>'
if export:
html1 += '<td><input type="checkbox" checked="checked" data-id="' + str(row) + '"></td>'
for col, td in enumerate(tr):
html1 += '<td'
if row in bads and col in bads[row]:
html1 += ' class="bad" data-error="' + str(bads[row][col]) + '"'
html1 += '>' + htmlescape(td) + '</td>'
html1 += '</tr>'
html1 += '</tbody>'
html1 += '</table>'
if 'text_after' in data:
html1 += '<div class="text">' + (htmlescape(data['text_after'])).replace('\n', '<br>') + '</div>'
if 'html_after' in data:
html1 += '<div class="text">' + data['html_after'] + '</div>'
tabs.append(html1)
result = '<div class="resheader"><h3>Результат<a id="btnHidebad" class="btn" data-show-text="Показать неподходящие результаты">Скрыть неподходящие результаты</a></h3></div>'
if len(tabs) > 1:
result += '<div role="tabpanel"><ul class="nav nav-tabs" role="tablist" id="restabs">'
result += ''.join(titles)
result += '</ul><div class="tab-content">'
for tab, html1 in enumerate(tabs):
result += '<div role="tabpanel" class="rescontainer tab-pane' + (' active' if tab == 0 else '') + '" id="restab' + str(tab) + '">' + html1 + '</div>'
result += '</div></div>'
else:
result += '<div class="rescontainer">' + tabs.pop(0) + '</div>'
return result