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

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)