diff options
| author | Schark <jordan@schark.online> | 2026-01-31 01:23:11 -0500 |
|---|---|---|
| committer | Schark <jordan@schark.online> | 2026-01-31 01:23:11 -0500 |
| commit | 340db0b5d1a76cbacd1e2e86138b02066ea84185 (patch) | |
| tree | 5a50dc01d41bd9c678af42e367548e4c132ab97e | |
| parent | 456230fbd46907744a8aff7dc36787247d98c8d1 (diff) | |
| download | cs2pov-340db0b5d1a76cbacd1e2e86138b02066ea84185.tar.gz cs2pov-340db0b5d1a76cbacd1e2e86138b02066ea84185.zip | |
Added loading module, fun stuff
| -rw-r--r-- | cs2pov/cli.py | 28 | ||||
| -rw-r--r-- | cs2pov/loading.py | 110 |
2 files changed, 125 insertions, 13 deletions
diff --git a/cs2pov/cli.py b/cs2pov/cli.py index 0d2ec26..f307032 100644 --- a/cs2pov/cli.py +++ b/cs2pov/cli.py @@ -19,6 +19,7 @@ from typing import Optional from . import __version__ from .automation import send_key, check_demo_ended, wait_for_cs2_window, wait_for_demo_ready, parse_demo_end_info +from .loading import LoadingAnimation from .capture import FFmpegCapture, get_default_audio_monitor from .config import RecordingConfig, generate_recording_cfg from .exceptions import CS2POVError @@ -800,20 +801,21 @@ def cmd_info(args) -> int: return 1 # Parse basic demo info - try: - demo_info = parse_demo(demo_path) - except CS2POVError as e: - print(f"Error: {e}", file=sys.stderr) - return 1 - - # Preprocess for timeline data (per-player) - player_timelines: dict[int, DemoTimeline] = {} - for player in demo_info.players: + with LoadingAnimation(): try: - timeline = preprocess_demo(demo_path, player.steamid, player.name) - player_timelines[player.steamid] = timeline - except Exception: - pass + demo_info = parse_demo(demo_path) + except CS2POVError as e: + print(f"Error: {e}", file=sys.stderr) + return 1 + + # Preprocess for timeline data (per-player) + player_timelines: dict[int, DemoTimeline] = {} + for player in demo_info.players: + try: + timeline = preprocess_demo(demo_path, player.steamid, player.name) + player_timelines[player.steamid] = timeline + except Exception: + pass if args.json: output = format_info_json(demo_info, player_timelines) diff --git a/cs2pov/loading.py b/cs2pov/loading.py new file mode 100644 index 0000000..6f3c1c6 --- /dev/null +++ b/cs2pov/loading.py @@ -0,0 +1,110 @@ +"""Loading animation with CS-themed messages.""" + +import random +import sys +import threading +import time + +# ============================================================================= +# Loading Messages (add more here!) +# ============================================================================= + +LOADING_MESSAGES = [ + "Bingo bango bongo", + "Bish bash bosh", + "Fire in the hole", + "It's going to explode", + "Inhuman reactions", + "How does he do this", + "Trying to build pyramids", + "This is not FPL", + "The flames come in", + "Starting to get nervous", + "Refusing to surrender", +] + +# ============================================================================= +# ANSI Color Codes +# ============================================================================= + +DIM = "\033[2m" # Dim/faint text +RESET = "\033[0m" # Reset all attributes +CLEAR_LINE = "\033[2K\r" # Clear line and return to start + + +class LoadingAnimation: + """Animated loading message that oscillates periods. + + Usage: + with LoadingAnimation(): + do_slow_work() + + Or manually: + loader = LoadingAnimation() + loader.start() + do_slow_work() + loader.stop() + """ + + def __init__(self, message: str | None = None, min_dots: int = 1, max_dots: int = 5): + """Initialize the loading animation. + + Args: + message: Custom message, or None to pick randomly from LOADING_MESSAGES + min_dots: Minimum number of dots (default 1) + max_dots: Maximum number of dots (default 5) + """ + self.message = message or random.choice(LOADING_MESSAGES) + self.min_dots = min_dots + self.max_dots = max_dots + self._stop_event = threading.Event() + self._thread: threading.Thread | None = None + + def _animate(self): + """Animation loop running in background thread.""" + dots = self.min_dots + direction = 1 # 1 = increasing, -1 = decreasing + + while not self._stop_event.is_set(): + # Build the display string + dot_str = "." * dots + display = f"{DIM}{self.message}{dot_str}{RESET}" + + # Clear line and print (no newline) + sys.stderr.write(f"{CLEAR_LINE}{display}") + sys.stderr.flush() + + # Update dot count + dots += direction + if dots >= self.max_dots: + direction = -1 + elif dots <= self.min_dots: + direction = 1 + + # Wait before next frame + self._stop_event.wait(0.3) + + # Clear the line when done + sys.stderr.write(CLEAR_LINE) + sys.stderr.flush() + + def start(self): + """Start the animation.""" + self._stop_event.clear() + self._thread = threading.Thread(target=self._animate, daemon=True) + self._thread.start() + + def stop(self): + """Stop the animation and clear the line.""" + self._stop_event.set() + if self._thread: + self._thread.join(timeout=1.0) + self._thread = None + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.stop() + return False |
