You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.5 KiB
52 lines
1.5 KiB
# Okay, have to admit. This code is from StackOverflow. It's so efficient, that it's probably the best way to do it.
|
|
# Although, it is edited to use less threads.
|
|
|
|
|
|
from itertools import cycle
|
|
from shutil import get_terminal_size
|
|
from threading import Thread
|
|
from time import sleep
|
|
|
|
|
|
class Loader:
|
|
def __init__(self, desc="Loading...", end="Done!", timeout=0.1):
|
|
"""
|
|
A loader-like context manager
|
|
|
|
Args:
|
|
desc (str, optional): The loader's description. Defaults to "Loading...".
|
|
end (str, optional): Final print. Defaults to "Done!".
|
|
timeout (float, optional): Sleep time between prints. Defaults to 0.1.
|
|
"""
|
|
self.desc = desc
|
|
self.end = end
|
|
self.timeout = timeout
|
|
|
|
self._thread = Thread(target=self._animate, daemon=True)
|
|
self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
|
|
self.done = False
|
|
|
|
def start(self):
|
|
self._thread.start()
|
|
return self
|
|
|
|
def _animate(self):
|
|
for c in cycle(self.steps):
|
|
if self.done:
|
|
break
|
|
print(f"\r{self.desc} {c}", flush=True, end="")
|
|
sleep(self.timeout)
|
|
|
|
def __enter__(self):
|
|
self.start()
|
|
|
|
def stop(self):
|
|
self.done = True
|
|
cols = get_terminal_size((80, 20)).columns
|
|
print("\r" + " " * cols, end="", flush=True)
|
|
print(f"\r{self.end}", flush=True)
|
|
|
|
def __exit__(self, exc_type, exc_value, tb):
|
|
# handle exceptions with those variables ^
|
|
self.stop()
|