refactor(linux_configuration): fix ruff violations in digital wellbeing and transcription scripts

- Add type annotations and docstrings to focus_mode_daemon.py, transcribe_fw.py, transcribe_helpers.py
- Use logging module instead of print
- Fix bare except clauses with specific exception types
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-03-13 20:42:39 +01:00
parent 0460f3fac6
commit 4d3da460fc
4 changed files with 1175 additions and 617 deletions

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Focus Mode Daemon - Steam/Browser Mutual Exclusion """Focus Mode Daemon - Steam/Browser Mutual Exclusion.
This daemon monitors running processes and enforces mutual exclusion between This daemon monitors running processes and enforces mutual exclusion between
Steam (gaming) and web browsers. Whichever starts first "wins" and the other Steam (gaming) and web browsers. Whichever starts first "wins" and the other
@ -8,17 +8,27 @@ category is blocked/killed.
Run as a systemd user service for continuous monitoring. Run as a systemd user service for continuous monitoring.
""" """
from datetime import datetime from __future__ import annotations
import os
import contextlib
from datetime import datetime, timezone
import logging
from pathlib import Path from pathlib import Path
import shutil
import signal import signal
import subprocess import subprocess
import sys import sys
import time import time
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from types import FrameType
logger = logging.getLogger(__name__)
# Configuration # Configuration
STATE_DIR = ( STATE_DIR = (
Path(os.environ.get("XDG_STATE_HOME", Path.home() / ".local/state")) / "focus-mode" Path.home() / ".local" / "state" / "focus-mode"
) )
LOG_FILE = STATE_DIR / "focus-mode.log" LOG_FILE = STATE_DIR / "focus-mode.log"
POLL_INTERVAL = 2 # seconds between process checks POLL_INTERVAL = 2 # seconds between process checks
@ -75,36 +85,44 @@ IGNORE_PATTERNS = frozenset(
def log(message: str) -> None: def log(message: str) -> None:
"""Log message with timestamp.""" """Log message with timestamp."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now(tz=timezone.utc).strftime(
"%Y-%m-%d %H:%M:%S"
)
log_line = f"{timestamp} - {message}" log_line = f"{timestamp} - {message}"
print(log_line) logger.info("%s", log_line)
try: with contextlib.suppress(OSError):
STATE_DIR.mkdir(parents=True, exist_ok=True) STATE_DIR.mkdir(parents=True, exist_ok=True)
with open(LOG_FILE, "a") as f: with LOG_FILE.open("a") as f:
f.write(log_line + "\n") f.write(log_line + "\n")
except Exception:
pass
def notify(title: str, message: str, urgency: str = "normal") -> None: def notify(
title: str, message: str, urgency: str = "normal"
) -> None:
"""Send desktop notification.""" """Send desktop notification."""
try: notify_send = shutil.which("notify-send")
if notify_send is None:
return
with contextlib.suppress(
OSError, subprocess.SubprocessError
):
subprocess.run( subprocess.run(
["notify-send", "-u", urgency, title, message], [notify_send, "-u", urgency, title, message],
capture_output=True, capture_output=True,
timeout=5, timeout=5,
check=False, check=False,
) )
except Exception:
pass
def get_running_processes() -> set[str]: def get_running_processes() -> set[str]:
"""Get set of currently running process names.""" """Get set of currently running process names."""
processes = set() processes: set[str] = set()
ps_bin = shutil.which("ps")
if ps_bin is None:
return processes
try: try:
result = subprocess.run( result = subprocess.run(
["ps", "-eo", "comm="], [ps_bin, "-eo", "comm="],
capture_output=True, capture_output=True,
text=True, text=True,
timeout=10, timeout=10,
@ -115,18 +133,16 @@ def get_running_processes() -> set[str]:
proc_name = line.strip().lower() proc_name = line.strip().lower()
if proc_name: if proc_name:
processes.add(proc_name) processes.add(proc_name)
except Exception as e: except (OSError, subprocess.SubprocessError) as exc:
log(f"Error getting processes: {e}") log(f"Error getting processes: {exc}")
return processes return processes
def is_steam_running(processes: set[str]) -> bool: def is_steam_running(processes: set[str]) -> bool:
"""Check if Steam or any Steam game is running.""" """Check if Steam or any Steam game is running."""
for proc in processes: for proc in processes:
# Check for Steam main processes
if proc in STEAM_PATTERNS: if proc in STEAM_PATTERNS:
return True return True
# Check for Steam games (have steam_app_ prefix)
if proc.startswith(STEAM_GAME_PREFIX): if proc.startswith(STEAM_GAME_PREFIX):
return True return True
return False return False
@ -135,129 +151,181 @@ def is_steam_running(processes: set[str]) -> bool:
def is_browser_running(processes: set[str]) -> bool: def is_browser_running(processes: set[str]) -> bool:
"""Check if any browser is running.""" """Check if any browser is running."""
for proc in processes: for proc in processes:
# Skip Electron apps and ignored patterns
if proc in ELECTRON_IGNORE: if proc in ELECTRON_IGNORE:
continue continue
if any(ign in proc for ign in IGNORE_PATTERNS): if any(ign in proc for ign in IGNORE_PATTERNS):
continue continue
# Use exact match to avoid false positives from Electron apps
if proc in BROWSER_PATTERNS: if proc in BROWSER_PATTERNS:
return True return True
return False return False
def _run_pkill(
pattern: str, *, force: bool = False
) -> None:
"""Run pkill with the given pattern."""
pkill_bin = shutil.which("pkill")
if pkill_bin is None:
return
cmd = [pkill_bin]
if force:
cmd.append("-9")
cmd.extend(["-f", pattern])
with contextlib.suppress(
OSError, subprocess.SubprocessError
):
subprocess.run(
cmd, capture_output=True, timeout=5, check=False
)
def kill_steam() -> None: def kill_steam() -> None:
"""Kill all Steam-related processes.""" """Kill all Steam-related processes."""
log("Killing Steam processes...") log("Killing Steam processes...")
notify("🎮 Gaming Blocked", "Browser is active. Closing Steam.", "critical") notify(
"\U0001f3ae Gaming Blocked",
"Browser is active. Closing Steam.",
"critical",
)
try: _run_pkill("steam")
# First try graceful shutdown time.sleep(2)
subprocess.run( _run_pkill("steam", force=True)
["pkill", "-f", "steam"], capture_output=True, timeout=5, check=False
)
time.sleep(2)
# Force kill if still running
subprocess.run(
["pkill", "-9", "-f", "steam"], capture_output=True, timeout=5, check=False
)
except Exception as e:
log(f"Error killing Steam: {e}")
def kill_browsers() -> None: def kill_browsers() -> None:
"""Kill all browser processes.""" """Kill all browser processes."""
log("Killing browser processes...") log("Killing browser processes...")
notify("🌐 Browsers Blocked", "Steam is active. Closing browsers.", "critical") notify(
"\U0001f310 Browsers Blocked",
"Steam is active. Closing browsers.",
"critical",
)
for browser in BROWSER_PATTERNS: for browser in BROWSER_PATTERNS:
try: _run_pkill(browser)
subprocess.run(
["pkill", "-f", browser], capture_output=True, timeout=5, check=False
)
except Exception:
pass
time.sleep(2) time.sleep(2)
# Force kill if still running
for browser in BROWSER_PATTERNS: for browser in BROWSER_PATTERNS:
try: _run_pkill(browser, force=True)
subprocess.run(
["pkill", "-9", "-f", browser],
capture_output=True,
timeout=5,
check=False,
)
except Exception:
pass
class FocusMode: class FocusMode:
"""Tracks current focus mode and enforces mutual exclusion.""" """Tracks current focus mode and enforces mutual exclusion."""
def __init__(self): def __init__(self) -> None:
self.current_mode: str | None = None # "gaming" or "browsing" or None """Initialize focus mode as inactive."""
self.current_mode: str | None = None
self.mode_start_time: datetime | None = None self.mode_start_time: datetime | None = None
def _enter_mode(
self, mode: str, msg: str, notification: str
) -> None:
"""Enter a new focus mode."""
log(msg)
self.current_mode = mode
self.mode_start_time = datetime.now(tz=timezone.utc)
notify(*notification.split("|", 1))
def _handle_no_mode(
self,
*,
steam_running: bool,
browser_running: bool,
) -> None:
"""Handle updates when no mode is active."""
if steam_running and browser_running:
log(
"Both Steam and browsers detected at "
"startup - entering GAMING mode"
)
self.current_mode = "gaming"
self.mode_start_time = datetime.now(
tz=timezone.utc
)
kill_browsers()
elif steam_running:
self._enter_mode(
"gaming",
"Steam detected - entering GAMING mode",
"\U0001f3ae Gaming Mode|"
"Steam detected. Browsers are now blocked.",
)
elif browser_running:
self._enter_mode(
"browsing",
"Browser detected - entering BROWSING mode",
"\U0001f310 Browsing Mode|"
"Browser detected. Steam is now blocked.",
)
def _handle_gaming(
self,
*,
steam_running: bool,
browser_running: bool,
) -> None:
"""Handle updates in gaming mode."""
if not steam_running:
log("Steam closed - exiting GAMING mode")
self.current_mode = None
self.mode_start_time = None
notify(
"\U0001f3ae Gaming Mode Ended",
"You can now use browsers.",
"normal",
)
elif browser_running:
log(
"Browser detected during GAMING mode "
"- killing browsers"
)
kill_browsers()
def _handle_browsing(
self,
*,
steam_running: bool,
browser_running: bool,
) -> None:
"""Handle updates in browsing mode."""
if not browser_running:
log("Browsers closed - exiting BROWSING mode")
self.current_mode = None
self.mode_start_time = None
notify(
"\U0001f310 Browsing Mode Ended",
"You can now use Steam.",
"normal",
)
elif steam_running:
log(
"Steam detected during BROWSING mode "
"- killing Steam"
)
kill_steam()
def update(self, processes: set[str]) -> None: def update(self, processes: set[str]) -> None:
"""Update focus mode based on running processes.""" """Update focus mode based on running processes."""
steam_running = is_steam_running(processes) steam_running = is_steam_running(processes)
browser_running = is_browser_running(processes) browser_running = is_browser_running(processes)
if self.current_mode is None: if self.current_mode is None:
# No mode set yet - first to start wins self._handle_no_mode(
if steam_running and browser_running: steam_running=steam_running,
# Both running at startup - prefer gaming mode (close browsers) browser_running=browser_running,
log( )
"Both Steam and browsers detected at startup - entering GAMING mode"
)
self.current_mode = "gaming"
self.mode_start_time = datetime.now()
kill_browsers()
elif steam_running:
log("Steam detected - entering GAMING mode")
self.current_mode = "gaming"
self.mode_start_time = datetime.now()
notify(
"🎮 Gaming Mode",
"Steam detected. Browsers are now blocked.",
"normal",
)
elif browser_running:
log("Browser detected - entering BROWSING mode")
self.current_mode = "browsing"
self.mode_start_time = datetime.now()
notify(
"🌐 Browsing Mode",
"Browser detected. Steam is now blocked.",
"normal",
)
elif self.current_mode == "gaming": elif self.current_mode == "gaming":
if not steam_running: self._handle_gaming(
# Steam closed - exit gaming mode steam_running=steam_running,
log("Steam closed - exiting GAMING mode") browser_running=browser_running,
self.current_mode = None )
self.mode_start_time = None
notify("🎮 Gaming Mode Ended", "You can now use browsers.", "normal")
elif browser_running:
# Browser started while in gaming mode - kill it
log("Browser detected during GAMING mode - killing browsers")
kill_browsers()
elif self.current_mode == "browsing": elif self.current_mode == "browsing":
if not browser_running: self._handle_browsing(
# Browsers closed - exit browsing mode steam_running=steam_running,
log("Browsers closed - exiting BROWSING mode") browser_running=browser_running,
self.current_mode = None )
self.mode_start_time = None
notify("🌐 Browsing Mode Ended", "You can now use Steam.", "normal")
elif steam_running:
# Steam started while in browsing mode - kill it
log("Steam detected during BROWSING mode - killing Steam")
kill_steam()
def get_status(self) -> str: def get_status(self) -> str:
"""Get current status string.""" """Get current status string."""
@ -266,33 +334,47 @@ class FocusMode:
duration = "" duration = ""
if self.mode_start_time: if self.mode_start_time:
elapsed = datetime.now() - self.mode_start_time elapsed = (
datetime.now(tz=timezone.utc)
- self.mode_start_time
)
minutes = int(elapsed.total_seconds() // 60) minutes = int(elapsed.total_seconds() // 60)
duration = f" (active for {minutes}m)" duration = f" (active for {minutes}m)"
if self.current_mode == "gaming": if self.current_mode == "gaming":
return f"🎮 GAMING mode{duration} - browsers blocked" return (
return f"🌐 BROWSING mode{duration} - Steam blocked" f"\U0001f3ae GAMING mode{duration}"
" - browsers blocked"
)
return (
f"\U0001f310 BROWSING mode{duration}"
" - Steam blocked"
)
def write_status(focus: FocusMode) -> None: def write_status(focus: FocusMode) -> None:
"""Write current status to state file for external queries.""" """Write current status to state file for external queries."""
try: with contextlib.suppress(OSError):
STATE_DIR.mkdir(parents=True, exist_ok=True) STATE_DIR.mkdir(parents=True, exist_ok=True)
status_file = STATE_DIR / "status" status_file = STATE_DIR / "status"
with open(status_file, "w") as f: with status_file.open("w") as f:
f.write(focus.get_status() + "\n") f.write(focus.get_status() + "\n")
f.write(f"mode={focus.current_mode or 'none'}\n") f.write(
except Exception: f"mode={focus.current_mode or 'none'}\n"
pass )
def main(): def main() -> None:
"""Main daemon loop.""" """Run the main daemon loop."""
logging.basicConfig(
format="%(message)s", level=logging.INFO
)
log("Focus Mode Daemon starting...") log("Focus Mode Daemon starting...")
# Setup signal handlers def handle_signal(
def handle_signal(signum, frame): signum: int, _frame: FrameType | None
) -> None:
"""Handle termination signals."""
log(f"Received signal {signum} - shutting down") log(f"Received signal {signum} - shutting down")
sys.exit(0) sys.exit(0)
@ -306,8 +388,11 @@ def main():
processes = get_running_processes() processes = get_running_processes()
focus.update(processes) focus.update(processes)
write_status(focus) write_status(focus)
except Exception as e: except (
log(f"Error in main loop: {e}") OSError,
subprocess.SubprocessError,
) as exc:
log(f"Error in main loop: {exc}")
time.sleep(POLL_INTERVAL) time.sleep(POLL_INTERVAL)

View File

@ -0,0 +1 @@
"""Transcription and helper tools for testsAndMisc bash scripts."""

View File

@ -1,13 +1,31 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Helper utilities for transcribe.sh - replaces inline Python snippets.""" """Helper utilities for transcribe.sh - replaces inline Python snippets."""
from __future__ import annotations
import argparse import argparse
import array import array
import importlib
import logging
import math import math
import os import os
import sys import sys
from typing import TYPE_CHECKING
import wave import wave
if TYPE_CHECKING:
import types
logger = logging.getLogger(__name__)
def _try_import(name: str) -> types.ModuleType | None:
"""Attempt to import a module, returning None on failure."""
try:
return importlib.import_module(name)
except ImportError:
return None
def get_python_version() -> str: def get_python_version() -> str:
"""Return Python major.minor version string.""" """Return Python major.minor version string."""
@ -16,42 +34,36 @@ def get_python_version() -> str:
def check_faster_whisper() -> bool: def check_faster_whisper() -> bool:
"""Check if faster_whisper is importable. Exit 7 if not.""" """Check if faster_whisper is importable. Exit 7 if not."""
try: return _try_import("faster_whisper") is not None
import faster_whisper # noqa: F401
return True
except ImportError:
return False
def check_diarization_deps() -> bool: def check_diarization_deps() -> bool:
"""Check if diarization dependencies are available. Returns False with warning if missing.""" """Check if diarization dependencies are available.
try:
import soundfile # noqa: F401
import speechbrain # noqa: F401
import torch # noqa: F401
return True Returns False with warning if missing.
except Exception as e: """
print( _sf = _try_import("soundfile")
f"[WARN] Diarization deps missing offline ({e}); speaker labels will be skipped." _sb = _try_import("speechbrain")
_torch = _try_import("torch")
if _sf is None or _sb is None or _torch is None:
logger.warning(
"Diarization deps missing offline; "
"speaker labels will be skipped.",
) )
return False return False
return True
def check_ctranslate2() -> bool: def check_ctranslate2() -> bool:
"""Check if ctranslate2 is importable.""" """Check if ctranslate2 is importable."""
try: return _try_import("ctranslate2") is not None
import ctranslate2 # noqa: F401
return True
except ImportError:
return False
def print_deps_installed(): def print_deps_installed() -> None:
"""Print confirmation that Python dependencies are installed.""" """Print confirmation that Python dependencies are installed."""
print(f"[PY] Python {sys.version.split()[0]} dependencies installed.") logger.info(
"Python %s dependencies installed.", sys.version.split()[0]
)
def generate_sine_wav( def generate_sine_wav(
@ -84,7 +96,12 @@ def generate_sine_wav(
min( min(
1.0, 1.0,
amplitude amplitude
* math.sin(2 * math.pi * frequency * (i / sample_rate)), * math.sin(
2
* math.pi
* frequency
* (i / sample_rate)
),
), ),
) )
* 32767 * 32767
@ -97,10 +114,11 @@ def generate_sine_wav(
wf.setsampwidth(2) wf.setsampwidth(2)
wf.setframerate(sample_rate) wf.setframerate(sample_rate)
wf.writeframes(data.tobytes()) wf.writeframes(data.tobytes())
return True except OSError:
except Exception as e: logger.exception("Failed to generate WAV")
print(f"[ERROR] Failed to generate WAV: {e}", file=sys.stderr)
return False return False
else:
return True
def prepare_model(model_name: str, model_dir: str) -> bool: def prepare_model(model_name: str, model_dir: str) -> bool:
@ -113,35 +131,40 @@ def prepare_model(model_name: str, model_dir: str) -> bool:
Returns: Returns:
True on success, False on failure True on success, False on failure
""" """
try: fw = _try_import("faster_whisper")
from faster_whisper import WhisperModel if fw is None:
logger.error("faster_whisper is not installed")
# Enable HuggingFace Hub progress bars for model download
try:
from huggingface_hub import logging as hf_logging
hf_logging.set_verbosity_info()
import huggingface_hub
huggingface_hub.constants.HF_HUB_DISABLE_PROGRESS_BARS = False
os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = "0"
except ImportError:
pass
print(f"[PY] Preparing model '{model_name}' into {model_dir}")
print(
"[INFO] Downloading model files (progress bar should appear below)...",
flush=True,
)
WhisperModel(
model_name, device="cpu", compute_type="int8", download_root=model_dir
)
print("[PY] Model prepared.")
return True
except Exception as e:
print(f"[ERROR] Failed to prepare model: {e}", file=sys.stderr)
return False return False
try:
hf_logging = _try_import("huggingface_hub.logging")
if hf_logging is not None:
hf_logging.set_verbosity_info()
hh = _try_import("huggingface_hub")
if hh is not None:
hh.constants.HF_HUB_DISABLE_PROGRESS_BARS = False
os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = "0"
logger.info(
"Preparing model '%s' into %s", model_name, model_dir
)
logger.info(
"Downloading model files "
"(progress bar should appear below)...",
)
fw.WhisperModel(
model_name,
device="cpu",
compute_type="int8",
download_root=model_dir,
)
logger.info("Model prepared.")
except (OSError, RuntimeError):
logger.exception("Failed to prepare model")
return False
else:
return True
def test_cuda() -> bool: def test_cuda() -> bool:
"""Test CUDA initialization with faster-whisper. """Test CUDA initialization with faster-whisper.
@ -149,30 +172,96 @@ def test_cuda() -> bool:
Returns: Returns:
True if CUDA works, False otherwise True if CUDA works, False otherwise
""" """
try: fw = _try_import("faster_whisper")
from faster_whisper import WhisperModel if fw is None:
logger.error("faster_whisper is not installed")
WhisperModel("tiny", device="cuda", compute_type="float16")
print("[PY] CUDA test init succeeded.")
return True
except Exception as e:
print(f"[ERROR] CUDA test failed: {e}", file=sys.stderr)
return False return False
try:
fw.WhisperModel(
"tiny", device="cuda", compute_type="float16"
)
logger.info("CUDA test init succeeded.")
except (OSError, RuntimeError):
logger.exception("CUDA test failed")
return False
else:
return True
def _handle_python_version() -> None:
"""Handle python-version command."""
logger.info("%s", get_python_version())
def _handle_check_faster_whisper() -> None:
"""Handle check-faster-whisper command."""
if not check_faster_whisper():
logger.error(
"Python dependency 'faster_whisper' not found in "
"offline mode. Run with --online to install.",
)
sys.exit(7)
def _handle_check_diarization() -> None:
"""Handle check-diarization command."""
check_diarization_deps()
def _handle_check_ctranslate2() -> None:
"""Handle check-ctranslate2 command."""
if not check_ctranslate2():
sys.exit(1)
def _handle_deps_installed() -> None:
"""Handle deps-installed command."""
print_deps_installed()
def _handle_generate_wav(args: argparse.Namespace) -> None:
"""Handle generate-wav command."""
if not args.file:
logger.error("--file is required for generate-wav")
sys.exit(2)
if not generate_sine_wav(args.file):
sys.exit(1)
def _handle_prepare_model(args: argparse.Namespace) -> None:
"""Handle prepare-model command."""
if not args.model or not args.model_dir:
logger.error(
"--model and --model-dir are required for prepare-model",
)
sys.exit(2)
if not prepare_model(args.model, args.model_dir):
sys.exit(1)
def _handle_test_cuda() -> None:
"""Handle test-cuda command."""
if not test_cuda():
sys.exit(1)
def main() -> None:
"""Parse arguments and dispatch helper commands."""
logging.basicConfig(format="%(message)s", level=logging.INFO)
def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Helper utilities for transcribe.sh", description="Helper utilities for transcribe.sh",
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=""" epilog="""
Commands: Commands:
python-version Print Python major.minor version python-version Print Python major.minor version
check-faster-whisper Check if faster_whisper is installed (exit 7 if not) check-faster-whisper Check if faster_whisper is installed
check-diarization Check diarization deps (warn if missing) check-diarization Check diarization deps (warn if missing)
check-ctranslate2 Check if ctranslate2 is installed (exit 1 if not) check-ctranslate2 Check if ctranslate2 is installed
deps-installed Print deps installed confirmation message deps-installed Print deps installed confirmation
generate-wav FILE Generate a 3s 1kHz sine wave WAV file generate-wav FILE Generate a 3s 1kHz sine wave WAV
prepare-model Download model for offline use (requires --model and --model-dir) prepare-model Download model for offline use
test-cuda Test CUDA initialization test-cuda Test CUDA initialization
""", """,
) )
@ -190,46 +279,32 @@ Commands:
], ],
help="Command to run", help="Command to run",
) )
parser.add_argument("--file", help="Output file path (for generate-wav)") parser.add_argument(
parser.add_argument("--model", help="Model name (for prepare-model)") "--file", help="Output file path (for generate-wav)"
parser.add_argument("--model-dir", help="Model directory (for prepare-model)") )
parser.add_argument(
"--model", help="Model name (for prepare-model)"
)
parser.add_argument(
"--model-dir", help="Model directory (for prepare-model)"
)
args = parser.parse_args() args = parser.parse_args()
if args.command == "python-version": dispatch: dict[str, object] = {
print(get_python_version()) "python-version": _handle_python_version,
elif args.command == "check-faster-whisper": "check-faster-whisper": _handle_check_faster_whisper,
if not check_faster_whisper(): "check-diarization": _handle_check_diarization,
print( "check-ctranslate2": _handle_check_ctranslate2,
"Python dependency 'faster_whisper' not found in offline mode. Run with --online to install.", "deps-installed": _handle_deps_installed,
file=sys.stderr, "generate-wav": lambda: _handle_generate_wav(args),
) "prepare-model": lambda: _handle_prepare_model(args),
sys.exit(7) "test-cuda": _handle_test_cuda,
elif args.command == "check-diarization": }
check_diarization_deps()
elif args.command == "check-ctranslate2": handler = dispatch.get(args.command)
if not check_ctranslate2(): if handler is not None and callable(handler):
sys.exit(1) handler()
elif args.command == "deps-installed":
print_deps_installed()
elif args.command == "generate-wav":
if not args.file:
print("--file is required for generate-wav", file=sys.stderr)
sys.exit(2)
if not generate_sine_wav(args.file):
sys.exit(1)
elif args.command == "prepare-model":
if not args.model or not args.model_dir:
print(
"--model and --model-dir are required for prepare-model",
file=sys.stderr,
)
sys.exit(2)
if not prepare_model(args.model, args.model_dir):
sys.exit(1)
elif args.command == "test-cuda":
if not test_cuda():
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":