-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Andy Zhang
authored
May 3, 2023
0 parents
commit de7e104
Showing
17 changed files
with
424 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2023 NWSOFT | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import sys | ||
|
||
if not sys.stdin.isatty(): | ||
print("Error: The console is not a TTY.", file=sys.stderr) | ||
sys.stderr.flush() | ||
sys.exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from typing import Dict, Union | ||
|
||
from prompt_toolkit import HTML | ||
|
||
from NWSh.printing import print_error | ||
from NWSh.subsystem import Subsystem | ||
|
||
|
||
class Arguments(Subsystem): | ||
def __init__(self, name: str = "(none)", preferences=None): | ||
super().__init__(name, preferences) | ||
self.arguments: Dict[str, Union[str, int, float]] = {} | ||
|
||
def print_welcome(self): | ||
return # Do not print welcome message, as this is not a "normal" subsystem | ||
|
||
def ask_argument(self, argument_name: str, argument_description: str, argument_type: str = "str"): | ||
# language=HTML | ||
self.prompt = HTML( | ||
f"<subsystem_name>{self.name}</subsystem_name>" | ||
f"<number>({argument_name})</number>" | ||
f"<prompt>></prompt> " | ||
) | ||
self.arguments[argument_name] = self.session.prompt(self.prompt, rprompt=argument_description, style=self.style) | ||
|
||
if argument_type == "int": | ||
try: | ||
self.arguments[argument_name] = int(self.arguments[argument_name]) | ||
except ValueError: | ||
print_error(self.name, f"Argument {argument_name} must be an integer") | ||
self.ask_argument(argument_name, argument_description, argument_type) | ||
elif argument_type == "float": | ||
try: | ||
self.arguments[argument_name] = float(self.arguments[argument_name]) | ||
except ValueError: | ||
print_error(self.name, f"Argument {argument_name} must be a float") | ||
self.ask_argument(argument_name, argument_description, argument_type) | ||
|
||
def get_argument(self, argument_name: str): | ||
try: | ||
return self.arguments[argument_name] | ||
except KeyError: | ||
print_error(self.name, f"Argument {argument_name} not found") | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from typing import Callable | ||
|
||
from NWSh.printing import print_warning | ||
from NWSh.subsystem import Subsystem | ||
from NWSh.system import System | ||
|
||
|
||
def register_command_system(system: System, command: str, func: Callable): | ||
if command in system.commands: | ||
print_warning(system.name, f"Command {command} already registered") | ||
system.commands[command] = func | ||
|
||
|
||
def register_command_subsystem(subsystem: Subsystem, command: str, func: Callable): | ||
if command in subsystem.commands: | ||
print_warning(subsystem.name, f"Command {command} already registered") | ||
subsystem.commands[command] = func |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import platform | ||
|
||
WINDOWS = platform.system() == "Windows" | ||
OSX = platform.system() == "Darwin" | ||
LINUX = platform.system() == "Linux" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import os | ||
from pathlib import Path | ||
|
||
from NWSh.constants import OSX, WINDOWS | ||
|
||
# Path to the user preferences folder | ||
if WINDOWS: | ||
USER_PREFS_DIR = Path(os.getenv("APPDATA")) / "NWSOFT" / "NWSh" | ||
elif OSX: | ||
USER_PREFS_DIR = Path.home() / "Library" / "Preferences" / "NWSOFT" / "NWSh" | ||
else: | ||
USER_PREFS_DIR = Path.home() / ".NWSOFT" / "NWSh" | ||
|
||
# Path to the user preferences file | ||
USER_PREFS_FILE = USER_PREFS_DIR / "settings.json" | ||
DEFAULT_PREFS_FILE = Path(__file__).parent / "resources" / "settings.json" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from prompt_toolkit import HTML, print_formatted_text | ||
from prompt_toolkit.styles import Style | ||
|
||
from NWSh.settings import Settings | ||
|
||
|
||
def print_error(subsystem: str, error: str): | ||
settings = Settings() | ||
using_style = settings.get("styles")[settings.get("using")] | ||
style = Style.from_dict(using_style) | ||
# language=HTML | ||
print_formatted_text( | ||
HTML(f"<subsystem_name>{subsystem}</subsystem_name>|<error>ERR : {error}</error>"), style=style | ||
) | ||
|
||
|
||
def print_warning(subsystem: str, warning: str): | ||
settings = Settings() | ||
using_style = settings.get("styles")[settings.get("using")] | ||
style = Style.from_dict(using_style) | ||
# language=HTML | ||
print_formatted_text( | ||
HTML(f"<subsystem_name>{subsystem}</subsystem_name>|<warning>WARN: {warning}</warning>"), style=style | ||
) | ||
|
||
|
||
def print_info(subsystem: str, info: str): | ||
settings = Settings() | ||
using_style = settings.get("styles")[settings.get("using")] | ||
style = Style.from_dict(using_style) | ||
# language=HTML | ||
print_formatted_text(HTML(f"<subsystem_name>{subsystem}</subsystem_name>|<info>INFO: {info}</info>"), style=style) | ||
|
||
|
||
def print_result(subsystem: str, result: str): | ||
settings = Settings() | ||
using_style = settings.get("styles")[settings.get("using")] | ||
style = Style.from_dict(using_style) | ||
# language=HTML | ||
print_formatted_text( | ||
HTML(f"<subsystem_name>{subsystem}</subsystem_name>|<result>=> {result}</result>"), style=style | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Default user preferences | ||
{ | ||
"styles": { | ||
"default": { | ||
// Plain text | ||
"": "", | ||
// Header | ||
"title": "#37AFAE", | ||
"description": "#356161", | ||
// Prompt | ||
"subsystem_name": "#368A8A", | ||
"system_name": "#57B4B4", | ||
"number": "#37AFAE", | ||
"prompt": "#ffffff", | ||
// Warnings/Errors | ||
"warning": "#FFA500", | ||
"error": "#FF0000", | ||
"result": "#4188C6" | ||
}, | ||
"green": { | ||
// Plain text | ||
"": "", | ||
// Header | ||
"title": "#77BC41", | ||
"description": "#537B2B", | ||
// Prompt | ||
"subsystem_name": "#669D35", | ||
"system_name": "#8ABF4F", | ||
"number": "#77BC41", | ||
"prompt": "#ffffff", | ||
// Warnings/Errors | ||
"warning": "#FFA500", | ||
"error": "#FF0000", | ||
"result": "#4188C6" | ||
} | ||
}, | ||
"using": "default" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import json5rw as json | ||
|
||
from NWSh.paths import DEFAULT_PREFS_FILE, USER_PREFS_FILE | ||
|
||
|
||
class Settings: | ||
def __init__(self): | ||
self.settings = {} | ||
self.load() | ||
|
||
def load(self): | ||
try: | ||
with DEFAULT_PREFS_FILE.open() as f: | ||
self.settings = json.load(f) | ||
with USER_PREFS_FILE.open() as f: | ||
self.settings |= json.load(f) | ||
except FileNotFoundError: | ||
self.save() | ||
|
||
def save(self): | ||
USER_PREFS_FILE.parent.mkdir(parents=True, exist_ok=True) | ||
with USER_PREFS_FILE.open("w") as f: | ||
json.dump(self.settings, f, indent=4, sort_keys=True) | ||
|
||
def get(self, key, default=None): | ||
return self.settings.get(key, default) | ||
|
||
def set(self, key, value): | ||
self.settings[key] = value | ||
self.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import sys | ||
|
||
from prompt_toolkit import HTML, print_formatted_text, PromptSession | ||
from prompt_toolkit.output.color_depth import ColorDepth as Depth | ||
from prompt_toolkit.styles import Style | ||
|
||
from NWSh.printing import print_error | ||
from NWSh.settings import Settings | ||
|
||
DEFAULT_PREFERENCES = { | ||
"name" : "(none)", | ||
"version" : "0.1", | ||
"description": # language=HTML | ||
"<i>No description</i>", | ||
"author" : "Anonymous", | ||
"license" : "MIT", | ||
} | ||
|
||
|
||
class Subsystem: | ||
commands = { | ||
"exit": lambda: sys.exit(0) | ||
} | ||
|
||
def __init__(self, name: str = "(none)", preferences=None): | ||
if preferences is None: | ||
preferences = {} | ||
self.preferences = DEFAULT_PREFERENCES | preferences | ||
self.name = name | ||
self.prompt = f"{name}> " | ||
self.session = PromptSession() | ||
self.settings = Settings() | ||
self.style = None | ||
self.number = 0 | ||
self.get_style() | ||
|
||
# language=HTML | ||
self.ctrl_c_msg = HTML( | ||
f"<subsystem_name>{self.name}</subsystem_name>: Press <b>Ctrl</b>+<b>D</b> (EOF) to exit." | ||
) | ||
|
||
self.print_welcome() | ||
|
||
def print_welcome(self): | ||
# language=HTML | ||
print_formatted_text( | ||
HTML( | ||
f"""\ | ||
<title><b>{self.preferences["name"]}</b> version {self.preferences["version"]} | ||
By {self.preferences["author"]}, under the {self.preferences["license"]} license | ||
</title>\ | ||
<description>\ | ||
{self.preferences["description"]} | ||
</description>\ | ||
""", | ||
), | ||
style=self.style, | ||
) | ||
|
||
def get_style(self): | ||
self.style = Style.from_dict( | ||
self.settings.get("styles") | ||
[self.settings.get("using")] | ||
) | ||
|
||
def command_not_found(self): | ||
print_error(self.name, "Command not found") | ||
|
||
def execute_command(self, name): | ||
try: | ||
command_function = self.commands[name] | ||
except KeyError: | ||
command_function = self.command_not_found | ||
command_function() | ||
|
||
def ask_command(self): | ||
self.prompt = HTML( | ||
# language=HTML | ||
f"<subsystem_name>({self.name})</subsystem_name> " | ||
f"<number>[{self.number}]</number>" | ||
f"<prompt>></prompt> " | ||
) | ||
self.number += 1 | ||
try: | ||
result = self.session.prompt(self.prompt, style=self.style, color_depth=Depth.TRUE_COLOR) | ||
except KeyboardInterrupt: | ||
print_formatted_text(self.ctrl_c_msg, style=self.style) | ||
return | ||
except EOFError: | ||
sys.exit(0) | ||
|
||
self.execute_command(result) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import sys | ||
|
||
from prompt_toolkit import HTML, print_formatted_text, PromptSession | ||
from prompt_toolkit.output import ColorDepth as Depth | ||
|
||
from NWSh.settings import Settings | ||
from NWSh.subsystem import Subsystem | ||
|
||
|
||
class System(Subsystem): | ||
commands = {} | ||
|
||
def __init__(self, name: str = "(none)", preferences=None): | ||
super().__init__(name, preferences) | ||
self.prompt = f"{name}> " | ||
self.session = PromptSession() | ||
self.settings = Settings() | ||
self.style = None | ||
self.number = 0 | ||
self.get_style() | ||
|
||
# language=HTML | ||
self.ctrl_c_msg = HTML( | ||
f"<system_name>{self.name}</system_name>: Press <b>Ctrl</b>+<b>D</b> (EOF) to exit." | ||
) | ||
|
||
def ask_command(self): | ||
# language=HTML | ||
self.prompt = HTML( | ||
f"<system_name>{self.name}</system_name> " | ||
f"<number>[{self.number}]</number>" | ||
f"<prompt>></prompt> " | ||
) | ||
self.number += 1 | ||
try: | ||
result = self.session.prompt(self.prompt, style=self.style, color_depth=Depth.TRUE_COLOR) | ||
except KeyboardInterrupt: | ||
print_formatted_text(self.ctrl_c_msg, style=self.style) | ||
return | ||
except EOFError: | ||
sys.exit(0) | ||
|
||
self.execute_command(result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# NWShDev | ||
This package provides a set of tools to facilitate the development of the [NWSh](https://github.com/NWSOFT-ORG/NWSh) shell. | ||
|
||
See the documents in the `docs` directory for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# API Documentation - Arguments | ||
# `module NWSh.arguments` - Ask for arguments | ||
> Provides a set of functions to ask for arguments. | ||
## `class NWSh.arguments.Arguments` | ||
> A class to ask for arguments. | ||
#### `def NWSh.arguments.Arguments.ask_argument(name, description, type)` | ||
> Asks for arguments, with a name, a description and a type.\ | ||
Note: The type can be `string`, `int`, `float`. Conversion is done automatically. | ||
#### `def NWSh.arguments.Arguments.get_argument(name)` | ||
> Returns the value of the argument with the given name. | ||
> If the argument is not found, returns `None` and prints an error message. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# API Documentation - Commands | ||
## `module NWSh.commands` - Create commands | ||
> Provides a set of functions to create commands. | ||
### `def NWSh.commands.register_command_subsystem(subsystem, command, func)` | ||
> Registers a command in a subsystem. | ||
> Arguments are not supported yet | ||
### `def NWSh.commands.register_command_system(system, command, func)` | ||
> Same as `NWSh.commands.register_command_subsystem`, but for the `System` class. |
Oops, something went wrong.