77 lines
2.0 KiB
Python
Raw Normal View History

2025-11-04 05:17:27 +01:00
import sys
import time
import threading
class ProgressIndicator:
def __init__(self, message: str = "Working", show: bool = True):
self.message = message
self.show = show
self.running = False
self.thread = None
def __enter__(self):
if self.show:
self.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.show:
self.stop()
def start(self):
self.running = True
self.thread = threading.Thread(target=self._animate, daemon=True)
self.thread.start()
def stop(self):
if self.running:
self.running = False
if self.thread:
self.thread.join(timeout=1.0)
sys.stdout.write('\r' + ' ' * (len(self.message) + 10) + '\r')
sys.stdout.flush()
def _animate(self):
spinner = ['', '', '', '', '', '', '', '', '', '']
idx = 0
while self.running:
sys.stdout.write(f'\r{spinner[idx]} {self.message}...')
sys.stdout.flush()
idx = (idx + 1) % len(spinner)
time.sleep(0.1)
class ProgressBar:
def __init__(self, total: int, description: str = "Progress", width: int = 40):
self.total = total
self.description = description
self.width = width
self.current = 0
def update(self, amount: int = 1):
self.current += amount
self._display()
def _display(self):
if self.total == 0:
percent = 100
else:
percent = int((self.current / self.total) * 100)
filled = int((self.current / self.total) * self.width) if self.total > 0 else self.width
bar = '' * filled + '' * (self.width - filled)
sys.stdout.write(f'\r{self.description}: |{bar}| {percent}% ({self.current}/{self.total})')
sys.stdout.flush()
if self.current >= self.total:
sys.stdout.write('\n')
def finish(self):
self.current = self.total
self._display()