Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions nava/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
atexit.register(stop_all)

__version__ = NAVA_VERSION

__all__ = ["Engine", "NavaBaseError", "play", "stop", "stop_all"]
41 changes: 1 addition & 40 deletions nava/__main__.py
Original file line number Diff line number Diff line change
@@ -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()
61 changes: 61 additions & 0 deletions nava/cli.py
Original file line number Diff line number Diff line change
@@ -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]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we do have parse_known_args here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that the first argument (filename) is positional, suggesting that parse_known_args should be used.

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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that ok we remove parser.print_help()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling parser.print_help() may not be incorrect, but it's not my personal preference.



def main() -> None:
"""CLI main function."""
try:
args = parse_args()
run(args)
except (KeyboardInterrupt, EOFError):
print(EXIT_MESSAGE)
sys.exit(1)
6 changes: 3 additions & 3 deletions nava/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions nava/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand All @@ -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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ def read_description() -> str:
license='MIT',
entry_points={
'console_scripts': [
'nava = nava.__main__:main',
'nava = nava.cli:main',
]})