| import itertools
|
| import sys
|
| import time
|
| import threading
|
|
|
|
|
| class StatusLine:
|
| _BAR = "|/-\\"
|
| _DOTS = "ββββ"
|
| _ARROW = "ββββββββ"
|
| _BRAILLE = "β β β Ήβ Έβ Όβ ΄β ¦β §β β "
|
| _CIRCLE = "ββββ"
|
| _DASH = "ββΎβΌβ"
|
|
|
| def __init__(self, delay: float = 0.1):
|
| self._stop = False
|
| self._spinner = itertools.cycle(self._BRAILLE)
|
| self._delay = delay
|
| self.message = ""
|
| self.lock = threading.Lock()
|
| self.thread = threading.Thread(target=self._run, daemon=True)
|
|
|
| def start(self):
|
| self.start_time = time.time()
|
| self.thread.start()
|
|
|
| def stop(self):
|
| self._stop = True
|
| self.thread.join()
|
|
|
| sys.stdout.write("\r" + " " * 80 + "\r")
|
| sys.stdout.flush()
|
|
|
| def update_message(self, msg: str):
|
| with self.lock:
|
| self.message = msg
|
|
|
| def log(self, msg: str):
|
|
|
| sys.stdout.write("\r" + " " * 80 + "\r")
|
| sys.stdout.write(msg + "\n")
|
| sys.stdout.flush()
|
|
|
| def _run(self):
|
| last_logged_message = ""
|
| last_logged_time = -1
|
| is_tty = sys.stdout.isatty()
|
|
|
| while not self._stop:
|
| with self.lock:
|
| spinner_char = next(self._spinner)
|
| now = time.time()
|
| elapsed = int(now - self.start_time)
|
| current_msg = self.message
|
| line = f"[{spinner_char}] {current_msg} | waiting {elapsed}s"
|
|
|
| if is_tty:
|
| sys.stdout.write("\r" + line[:79])
|
| sys.stdout.flush()
|
| else:
|
|
|
|
|
| current_period = int(now) // 30
|
| if current_msg != last_logged_message or (current_period > last_logged_time):
|
| sys.stdout.write(f"{line}\n")
|
| sys.stdout.flush()
|
| last_logged_message = current_msg
|
| last_logged_time = current_period
|
|
|
| time.sleep(self._delay)
|
|
|
|
|
|
|
| if __name__ == "__main__":
|
| status = StatusLine()
|
| status.start()
|
|
|
| for i in range(5):
|
| status.update_message(f"Awaiting {5 - i} batches")
|
| time.sleep(3)
|
| status.log(f"Batch {i + 1} ended!")
|
|
|
| status.stop()
|
| print("Done.")
|
|
|
|
|
| def get_progress_bar():
|
| from rich.progress import (
|
| Progress,
|
| TimeElapsedColumn,
|
| BarColumn,
|
| TaskProgressColumn,
|
| TimeRemainingColumn,
|
| )
|
|
|
| return Progress(
|
| "[progress.description]{task.description}",
|
| BarColumn(),
|
| TaskProgressColumn(),
|
| "[yellow]({task.completed}/{task.total})",
|
| TimeElapsedColumn(),
|
| TimeRemainingColumn(),
|
| )
|
|
|