diff --git a/CHANGELOG.md b/CHANGELOG.md index 39f7ee5..66d7f63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Changed - Python typing features added to all modules +- CLI functions moved to `cli.py` ## [0.8] - 2025-12-17 ### Added - `WinMM` engine diff --git a/nava/__init__.py b/nava/__init__.py index 8d44578..f501ca8 100644 --- a/nava/__init__.py +++ b/nava/__init__.py @@ -8,3 +8,5 @@ atexit.register(stop_all) __version__ = NAVA_VERSION + +__all__ = ["Engine", "NavaBaseError", "play", "stop", "stop_all"] diff --git a/nava/__main__.py b/nava/__main__.py index 9f563bf..c305b84 100644 --- a/nava/__main__.py +++ b/nava/__main__.py @@ -1,46 +1,7 @@ # -*- coding: utf-8 -*- """Nava main.""" -import argparse -from art import tprint -from .params import NAVA_VERSION -from .functions import nava_help, play_cli - - -def main() -> None: - """CLI main function.""" - parser = argparse.ArgumentParser() - parser.add_argument( - 'filename', - nargs='?', - type=str, - metavar='FILE_PATH', - help='path to audio file' - ) - parser.add_argument( - '--file', - nargs='?', - type=str, - metavar='FILE_PATH', - help='path to audio file', - ) - parser.add_argument('--loop', help='sound play in loop', action='store_true', default=False) - parser.add_argument('--version', help="version", action='store_true', default=False) - parser.add_argument('-v', help="version", action='store_true', default=False) - args = parser.parse_known_args()[0] - if args.version or args.v: - print(NAVA_VERSION) - elif args.filename or args.file: - file_name = args.filename - if args.file: - file_name = args.file - loop = args.loop - play_cli(file_name, loop=loop) - else: - tprint("Nava") - tprint("V:" + NAVA_VERSION) - nava_help() - parser.print_help() +from .cli import main if __name__ == "__main__": main() diff --git a/nava/cli.py b/nava/cli.py new file mode 100644 index 0000000..b522c3a --- /dev/null +++ b/nava/cli.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +"""Nava cli.""" +import sys +import argparse +from art import tprint +from .params import NAVA_VERSION, EXIT_MESSAGE +from .functions import nava_help, play_cli + + +def parse_args() -> argparse.Namespace: + """Parse arguments.""" + parser = argparse.ArgumentParser() + parser.add_argument( + 'filename', + nargs='?', + type=str, + metavar='FILE_PATH', + help='path to audio file' + ) + parser.add_argument( + '--file', + nargs='?', + type=str, + metavar='FILE_PATH', + help='path to audio file', + ) + parser.add_argument('--loop', help='sound play in loop', action='store_true', default=False) + parser.add_argument('--version', help="version", action='store_true', default=False) + parser.add_argument('-v', help="version", action='store_true', default=False) + args = parser.parse_known_args()[0] + return args + + +def run(args: argparse.Namespace) -> None: + """ + Run nava CLI. + + :param args: arguments + """ + if args.version or args.v: + print(NAVA_VERSION) + elif args.filename or args.file: + file_name = args.filename + if args.file: + file_name = args.file + loop = args.loop + play_cli(file_name, loop=loop) + else: + tprint("Nava") + tprint("V:" + NAVA_VERSION) + nava_help() + + +def main() -> None: + """CLI main function.""" + try: + args = parse_args() + run(args) + except (KeyboardInterrupt, EOFError): + print(EXIT_MESSAGE) + sys.exit(1) diff --git a/nava/functions.py b/nava/functions.py index 78319eb..cf438be 100644 --- a/nava/functions.py +++ b/nava/functions.py @@ -52,7 +52,7 @@ def nava_help() -> None: def quote(func: Callable) -> Callable: """ Quote the given shell string. - + :param func: function to wrap """ @wraps(func) @@ -143,7 +143,7 @@ def get_sound_status(alias: str) -> str: # So the main thread can’t “see” the alias created in the worker thread. if getattr(current_thread, "_force_stop", False): break - status = get_sound_status (alias) + status = get_sound_status(alias) if status != "playing": if getattr(current_thread, "_loop", loop): stop_sound(alias) @@ -293,7 +293,7 @@ def __play_proc_afplay(sound_path: str) -> subprocess.Popen: def path_check(func: Callable) -> Callable: """ Check the given path to be a string and a valid file directory. - + :param func: function to wrap """ @wraps(func) diff --git a/nava/params.py b/nava/params.py index 9479559..ffecbba 100644 --- a/nava/params.py +++ b/nava/params.py @@ -38,15 +38,15 @@ class PythonEnvironment(Enum): # Environment variables typically set by VS Code VSCODE_ENV_VARS = [ - "VSCODE_PID", # this is often set when running in VS Code - "VSCODE_CWD", # this is often set when running in VS Code + "VSCODE_PID", # this is often set when running in VS Code + "VSCODE_CWD", # this is often set when running in VS Code "VSCODE_IPC_HOOK_CLI", "TERM_PROGRAM", # often set to "vscode" ] # Shell type identifiers SHELL_TYPE_ZMQ = "zmqinteractiveshell" # Jupyter Notebook/Lab -SHELL_TYPE_TERMINAL = "terminalinteractiveshell" # IPython Terminal +SHELL_TYPE_TERMINAL = "terminalinteractiveshell" # IPython Terminal SOUND_FILE_PLAY_ERROR = "Sound can not play due to some issues." SOUND_FILE_EXIST_ERROR = "Given sound file doesn't exist." @@ -55,5 +55,7 @@ class PythonEnvironment(Enum): LOOP_ASYNC_ERROR = "`loop` can not be set True when `async_mode` is False." ENGINE_TYPE_ERROR = "`engine` type must be `Engine` enum." +EXIT_MESSAGE = "See you. Bye!" + _play_threads_map = dict() _play_threads_counter = 0 diff --git a/setup.py b/setup.py index b3cdf66..08ddc8d 100644 --- a/setup.py +++ b/setup.py @@ -74,5 +74,5 @@ def read_description() -> str: license='MIT', entry_points={ 'console_scripts': [ - 'nava = nava.__main__:main', + 'nava = nava.cli:main', ]})