summaryrefslogtreecommitdiff
path: root/src/mic_clipper/cli.py
blob: cd62cef1526e0c77a7d9ec69bb14400cfb95ec89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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())