From 37dbbdf4e2f5d2791496dcd285dcf22f7a1fb374 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Fri, 23 May 2025 21:29:18 +0100 Subject: [PATCH] print list as rich table swap out typer.echo for rich consoles add filter status command add util function minor bump --- CHANGELOG.md | 6 ++++ README.md | 7 +++++ obsws_cli/__about__.py | 2 +- obsws_cli/filter.py | 65 ++++++++++++++++++++++++++++++++---------- obsws_cli/util.py | 6 ++++ 5 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 obsws_cli/util.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 55e689e..8e87d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [0.12.0] - 2025-05-23 + +### Added + +- filter commands, see [Filter](https://github.com/onyx-and-iris/obsws-cli?tab=readme-ov-file#filter) + # [0.11.0] - 2025-05-22 ### Added diff --git a/README.md b/README.md index c6921fd..d5a2c59 100644 --- a/README.md +++ b/README.md @@ -516,6 +516,13 @@ obsws-cli filter disable "Mic/Aux" "Test Compression Filter" obsws-cli filter toggle "Mic/Aux" "Test Compression Filter" ``` +- status: Get the status of a filter for a source. + - args: + +```console +obsws-cli filter status "Mic/Aux" "Test Compression Filter" +``` + ## License `obsws-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. diff --git a/obsws_cli/__about__.py b/obsws_cli/__about__.py index 7fcb8d8..a58f687 100644 --- a/obsws_cli/__about__.py +++ b/obsws_cli/__about__.py @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2025-present onyx-and-iris # # SPDX-License-Identifier: MIT -__version__ = "0.11.0" +__version__ = "0.12.0" diff --git a/obsws_cli/filter.py b/obsws_cli/filter.py index f9b69b4..4f1c553 100644 --- a/obsws_cli/filter.py +++ b/obsws_cli/filter.py @@ -1,10 +1,15 @@ """module containing commands for manipulating filters in scenes.""" import typer +from rich.console import Console +from rich.table import Table +from . import util from .alias import AliasGroup app = typer.Typer(cls=AliasGroup) +out_console = Console() +err_console = Console(stderr=True) @app.callback() @@ -18,14 +23,28 @@ def list(ctx: typer.Context, source_name: str): resp = ctx.obj.get_source_filter_list(source_name) if not resp.filters: - typer.echo(f'No filters found for source {source_name}') + out_console.print(f'No filters found for source {source_name}') return + table = Table(title=f'Filters for Source: {source_name}') + + for column in ('Name', 'Kind', 'Enabled', 'Settings'): + table.add_column(column, justify='center', style='cyan') + for filter in resp.filters: - typer.echo(f'Filter: {filter["filterName"]}') - for key, value in filter.items(): - if key != 'filterName': - typer.echo(f' {key}: {value}') + table.add_row( + filter['filterName'], + util.snakecase_to_titlecase(filter['filterKind']), + ':heavy_check_mark:' if filter['filterEnabled'] else ':x:', + '\n'.join( + [ + f'{util.snakecase_to_titlecase(k):<20} {v:>10}' + for k, v in filter['filterSettings'].items() + ] + ), + ) + + out_console.print(table) def _get_filter_enabled(ctx: typer.Context, source_name: str, filter_name: str): @@ -42,14 +61,13 @@ def enable( ): """Enable a filter for a source.""" if _get_filter_enabled(ctx, source_name, filter_name): - typer.echo( - f'Filter {filter_name} is already enabled for source {source_name}', - err=True, + err_console.print( + f'Filter {filter_name} is already enabled for source {source_name}' ) raise typer.Exit(1) ctx.obj.set_source_filter_enabled(source_name, filter_name, enabled=True) - typer.echo(f'Enabled filter {filter_name} for source {source_name}') + out_console.print(f'Enabled filter {filter_name} for source {source_name}') @app.command('disable | off') @@ -60,14 +78,13 @@ def disable( ): """Disable a filter for a source.""" if not _get_filter_enabled(ctx, source_name, filter_name): - typer.echo( - f'Filter {filter_name} is already disabled for source {source_name}', - err=True, + err_console.print( + f'Filter {filter_name} is already disabled for source {source_name}' ) raise typer.Exit(1) ctx.obj.set_source_filter_enabled(source_name, filter_name, enabled=False) - typer.echo(f'Disabled filter {filter_name} for source {source_name}') + out_console.print(f'Disabled filter {filter_name} for source {source_name}') @app.command('toggle | tg') @@ -82,6 +99,24 @@ def toggle( ctx.obj.set_source_filter_enabled(source_name, filter_name, enabled=new_state) if new_state: - typer.echo(f'Enabled filter {filter_name} for source {source_name}') + out_console.print(f'Enabled filter {filter_name} for source {source_name}') else: - typer.echo(f'Disabled filter {filter_name} for source {source_name}') + out_console.print(f'Disabled filter {filter_name} for source {source_name}') + + +@app.command('status | ss') +def status( + ctx: typer.Context, + source_name: str = typer.Argument( + ..., help='The source to get the filter status for' + ), + filter_name: str = typer.Argument( + ..., help='The name of the filter to get the status for' + ), +): + """Get the status of a filter for a source.""" + is_enabled = _get_filter_enabled(ctx, source_name, filter_name) + if is_enabled: + out_console.print(f'Filter {filter_name} is enabled for source {source_name}') + else: + out_console.print(f'Filter {filter_name} is disabled for source {source_name}') diff --git a/obsws_cli/util.py b/obsws_cli/util.py new file mode 100644 index 0000000..07482d5 --- /dev/null +++ b/obsws_cli/util.py @@ -0,0 +1,6 @@ +"""module contains utility functions for the obsws_cli package.""" + + +def snakecase_to_titlecase(snake_str): + """Convert a snake_case string to a title case string.""" + return snake_str.replace('_', ' ').title()