14 from io
import StringIO
15 from html
import escape
17 from dateutil.relativedelta
import relativedelta
22 A base class for widgets in the hep ipython projects.
35 from IPython.core.display
import display
42 """The css string for styling the notebook."""
60 """Create the styling widget."""
61 from IPython.core.display
import HTML
62 html = HTML(
"<style>\n%s\n</style>" % self.
css_stringcss_string)
68 Viewer Object used to print data to the IPython Notebook.
69 Do not use it on your own.
74 Create a new progress bar viewer.
76 from IPython.core.display
import display
77 from ipywidgets
import FloatProgress, VBox, Layout, Label
85 self.
progress_barprogress_bar = FloatProgress(value=0, min=0, max=1,
86 layout=Layout(width=
"100%", height=
"40px"))
94 def update(self, text_or_percentage):
96 Update the widget with a new event number
99 if isinstance(text_or_percentage, numbers.Number):
101 current_percentage = float(text_or_percentage)
102 current_time = time.time()
104 remaining_percentage = 1.0 - current_percentage
106 time_delta = current_time - self.
last_timelast_time
107 percentage_delta = current_percentage - self.
last_percentagelast_percentage
109 if percentage_delta > 0:
110 time_delta_per_percentage = 1.0 * time_delta / percentage_delta
113 attrs = [
'years',
'months',
'days',
'hours',
'minutes',
'seconds']
115 def human_readable(delta):
return [
'%d %s' % (getattr(delta, attr), getattr(delta, attr) > 1
and attr
or attr[:-1])
116 for attr
in attrs
if getattr(delta, attr)]
118 times_list = human_readable(relativedelta(seconds=time_delta_per_percentage * remaining_percentage))
119 human_readable_str =
" ".join(times_list)
121 display_text =
"%d %% Remaining time: %s" % (
122 100 * current_percentage, human_readable_str)
125 self.
progress_barprogress_bar.value = float(current_percentage)
128 self.
progress_labelprogress_label.value = f
"Status: {text_or_percentage}"
129 if "finished" in str(text_or_percentage):
132 elif "failed" in str(text_or_percentage):
141 from IPython.core.display
import display
148 Viewer object for the store entries.
149 Do not use it on your own.
154 Create a new collections viewer with the collections object from the process.
155 Collections must be a StoreContentList with a list of StoreContents.
161 self.
table_row_htmltable_row_html =
"""<tr><td style="padding: 10px 0;">{content.name}</td>
162 <td style="padding: 10px 0;">{content.number}</td></tr>"""
169 import ipywidgets
as widgets
172 return widgets.HTML(
"")
177 for i, event
in enumerate(self.
collectionscollections):
178 html = widgets.HTML()
179 html.value =
"""<table style="border-collapse: separate; border-spacing: 50px 0;">"""
180 for store_content
in event.content:
181 html.value += self.
table_row_htmltable_row_html.format(content=store_content)
182 html.value +=
"</table>"
183 children.append(html)
184 a.set_title(i,
"Event " + str(event.event_number))
186 a.children = children
193 A viewer widget for displaying the
194 statistics in a nicer way in ipython
198 """ Init the widget with the statistics from the process.
199 The statistics must be an instance of Statistics. """
208 self.
table_cell_htmltable_cell_html =
"""<td style="padding: 10px; text-align: left">{content}</td>"""
210 self.
table_cell_3_htmltable_cell_3_html =
"""<td style=\"text-align: right\">{content[0]}</td><td>{content[1]}</td><td>{content[2]}</td>"""
216 import ipywidgets
as widgets
219 return widgets.HTML(
"")
221 html = widgets.HTML()
222 html.value =
"""<table style="border-collapse: collapsed; border: 1px solid black;">
223 <thead><tr style="background: #AAA; font-weight: bold">"""
225 for column
in self.
statisticsstatistics.columns:
226 if column.three_column_format:
227 html.value += self.
table_column_3_htmltable_column_3_html.format(content=column.display_name)
229 html.value += self.
table_column_htmltable_column_html.format(content=column.display_name)
230 html.value +=
"</tr></thead><tbody>"
232 for n, module
in enumerate(self.
statisticsstatistics.modules):
234 html.value +=
"""<tr style="background: #EEE;">"""
236 html.value +=
"""<tr>"""
238 for column
in self.
statisticsstatistics.columns:
239 if column.three_column_format:
240 html.value += self.
table_cell_3_htmltable_cell_3_html.format(content=module[column.name])
242 html.value += self.
table_cell_htmltable_cell_html.format(content=module[column.name])
244 html.value +=
"</tr>"
248 html.value +=
"</tbody></table>"
255 A widget to summarize all the infromation from different processes.
256 Must be filled with the widgets of the single processes
261 Create a process viewer
271 import ipywidgets
as widgets
274 for i
in range(len(self.
childrenchildren)):
275 a.set_title(i,
"Process " + str(i))
276 a.children = [children.create()
for children
in self.
childrenchildren
if children
is not None]
284 import ipywidgets
as widgets
285 from IPython.core.display
import display
291 a = widgets.HTML(
"<strong>Calculation list empty. Nothing to show.</strong>")
298 A widget to show the log of a calculation.
303 Initialize the log viewer.
310 self.
log_levelslog_levels = [
"DEBUG",
"INFO",
"RESULT",
"WARNING",
"ERROR",
"FATAL",
"DEFAULT"]
313 self.
log_color_codeslog_color_codes = {
"DEBUG":
"gray",
"ERROR":
"red",
"FATAL":
"red",
"INFO":
"black",
"RESULT":
"green",
314 "WARNING":
"orange",
"DEFAULT":
"black"}
317 self.
log_messagelog_message =
"""<pre class="log-line-{type_lower}" title="{info}">[{level}] {message}{var_output}</pre>"""
321 $('.log-line-{type_lower}-hide-button').hide();
322 $('.log-line-{type_lower}-show-button').show();"
323 style="cursor: pointer; margin: 0px 10px;"
324 class="log-line-{type_lower}-hide-button">Hide {type_upper}</a>
325 <a onclick="$('.log-line-{type_lower}').show();
326 $('.log-line-{type_lower}-hide-button').show();
327 $('.log-line-{type_lower}-show-button').hide();"
328 style="cursor: pointer; margin: 0px 10px; display: none;"
329 class="log-line-{type_lower}-show-button">Show {type_upper}</a>"""
333 Format the json object of a logmessage as key: value list with recursion and indentation
334 Funnily this is faster than json.dumps() and looks a bit better in the title attribute
336 for key, val
in message.items():
339 if isinstance(val, dict):
340 buf.write(f
"{key}:\n")
341 self.
format_logmessageformat_logmessage(buf, val, indent=indent, base=base + indent)
343 buf.write(base *
" ")
344 buf.write(f
"{key}: {val!r}\n")
348 Create the log viewer.
350 from ipywidgets
import HTML, HBox, VBox
353 output.write(
"<style scoped>\n")
355 level = level.lower()
356 output.write(f
".log-line-{level} {{margin:0; padding:0; line-height:normal; color: {color} !important;}}\n")
358 output.write(
"""</style><div style="max-height: 400px; overflow-y: auto; width: 100%";>""")
360 for line
in self.
log_contentlog_content.split(
"\n"):
361 if line.startswith(
'{"level"'):
363 message = json.loads(line)
370 info = escape(buf.getvalue())
372 variables = message.get(
"variables",
"")
374 variables =
"\n".join([
""] + [f
"\t{k} = {v}" for k, v
in variables.items()])
376 level = message[
"level"].lower()
377 output.write(self.
log_messagelog_message.format(info=info, type_lower=level, var_output=variables, **message))
379 except json.JSONDecodeError:
383 output.write(
'<pre class="log-line-default">')
385 output.write(
'</pre>')
387 output.write(
"</div>")
390 html.value = output.getvalue()
396 buttons.append(HTML(self.
toggle_button_linetoggle_button_line.format(type_lower=type.lower(), type_upper=type.upper())))
398 buttons_view = HBox(buttons)
399 buttons_view.margin =
"10px 0px"
400 result_vbox = VBox((buttons_view, html))