47 lines
1.2 KiB
Python
47 lines
1.2 KiB
Python
from enum import Enum, auto
|
||
import time
|
||
import threading
|
||
|
||
class Spinner:
|
||
class State(Enum):
|
||
LOADING = auto()
|
||
SUCCESS = '✓'
|
||
FAILURE = '⨯'
|
||
|
||
def __init__(self, text: str):
|
||
self.text = text
|
||
self.state = self.State.LOADING
|
||
|
||
def __enter__(self):
|
||
t = threading.Thread(target = self._thread_fn)
|
||
t.start()
|
||
self.thread = t
|
||
return self
|
||
|
||
def __exit__(self, *_):
|
||
if self.state == self.State.LOADING:
|
||
self.state = self.State.SUCCESS
|
||
if self.thread:
|
||
self.thread.join()
|
||
|
||
def fail(self):
|
||
if self.thread:
|
||
self.state = self.State.FAILURE
|
||
self.thread.join()
|
||
self.thread = None
|
||
|
||
def done(self):
|
||
if self.thread:
|
||
self.state = self.State.SUCCESS
|
||
self.thread.join()
|
||
self.thread = None
|
||
|
||
def _thread_fn(self):
|
||
interval = 80
|
||
spinner = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
||
i = 0
|
||
while self.state == self.State.LOADING:
|
||
i = (i + 1) % len(spinner)
|
||
print(f"\r{spinner[i]} {self.text}", end=' ')
|
||
time.sleep(interval / 1000)
|
||
print(f"\r{self.state.value} {self.text}")
|