You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.1 KiB
Python
123 lines
3.1 KiB
Python
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import sys
|
|
import threading
|
|
|
|
import halo.cursor as cursor
|
|
|
|
from halo import Halo
|
|
from halo._utils import colored_frame, decode_utf_8_text
|
|
|
|
|
|
class HaloNotebook(Halo):
|
|
def __init__(
|
|
self,
|
|
text="",
|
|
color="cyan",
|
|
text_color=None,
|
|
spinner=None,
|
|
placement="left",
|
|
animation=None,
|
|
interval=-1,
|
|
enabled=True,
|
|
stream=sys.stdout,
|
|
):
|
|
super(HaloNotebook, self).__init__(
|
|
text=text,
|
|
color=color,
|
|
text_color=text_color,
|
|
spinner=spinner,
|
|
placement=placement,
|
|
animation=animation,
|
|
interval=interval,
|
|
enabled=enabled,
|
|
stream=stream,
|
|
)
|
|
self.output = self._make_output_widget()
|
|
|
|
def _make_output_widget(self):
|
|
from ipywidgets.widgets import Output
|
|
|
|
return Output()
|
|
|
|
# TODO: using property and setter
|
|
def _output(self, text=""):
|
|
return ({"name": "stdout", "output_type": "stream", "text": text},)
|
|
|
|
def clear(self):
|
|
if not self.enabled:
|
|
return self
|
|
|
|
with self.output:
|
|
self.output.outputs += self._output("\r")
|
|
self.output.outputs += self._output(self.CLEAR_LINE)
|
|
|
|
self.output.outputs = self._output()
|
|
return self
|
|
|
|
def _render_frame(self):
|
|
frame = self.frame()
|
|
output = "\r{}".format(frame)
|
|
with self.output:
|
|
self.output.outputs += self._output(output)
|
|
|
|
def start(self, text=None):
|
|
if text is not None:
|
|
self.text = text
|
|
|
|
if not self.enabled or self._spinner_id is not None:
|
|
return self
|
|
|
|
if self._stream.isatty():
|
|
cursor.hide()
|
|
|
|
self.output = self._make_output_widget()
|
|
from IPython.display import display
|
|
|
|
display(self.output)
|
|
self._stop_spinner = threading.Event()
|
|
self._spinner_thread = threading.Thread(target=self.render)
|
|
self._spinner_thread.setDaemon(True)
|
|
self._render_frame()
|
|
self._spinner_id = self._spinner_thread.name
|
|
self._spinner_thread.start()
|
|
|
|
return self
|
|
|
|
def stop_and_persist(self, symbol=" ", text=None):
|
|
"""Stops the spinner and persists the final frame to be shown.
|
|
Parameters
|
|
----------
|
|
symbol : str, optional
|
|
Symbol to be shown in final frame
|
|
text: str, optional
|
|
Text to be shown in final frame
|
|
|
|
Returns
|
|
-------
|
|
self
|
|
"""
|
|
if not self.enabled:
|
|
return self
|
|
|
|
symbol = decode_utf_8_text(symbol)
|
|
|
|
if text is not None:
|
|
text = decode_utf_8_text(text)
|
|
else:
|
|
text = self._text["original"]
|
|
|
|
text = text.strip()
|
|
|
|
if self._text_color:
|
|
text = colored_frame(text, self._text_color)
|
|
|
|
self.stop()
|
|
|
|
output = "\r{} {}\n".format(
|
|
*[(text, symbol) if self._placement == "right" else (symbol, text)][0]
|
|
)
|
|
|
|
with self.output:
|
|
self.output.outputs = self._output(output)
|