From 588f9cf6a5a059afab136c312e2b09c7e6a5158f Mon Sep 17 00:00:00 2001 From: eliranwong Date: Tue, 3 Dec 2024 21:22:45 +0000 Subject: [PATCH] added api-client-localhost --- setup.py | 3 ++- uniquebible/latest_changes.txt | 10 ++++++++++ uniquebible/main.py | 4 +++- uniquebible/startup/nonGui.py | 33 +++++++++++++++++++++------------ uniquebible/uba.py | 7 ++++++- uniquebible/util/ConfigUtil.py | 2 +- xonsh/completer.py | 2 +- 7 files changed, 44 insertions(+), 17 deletions(-) diff --git a/setup.py b/setup.py index df2d8c637..28b768eeb 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ # https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/ setup( name=package, - version="0.2.5", + version="0.2.7", python_requires=">=3.8, <3.13", description=f"UniqueBible App is a cross-platform & offline bible application, integrated with high-quality resources and unique features. Developers: Eliran Wong and Oliver Tseng", long_description=long_description, @@ -568,6 +568,7 @@ f"ub={package}.uba:stream", f"ubapi={package}.uba:api", f"uba={package}.uba:api", # essentailly the same as ubapi, just quicker to type + f"ubal={package}.uba:apil", # connect to localhost f"ubhttp={package}.uba:http", f"ubssh={package}.uba:ssh", f"ubtelnet={package}.uba:telnet", diff --git a/uniquebible/latest_changes.txt b/uniquebible/latest_changes.txt index 83cf98d3c..f1da86ff7 100755 --- a/uniquebible/latest_changes.txt +++ b/uniquebible/latest_changes.txt @@ -1,5 +1,15 @@ PIP package: +0.2.6 + +* added a running mode `api-client-localhost` + +* added command `ubal` to connect web api running on localhost + +0.2.5 + +* use translateLibre for translation + 0.2.4 * added support of using X AI Grok model diff --git a/uniquebible/main.py b/uniquebible/main.py index 83fe84fce..be70fff26 100755 --- a/uniquebible/main.py +++ b/uniquebible/main.py @@ -28,7 +28,7 @@ os.environ[key] = value # check runmode and initial command -config.noQt = True if config.runMode in ("stream", "terminal", "ssh-server", "telnet-server", "http-server", "api-server", "api-client", "execute-macro") or os.path.isdir("/data/data/com.termux/files/home") else False +config.noQt = True if config.runMode in ("stream", "terminal", "ssh-server", "telnet-server", "http-server", "api-server", "api-client", "api-client-localhost", "execute-macro") or os.path.isdir("/data/data/com.termux/files/home") else False config.cli = True if config.runMode == "cli" else False config.enableCli = True if config.runMode in ("cli", "gui", "docker") else False config.enableApiServer = True if config.runMode == "api-server" else False @@ -100,6 +100,8 @@ run_stream_mode() elif config.runMode == "api-client": run_api_client_mode() + elif config.runMode == "api-client-localhost": + run_api_client_mode(localhost=True) elif config.runMode == "terminal": run_terminal_mode() elif config.runMode == "ssh-server": diff --git a/uniquebible/startup/nonGui.py b/uniquebible/startup/nonGui.py index 9fc05583e..5c1b726b5 100755 --- a/uniquebible/startup/nonGui.py +++ b/uniquebible/startup/nonGui.py @@ -226,17 +226,21 @@ def run_terminal_mode(): # api-client mode -def run_api_client_mode(): +def run_api_client_mode(localhost: bool =False): cwd = os.getcwd() - def getApiOutput(command: str): + def getApiOutput(command: str, localhost: bool =False): + endpoint = f"http://{NetworkUtil.get_ip()}:{config.httpServerPort}/plain" if localhost else config.web_api_endpoint private = f"private={config.web_api_private}&" if config.web_api_private else "" - url = f"""{config.web_api_endpoint}?{private}cmd={command}""" - response = requests.get(url, timeout=config.web_api_timeout) - response.encoding = "utf-8" - print(response.text.strip()) + url = f"""{endpoint}?{private}cmd={command}""" + try: + response = requests.get(url, timeout=config.web_api_timeout) + response.encoding = "utf-8" + print(response.text.strip()) + except Exception as err: + print(f"An error occurred: {err}") - def multiturn_api_output(apiCommandSuggestions=None): + def multiturn_api_output(apiCommandSuggestions=None, localhost=False): from uniquebible.util.prompt_shared_key_bindings import prompt_shared_key_bindings from uniquebible.util.uba_command_prompt_key_bindings import api_command_prompt_key_bindings from uniquebible.util.PromptValidator import NumberValidator @@ -348,7 +352,7 @@ def changeSettings(): # change full width characters command = re.sub(":::", r":::", command) - getApiOutput(command) + getApiOutput(command, localhost=localhost) clear_title() @@ -360,7 +364,7 @@ def changeSettings(): if command: # stream output directly - getApiOutput(command) + getApiOutput(command, localhost=localhost) else: # interactive mode private = f"private={config.web_api_private}&" if config.web_api_private else "" @@ -368,7 +372,7 @@ def changeSettings(): r.encoding = "utf-8" apiCommandSuggestions = r.json() - multiturn_api_output(apiCommandSuggestions=apiCommandSuggestions) + multiturn_api_output(apiCommandSuggestions=apiCommandSuggestions, localhost=localhost) except: #import traceback @@ -494,6 +498,7 @@ def startHttpServer(): if (len(sys.argv) > 2): port = int(sys.argv[2]) config.thisHttpServerPort = port + #ConfigUtil.save() print("Running in HTTP Server Mode") print("Open browser link: 'http://{0}:{1}'".format(NetworkUtil.get_ip(), port)) socketserver.TCPServer.allow_reuse_address = True @@ -511,9 +516,13 @@ def startApiServer(): config.restartApiServer = False port = config.httpServerPort - if (len(sys.argv) > 2): - port = int(sys.argv[2]) + try: + if (len(sys.argv) > 2): + port = int(sys.argv[2]) + except: + pass config.thisHttpServerPort = port + print("Running in API Server Mode") print("API URL: 'http://{0}:{1}'".format(NetworkUtil.get_ip(), port)) socketserver.TCPServer.allow_reuse_address = True diff --git a/uniquebible/uba.py b/uniquebible/uba.py index cdcc2a92c..d7e37cd82 100755 --- a/uniquebible/uba.py +++ b/uniquebible/uba.py @@ -16,7 +16,7 @@ def main(): # check running mode and initial command runMode = sys.argv[1] if len(sys.argv) > 1 else "" - enableCli = True if runMode.lower() in ("stream", "cli", "cli.py", "gui", "terminal", "docker", "telnet-server", "http-server", "execute-macro", "api-server", "api-client") else False + enableCli = True if runMode.lower() in ("stream", "cli", "cli.py", "gui", "terminal", "docker", "telnet-server", "http-server", "execute-macro", "api-server", "api-client", "api-client-localhost") else False initialCommand = input("Enter command: ").strip() if runMode == "-i" else " ".join(sys.argv[1:]).strip() initialCommand = initialCommand.strip() @@ -165,6 +165,11 @@ def api(): sys.argv.insert(1, "api-client") main() +def apil(): + # web api-client, not api-server mode; connect to localhost + sys.argv.insert(1, "api-client-localhost") + main() + def http(): sys.argv.insert(1, "http-server") main() diff --git a/uniquebible/util/ConfigUtil.py b/uniquebible/util/ConfigUtil.py index 15007995d..96b7048f7 100644 --- a/uniquebible/util/ConfigUtil.py +++ b/uniquebible/util/ConfigUtil.py @@ -67,7 +67,7 @@ def setup(noQt=None, cli=None, enableCli=None, enableApiServer=None, enableHttpS # check running mode config.runMode = sys.argv[1].lower() if len(sys.argv) > 1 else "" - if config.runMode and not config.runMode in ("stream", "setup-only", "cli", "gui", "terminal", "docker", "telnet-server", "http-server", "execute-macro", "api-server", "api-client"): + if config.runMode and not config.runMode in ("stream", "setup-only", "cli", "gui", "terminal", "docker", "telnet-server", "http-server", "execute-macro", "api-server", "api-client", "api-client-localhost"): config.runMode = "" # Temporary configurations diff --git a/xonsh/completer.py b/xonsh/completer.py index 4e8864521..8f61d8631 100644 --- a/xonsh/completer.py +++ b/xonsh/completer.py @@ -57,7 +57,7 @@ def ub_completer(context): @non_exclusive_completer @contextual_completer def ubapi_completer(context): - if context.command and context.command.args and context.command.args[0].value in ('ubapi', 'uba') and context.command.prefix: + if context.command and context.command.args and context.command.args[0].value in ('ubapi', 'uba', 'ubal') and context.command.prefix: check = " ".join([i.value for i in context.command.args[1:] if hasattr(i, "value")]) + context.command.prefix if re.search(f"^({'|'.join(bibleKeywords)}):::", check, re.IGNORECASE): return set([context.command.prefix+i for i in api_resources.get("bibleListAbb", [])])