From c82a021708f3dcc46b48fb9de7312bd22d0fc5dd Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Sun, 1 Mar 2026 21:15:42 +0000 Subject: [PATCH] add recorder subcommand group add validation module --- src/vban_cli/app.py | 3 +- src/vban_cli/recorder.py | 118 +++++++++++++++++++++++++++++++++++++ src/vban_cli/validation.py | 9 +++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/vban_cli/recorder.py create mode 100644 src/vban_cli/validation.py diff --git a/src/vban_cli/app.py b/src/vban_cli/app.py index c04b6dc..ee5f93d 100644 --- a/src/vban_cli/app.py +++ b/src/vban_cli/app.py @@ -5,7 +5,7 @@ import vban_cmd from cyclopts import App, Argument, Parameter, config from . import __version__ as version -from . import bus, command, console, strip +from . import bus, command, console, recorder, strip from .context import Context app = App( @@ -17,6 +17,7 @@ app = App( app.command(strip.app.meta, name='strip') app.command(bus.app.meta, name='bus') app.command(command.app, name='command') +app.command(recorder.app, name='recorder') app.register_install_completion_command() diff --git a/src/vban_cli/recorder.py b/src/vban_cli/recorder.py new file mode 100644 index 0000000..8df2a6e --- /dev/null +++ b/src/vban_cli/recorder.py @@ -0,0 +1,118 @@ +from pathlib import Path +from typing import Annotated + +from cyclopts import App, Parameter, validators + +from . import console, validation +from .context import Context +from .help import BaseHelpFormatter + +app = App(name='recorder', help_formatter=BaseHelpFormatter()) + + +@app.command(name='play') +def play( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Start the recorder playback.""" + ctx.client.recorder.play() + console.out.print('Recorder playback started.') + + +@app.command(name='stop') +def stop( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Stop the recorder playback.""" + ctx.client.recorder.stop() + console.out.print('Recorder playback stopped.') + + +@app.command(name='pause') +def pause( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Pause the recorder playback.""" + ctx.client.recorder.pause() + console.out.print('Recorder playback paused.') + + +@app.command(name='replay') +def replay( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Replay the recorder playback.""" + ctx.client.recorder.replay() + console.out.print('Recorder playback replay started.') + + +@app.command(name='record') +def record( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Start recording.""" + ctx.client.recorder.record() + console.out.print('Recording started.') + + +@app.command(name='ff') +def ff( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Fast forward the recorder playback.""" + ctx.client.recorder.ff() + console.out.print('Recorder playback fast forwarded.') + + +@app.command(name='rew') +def rew( + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Rewind the recorder playback.""" + ctx.client.recorder.rew() + console.out.print('Recorder playback rewound.') + + +@app.command(name='load') +def load( + file_path: Annotated[ + Path, + Parameter( + help='The path to the recording file to load.', + validator=validators.Path(exists=True), + ), + ], + /, + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Load a file into the recorder. + + note: This command may only work if vban-cli is running on localhost and may not work if vban-cli is running on a remote server.""" + ctx.client.recorder.load(file_path) + console.out.print(f'Loaded file: {file_path}') + + +@app.command(name='goto') +def goto( + time_string: Annotated[ + str, + Parameter( + help='The timestamp to go to in the recorder playback (format: HH:MM:SS).', + validator=validation.is_valid_time_string, + ), + ], + /, + *, + ctx: Annotated[Context, Parameter(show=False)] = None, +): + """Go to a specific timestamp in the recorder playback.""" + ctx.client.recorder.goto(time_string) + console.out.print(f'Went to timestamp {time_string} in recorder playback.') diff --git a/src/vban_cli/validation.py b/src/vban_cli/validation.py new file mode 100644 index 0000000..451692f --- /dev/null +++ b/src/vban_cli/validation.py @@ -0,0 +1,9 @@ +import re + + +def is_valid_time_string(type_, value: str) -> str: + """Validate if the given string is a valid time format (HH:MM:SS).""" + pattern = r'^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$' + if not re.match(pattern, value): + raise ValueError('Invalid time format. Expected HH:MM:SS.') + return value