summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cs2pov/cli.py28
-rw-r--r--cs2pov/loading.py110
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