summaryrefslogtreecommitdiff
path: root/src/mic_clipper/cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mic_clipper/cli.py')
-rw-r--r--src/mic_clipper/cli.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/mic_clipper/cli.py b/src/mic_clipper/cli.py
new file mode 100644
index 0000000..cd62cef
--- /dev/null
+++ b/src/mic_clipper/cli.py
@@ -0,0 +1,66 @@
+"""Command-line entry points for recording and service administration."""
+
+from __future__ import annotations
+
+import argparse
+import logging
+import sys
+from pathlib import Path
+
+from mic_clipper import service
+from mic_clipper.runner import run_forever
+
+
+DEFAULT_OUTPUT = Path.home() / "Documents" / "Mic Clips"
+DEFAULT_UNIT = Path.home() / ".config" / "systemd" / "user" / service.UNIT_NAME
+PROJECT_ROOT = Path(__file__).resolve().parents[2]
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(description="Offline voice-activated microphone clips")
+ commands = parser.add_subparsers(dest="command", required=True)
+
+ run = commands.add_parser("run", help="listen and save speech clips")
+ run.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT)
+ run.add_argument("--threshold", type=float, default=0.5)
+
+ service_parser = commands.add_parser("service", help="manage the systemd user service")
+ service_commands = service_parser.add_subparsers(dest="service_command", required=True)
+ install = service_commands.add_parser("install", help="install and enable the user service")
+ install.add_argument("--dry-run", action="store_true")
+ install.add_argument("--unit-path", type=Path, default=DEFAULT_UNIT)
+ install.add_argument("--project-root", type=Path, default=PROJECT_ROOT)
+ install.add_argument("--python", type=Path, default=Path(sys.executable))
+ uninstall = service_commands.add_parser("uninstall", help="remove only this tool's service")
+ uninstall.add_argument("--unit-path", type=Path, default=DEFAULT_UNIT)
+ service_commands.add_parser("status", help="show systemd user service status")
+ return parser
+
+
+def main(arguments: list[str] | None = None) -> int:
+ args = build_parser().parse_args(arguments)
+ if args.command == "run":
+ if not 0 < args.threshold <= 1:
+ raise SystemExit("--threshold must be between 0 and 1")
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
+ run_forever(args.output_dir, threshold=args.threshold)
+ return 0
+ if args.service_command == "install":
+ commands = service.install(
+ unit_path=args.unit_path,
+ python=args.python,
+ project_root=args.project_root,
+ dry_run=args.dry_run,
+ )
+ if args.dry_run:
+ for command in commands:
+ print(" ".join(command))
+ return 0
+ if args.service_command == "uninstall":
+ service.uninstall(unit_path=args.unit_path)
+ return 0
+ return service.status()
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())