7 from io
import StringIO
8 from html
import escape
10 from dateutil.relativedelta
import relativedelta
15 A base class for widgets in the hep ipython projects.
28 from IPython.core.display
import display
35 """The css string for styling the notebook."""
53 """Create the styling widget."""
54 from IPython.core.display
import HTML
55 html = HTML(
"<style>\n%s\n</style>" % self.
css_string)
61 Viewer Object used to print data to the IPython Notebook.
62 Do not use it on your own.
67 Create a new progress bar viewer.
69 from IPython.core.display
import display
70 from ipywidgets
import FloatProgress, VBox, Layout, Label
79 layout=Layout(width=
"100%", height=
"40px"))
87 def update(self, text_or_percentage):
89 Update the widget with a new event number
92 if isinstance(text_or_percentage, numbers.Number):
94 current_percentage = float(text_or_percentage)
95 current_time = time.time()
97 remaining_percentage = 1.0 - current_percentage
99 time_delta = current_time - self.
last_time
102 if percentage_delta > 0:
103 time_delta_per_percentage = 1.0 * time_delta / percentage_delta
106 attrs = [
'years',
'months',
'days',
'hours',
'minutes',
'seconds']
108 def human_readable(delta):
return [
'%d %s' % (getattr(delta, attr), getattr(delta, attr) > 1
and attr
or attr[:-1])
109 for attr
in attrs
if getattr(delta, attr)]
111 times_list = human_readable(relativedelta(seconds=time_delta_per_percentage * remaining_percentage))
112 human_readable_str =
" ".join(times_list)
114 display_text =
"%d %% Remaining time: %s" % (
115 100 * current_percentage, human_readable_str)
121 self.
progress_label.value =
"Status: {}".format(text_or_percentage)
122 if "finished" in str(text_or_percentage):
125 elif "failed" in str(text_or_percentage):
134 from IPython.core.display
import display
141 Viewer object for the store entries.
142 Do not use it on your own.
147 Create a new collections viewer with the collections object from the process.
148 Collections must be a StoreContentList with a list of StoreContents.
155 <td style="padding: 10px 0;">{content.number}</td></tr>"""
162 import ipywidgets
as widgets
165 return widgets.HTML(
"")
171 html = widgets.HTML()
172 html.value =
"""<table style="border-collapse: separate; border-spacing: 50px 0;">"""
173 for store_content
in event.content:
175 html.value +=
"</table>"
176 children.append(html)
177 a.set_title(i,
"Event " + str(event.event_number))
179 a.children = children
186 A viewer widget for displaying the
187 statistics in a nicer way in ipython
191 """ Init the widget with the statistics from the process.
192 The statistics must be an instance of Statistics. """
201 self.
table_cell_html =
"""<td style="padding: 10px; text-align: left">{content}</td>"""
203 self.
table_cell_3_html =
"""<td style=\"text-align: right\">{content[0]}</td><td>{content[1]}</td><td>{content[2]}</td>"""
209 import ipywidgets
as widgets
212 return widgets.HTML(
"")
214 html = widgets.HTML()
215 html.value =
"""<table style="border-collapse: collapsed; border: 1px solid black;">
216 <thead><tr style="background: #AAA; font-weight: bold">"""
219 if column.three_column_format:
223 html.value +=
"</tr></thead><tbody>"
225 for n, module
in enumerate(self.
statistics.modules):
227 html.value +=
"""<tr style="background: #EEE;">"""
229 html.value +=
"""<tr>"""
232 if column.three_column_format:
237 html.value +=
"</tr>"
241 html.value +=
"</tbody></table>"
248 A widget to summarize all the infromation from different processes.
249 Must be filled with the widgets of the single processes
254 Create a process viewer
264 import ipywidgets
as widgets
268 a.set_title(i,
"Process " + str(i))
269 a.children = [children.create()
for children
in self.
children if children
is not None]
277 import ipywidgets
as widgets
278 from IPython.core.display
import display
284 a = widgets.HTML(
"<strong>Calculation list empty. Nothing to show.</strong>")
291 A widget to show the log of a calculation.
296 Initialize the log viewer.
303 self.
log_levels = [
"DEBUG",
"INFO",
"RESULT",
"WARNING",
"ERROR",
"FATAL",
"DEFAULT"]
306 self.
log_color_codes = {
"DEBUG":
"gray",
"ERROR":
"red",
"FATAL":
"red",
"INFO":
"black",
"RESULT":
"green",
307 "WARNING":
"orange",
"DEFAULT":
"black"}
310 self.
log_message =
"""<pre class="log-line-{type_lower}" title="{info}">[{level}] {message}{var_output}</pre>"""
314 $('.log-line-{type_lower}-hide-button').hide();
315 $('.log-line-{type_lower}-show-button').show();"
316 style="cursor: pointer; margin: 0px 10px;"
317 class="log-line-{type_lower}-hide-button">Hide {type_upper}</a>
318 <a onclick="$('.log-line-{type_lower}').show();
319 $('.log-line-{type_lower}-hide-button').show();
320 $('.log-line-{type_lower}-show-button').hide();"
321 style="cursor: pointer; margin: 0px 10px; display: none;"
322 class="log-line-{type_lower}-show-button">Show {type_upper}</a>"""
326 Format the json object of a logmessage as key: value list with recursion and indentation
327 Funnily this is faster than json.dumps() and looks a bit better in the title attribute
329 for key, val
in message.items():
332 if isinstance(val, dict):
333 buf.write(f
"{key}:\n")
336 buf.write(base *
" ")
337 buf.write(f
"{key}: {val!r}\n")
341 Create the log viewer.
343 from ipywidgets
import HTML, HBox, VBox
346 output.write(
"<style scoped>\n")
348 level = level.lower()
349 output.write(f
".log-line-{level} {{margin:0; padding:0; line-height:normal; color: {color} !important;}}\n")
351 output.write(
"""</style><div style="max-height: 400px; overflow-y: auto; width: 100%";>""")
354 if line.startswith(
'{"level"'):
356 message = json.loads(line)
363 info = escape(buf.getvalue())
365 variables = message.get(
"variables",
"")
367 variables =
"\n".join([
""] + [f
"\t{k} = {v}" for k, v
in variables.items()])
369 level = message[
"level"].lower()
370 output.write(self.
log_message.format(info=info, type_lower=level, var_output=variables, **message))
372 except json.JSONDecodeError
as e:
376 output.write(
'<pre class="log-line-default">')
378 output.write(
'</pre>')
380 output.write(
"</div>")
383 html.value = output.getvalue()
389 buttons.append(HTML(self.
toggle_button_line.format(type_lower=type.lower(), type_upper=type.upper())))
391 buttons_view = HBox(buttons)
392 buttons_view.margin =
"10px 0px"
393 result_vbox = VBox((buttons_view, html))