cmdbox 0.6.4.2__py3-none-any.whl → 0.6.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cmdbox might be problematic. Click here for more details.
- cmdbox/app/app.py +7 -0
- cmdbox/app/client.py +384 -383
- cmdbox/app/common.py +85 -7
- cmdbox/app/commons/convert.py +3 -1
- cmdbox/app/edge.py +12 -12
- cmdbox/app/feature.py +1 -1
- cmdbox/app/features/cli/{cmdbox_vision_install.py → _cmdbox_vision_install.py} +2 -10
- cmdbox/app/features/cli/_cmdbox_vision_predict.py +487 -0
- cmdbox/app/features/cli/{cmdbox_vision_start.py → _cmdbox_vision_start.py} +5 -1
- cmdbox/app/features/cli/cmdbox_audit_createdb.py +1 -11
- cmdbox/app/features/cli/cmdbox_audit_delete.py +0 -9
- cmdbox/app/features/cli/cmdbox_audit_search.py +0 -9
- cmdbox/app/features/cli/cmdbox_audit_write.py +0 -9
- cmdbox/app/features/cli/cmdbox_cmd_list.py +3 -3
- cmdbox/app/features/cli/cmdbox_cmd_load.py +3 -3
- cmdbox/app/features/cli/cmdbox_excel_cell_details.py +436 -0
- cmdbox/app/features/cli/cmdbox_excel_cell_search.py +276 -0
- cmdbox/app/features/cli/cmdbox_excel_cell_values.py +258 -0
- cmdbox/app/features/cli/cmdbox_excel_sheet_list.py +159 -0
- cmdbox/app/features/cli/cmdbox_tts_install.py +4 -11
- cmdbox/app/features/cli/cmdbox_tts_say.py +2 -10
- cmdbox/app/features/cli/cmdbox_tts_start.py +0 -9
- cmdbox/app/features/cli/cmdbox_tts_stop.py +0 -9
- cmdbox/app/features/cli/cmdbox_web_apikey_add.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_apikey_del.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_group_add.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_group_del.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_group_edit.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_group_list.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_start.py +10 -10
- cmdbox/app/features/cli/cmdbox_web_user_add.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_user_del.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_user_edit.py +3 -3
- cmdbox/app/features/cli/cmdbox_web_user_list.py +3 -3
- cmdbox/app/features/cli/excel_base.py +301 -0
- cmdbox/app/features/web/cmdbox_web_exec_cmd.py +12 -14
- cmdbox/app/filer.py +5 -2
- cmdbox/app/mcp.py +4 -3
- cmdbox/app/options.py +8 -0
- cmdbox/app/web.py +58 -39
- cmdbox/extensions/features.yml +3 -0
- cmdbox/extensions/sample_project/sample/app/features/cli/sample_server_time.py +0 -9
- cmdbox/licenses/LICENSE_Mako_1_3_10_MIT_License.txt +19 -0
- cmdbox/licenses/LICENSE_alembic_1_16_5_UNKNOWN.txt +19 -0
- cmdbox/licenses/{LICENSE_cffi_1_17_1_MIT_License.txt → LICENSE_cffi_2_0_0_UNKNOWN.txt} +2 -5
- cmdbox/licenses/LICENSE_debugpy_1_8_17_MIT_License.txt +24 -0
- cmdbox/licenses/LICENSE_et_xmlfile_2_0_0_MIT_License.txt +298 -0
- cmdbox/licenses/LICENSE_fastuuid_0_13_5_BSD_License.txt +29 -0
- cmdbox/licenses/LICENSE_google-cloud-monitoring_2_27_2_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_google-cloud-spanner_3_58_0_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_google-genai_1_40_0_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_grpc-interceptor_0_15_4_MIT_License.txt +21 -0
- cmdbox/licenses/{LICENSE_lazy-object-proxy_1_11_0_BSD_License.txt → LICENSE_lazy-object-proxy_1_12_0_UNKNOWN.txt} +1 -1
- cmdbox/licenses/LICENSE_openpyxl_3_1_5_MIT_License.txt +23 -0
- cmdbox/licenses/LICENSE_opentelemetry-exporter-otlp-proto-common_1_37_0_UNKNOWN.txt +201 -0
- cmdbox/licenses/LICENSE_opentelemetry-exporter-otlp-proto-http_1_37_0_UNKNOWN.txt +201 -0
- cmdbox/licenses/LICENSE_opentelemetry-proto_1_37_0_UNKNOWN.txt +201 -0
- cmdbox/licenses/LICENSE_opentelemetry-sdk_1_37_0_UNKNOWN.txt +201 -0
- cmdbox/licenses/LICENSE_opentelemetry-semantic-conventions_0_58b0_UNKNOWN.txt +201 -0
- cmdbox/licenses/LICENSE_sqlalchemy-spanner_1_16_0_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_sqlparse_0_5_3_BSD_License.txt +25 -0
- cmdbox/licenses/{LICENSE_uvicorn_0_35_0_BSD_License.txt → LICENSE_uvicorn_0_37_0_BSD_License.txt} +2 -1
- cmdbox/licenses/files.txt +82 -71
- cmdbox/version.py +2 -2
- cmdbox/web/assets/cmdbox/svgicon.js +9 -0
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/METADATA +29 -29
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/RECORD +133 -117
- cmdbox/app/features/cli/cmdbox_vision_predict.py +0 -192
- cmdbox/licenses/LICENSE_APScheduler_3_11_0_MIT_License.txt +0 -19
- cmdbox/licenses/LICENSE_backoff_2_2_1_MIT_License.txt +0 -21
- cmdbox/licenses/LICENSE_fastapi-sso_0_18_0_MIT_License.txt +0 -21
- cmdbox/licenses/LICENSE_litellm-enterprise_0_1_19_UNKNOWN.txt +0 -37
- cmdbox/licenses/LICENSE_oauthlib_3_3_1_BSD-3-Clause.txt +0 -27
- cmdbox/licenses/LICENSE_orjson_3_11_1_Apache_Software_License-MIT_License.txt +0 -201
- /cmdbox/licenses/{LICENSE_Authlib_1_6_1_BSD_License.txt → LICENSE_Authlib_1_6_5_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_MarkupSafe_3_0_2_BSD_License.txt → LICENSE_MarkupSafe_3_0_3_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_PyYAML_6_0_2_MIT_License.txt → LICENSE_PyYAML_6_0_3_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_anyio_4_10_0_UNKNOWN.txt → LICENSE_anyio_4_11_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_cachetools_5_5_2_MIT_License.txt → LICENSE_cachetools_6_2_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_click_8_2_1_UNKNOWN.txt → LICENSE_click_8_3_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_cryptography_45_0_6_Apache-2_0_OR_BSD-3-Clause.txt → LICENSE_cryptography_46_0_2_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_cyclopts_3_22_5_Apache_Software_License.txt → LICENSE_cyclopts_3_24_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_dnspython_2_7_0_ISC_License-ISCL.txt → LICENSE_dnspython_2_8_0_ISC_License-ISCL.txt} +0 -0
- /cmdbox/licenses/{LICENSE_email_validator_2_2_0_The_Unlicense-Unlicense.txt → LICENSE_email-validator_2_3_0_The_Unlicense-Unlicense.txt} +0 -0
- /cmdbox/licenses/{LICENSE_fastapi_0_116_1_MIT_License.txt → LICENSE_fastapi_0_118_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_fastmcp_2_11_3_Apache_Software_License.txt → LICENSE_fastmcp_2_12_4_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_filelock_3_18_0_The_Unlicense-Unlicense.txt → LICENSE_filelock_3_19_1_The_Unlicense-Unlicense.txt} +0 -0
- /cmdbox/licenses/{LICENSE_fsspec_2025_7_0_BSD_License.txt → LICENSE_fsspec_2025_9_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_gevent_25_5_1_MIT.txt → LICENSE_gevent_25_9_1_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-adk_1_10_0_Apache_Software_License.txt → LICENSE_google-adk_1_15_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-api-core_2_25_1_Apache_Software_License.txt → LICENSE_google-api-core_2_25_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-api-python-client_2_178_0_Apache_Software_License.txt → LICENSE_google-api-python-client_2_184_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-auth_2_40_3_Apache_Software_License.txt → LICENSE_google-auth_2_41_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-cloud-aiplatform_1_108_0_Apache_2_0.txt → LICENSE_google-cloud-aiplatform_1_119_0_Apache_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-cloud-bigquery_3_35_1_Apache_Software_License.txt → LICENSE_google-cloud-bigquery_3_38_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_google-genai_1_29_0_Apache_Software_License.txt → LICENSE_google-cloud-bigtable_2_32_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_grpcio-status_1_74_0_Apache_Software_License.txt → LICENSE_grpcio-status_1_75_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_grpcio_1_74_0_Apache_Software_License.txt → LICENSE_grpcio_1_75_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_httplib2_0_22_0_MIT_License.txt → LICENSE_httplib2_0_31_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_huggingface-hub_0_34_4_Apache_Software_License.txt → LICENSE_huggingface-hub_0_35_3_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_jaraco_functools_4_2_1_UNKNOWN.txt → LICENSE_jaraco_functools_4_3_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_jiter_0_10_0_MIT_License.txt → LICENSE_jiter_0_11_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_jsonschema-specifications_2025_4_1_UNKNOWN.txt → LICENSE_jsonschema-specifications_2025_9_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_jsonschema_4_25_0_UNKNOWN.txt → LICENSE_jsonschema_4_25_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_litellm_1_75_5_post1_MIT_License.txt → LICENSE_litellm_1_77_5_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_mcp_1_12_4_MIT_License.txt → LICENSE_mcp_1_16_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_more-itertools_10_7_0_MIT_License.txt → LICENSE_more-itertools_10_8_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_numpy_2_3_2_BSD_License.txt → LICENSE_numpy_2_3_3_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_openai_1_99_9_Apache_Software_License.txt → LICENSE_openai_2_1_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_opentelemetry-api_1_36_0_UNKNOWN.txt → LICENSE_opentelemetry-api_1_37_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_opentelemetry-sdk_1_36_0_UNKNOWN.txt → LICENSE_opentelemetry-exporter-gcp-logging_1_9_0a0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_opentelemetry-semantic-conventions_0_57b0_UNKNOWN.txt → LICENSE_opentelemetry-exporter-gcp-monitoring_1_9_0a0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_prompt_toolkit_3_0_51_BSD_License.txt → LICENSE_prompt_toolkit_3_0_52_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_protobuf_6_31_1_3-Clause_BSD_License.txt → LICENSE_protobuf_6_32_1_3-Clause_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_psycopg-binary_3_2_9_GNU_Lesser_General_Public_License_v3-LGPLv3.txt → LICENSE_psycopg-binary_3_2_10_GNU_Lesser_General_Public_License_v3-LGPLv3.txt} +0 -0
- /cmdbox/licenses/{LICENSE_psycopg_3_2_9_GNU_Lesser_General_Public_License_v3-LGPLv3.txt → LICENSE_psycopg_3_2_10_GNU_Lesser_General_Public_License_v3-LGPLv3.txt} +0 -0
- /cmdbox/licenses/{LICENSE_pycparser_2_22_BSD_License.txt → LICENSE_pycparser_2_23_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_pydantic-settings_2_10_1_MIT_License.txt → LICENSE_pydantic-settings_2_11_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_pydantic_2_11_7_MIT_License.txt → LICENSE_pydantic_2_11_10_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_pyparsing_3_2_3_MIT_License.txt → LICENSE_pyparsing_3_2_5_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_pyperclip_1_9_0_BSD_License.txt → LICENSE_pyperclip_1_11_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_questionary_2_1_0_MIT_License.txt → LICENSE_questionary_2_1_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_regex_2025_7_34_UNKNOWN.txt → LICENSE_regex_2025_9_18_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_requests_2_32_4_Apache_Software_License.txt → LICENSE_requests_2_32_5_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_rpds-py_0_27_0_UNKNOWN.txt → LICENSE_rpds-py_0_27_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_shapely_2_1_1_BSD_License.txt → LICENSE_shapely_2_1_2_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_sphinx-sitemap_2_7_2_UNKNOWN.txt → LICENSE_sphinx-sitemap_2_8_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_starlette_0_47_2_BSD_License.txt → LICENSE_starlette_0_48_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_tenacity_9_1_2_Apache_Software_License.txt → LICENSE_tenacity_8_5_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_tokenizers_0_21_4_Apache_Software_License.txt → LICENSE_tokenizers_0_22_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_twine_6_1_0_Apache_Software_License.txt → LICENSE_twine_6_2_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_typing-inspection_0_4_1_UNKNOWN.txt → LICENSE_typing-inspection_0_4_2_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_typing_extensions_4_14_1_UNKNOWN.txt → LICENSE_typing_extensions_4_15_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE_wcwidth_0_2_13_MIT_License.txt → LICENSE_wcwidth_0_2_14_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_zope_event_5_1_1_Zope_Public_License.txt → LICENSE_zope_event_6_0_Zope_Public_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE_zope_interface_7_2_Zope_Public_License.txt → LICENSE_zope_interface_8_0_1_Zope_Public_License.txt} +0 -0
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/WHEEL +0 -0
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/entry_points.txt +0 -0
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/licenses/LICENSE +0 -0
- {cmdbox-0.6.4.2.dist-info → cmdbox-0.6.6.dist-info}/top_level.txt +0 -0
cmdbox/app/client.py
CHANGED
|
@@ -1,383 +1,384 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from cmdbox.app import filer
|
|
3
|
-
from cmdbox.app.commons import convert, redis_client
|
|
4
|
-
import base64
|
|
5
|
-
import logging
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Client(object):
|
|
9
|
-
def __init__(self, logger:logging.Logger, redis_host:str = "localhost", redis_port:int = 6379, redis_password:str = None, svname:str = 'server'):
|
|
10
|
-
"""
|
|
11
|
-
Redisサーバーとの通信を行うクラス
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
logger (logging): ロガー
|
|
15
|
-
redis_host (str, optional): Redisサーバーのホスト名. Defaults to "localhost".
|
|
16
|
-
redis_port (int, optional): Redisサーバーのポート番号. Defaults to 6379.
|
|
17
|
-
redis_password (str, optional): Redisサーバーのパスワード. Defaults to None.
|
|
18
|
-
svname (str, optional): サーバーのサービス名. Defaults to 'server'.
|
|
19
|
-
"""
|
|
20
|
-
self.logger = logger
|
|
21
|
-
if svname is None or svname == "":
|
|
22
|
-
raise Exception("svname is empty.")
|
|
23
|
-
if svname.find('-') >= 0:
|
|
24
|
-
raise ValueError(f"Server name is invalid. '-' is not allowed. svname={svname}")
|
|
25
|
-
self.redis_cli = redis_client.RedisClient(logger, host=redis_host, port=redis_port, password=redis_password, svname=svname)
|
|
26
|
-
self.is_running = False
|
|
27
|
-
|
|
28
|
-
def __exit__(self, a, b, c):
|
|
29
|
-
pass
|
|
30
|
-
|
|
31
|
-
def stop_server(self, retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
32
|
-
"""
|
|
33
|
-
Redisサーバーを停止する
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
37
|
-
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
38
|
-
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
dict: Redisサーバーからの応答
|
|
42
|
-
"""
|
|
43
|
-
res_json = self.redis_cli.send_cmd('stop_server', [], retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
44
|
-
return res_json
|
|
45
|
-
|
|
46
|
-
def file_list(self, svpath:str, recursive:bool, scope:str="client", client_data:Path = None,
|
|
47
|
-
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
48
|
-
"""
|
|
49
|
-
サーバー上のファイルリストを取得する
|
|
50
|
-
|
|
51
|
-
Args:
|
|
52
|
-
svpath (Path): サーバー上のファイルパス
|
|
53
|
-
recursive (bool): 再帰的に取得するかどうか
|
|
54
|
-
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
55
|
-
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
56
|
-
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
57
|
-
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
58
|
-
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
dict: Redisサーバーからの応答
|
|
62
|
-
"""
|
|
63
|
-
if scope == "client":
|
|
64
|
-
if client_data is not None:
|
|
65
|
-
f = filer.Filer(client_data, self.logger)
|
|
66
|
-
_, res_json = f.file_list(svpath, recursive)
|
|
67
|
-
return res_json
|
|
68
|
-
else:
|
|
69
|
-
self.logger.warning(f"client_data is empty.")
|
|
70
|
-
return dict(warn=f"client_data is empty.")
|
|
71
|
-
elif scope == "current":
|
|
72
|
-
f = filer.Filer(Path.cwd(), self.logger)
|
|
73
|
-
_, res_json = f.file_list(svpath, recursive)
|
|
74
|
-
return res_json
|
|
75
|
-
elif scope == "server":
|
|
76
|
-
res_json = self.redis_cli.send_cmd('file_list', [convert.str2b64str(str(svpath)), str(recursive)],
|
|
77
|
-
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
78
|
-
return res_json
|
|
79
|
-
else:
|
|
80
|
-
self.logger.warning(f"scope is invalid. {scope}")
|
|
81
|
-
return dict(warn=f"scope is invalid. {scope}")
|
|
82
|
-
|
|
83
|
-
def file_mkdir(self, svpath:str, scope:str="client", client_data:Path = None,
|
|
84
|
-
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
85
|
-
"""
|
|
86
|
-
サーバー上にディレクトリを作成する
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
svpath (Path): サーバー上のディレクトリパス
|
|
90
|
-
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
91
|
-
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
92
|
-
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
93
|
-
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
94
|
-
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
95
|
-
|
|
96
|
-
Returns:
|
|
97
|
-
dict: Redisサーバーからの応答
|
|
98
|
-
"""
|
|
99
|
-
if scope == "client":
|
|
100
|
-
if client_data is not None:
|
|
101
|
-
f = filer.Filer(client_data, self.logger)
|
|
102
|
-
_, res_json = f.file_mkdir(svpath)
|
|
103
|
-
return res_json
|
|
104
|
-
else:
|
|
105
|
-
self.logger.warning(f"client_data is empty.")
|
|
106
|
-
return dict(warn=f"client_data is empty.")
|
|
107
|
-
elif scope == "current":
|
|
108
|
-
f = filer.Filer(Path.cwd(), self.logger)
|
|
109
|
-
_, res_json = f.file_mkdir(svpath)
|
|
110
|
-
return res_json
|
|
111
|
-
elif scope == "server":
|
|
112
|
-
res_json = self.redis_cli.send_cmd('file_mkdir', [convert.str2b64str(str(svpath))],
|
|
113
|
-
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
114
|
-
return res_json
|
|
115
|
-
else:
|
|
116
|
-
self.logger.warning(f"scope is invalid. {scope}")
|
|
117
|
-
return dict(warn=f"scope is invalid. {scope}")
|
|
118
|
-
|
|
119
|
-
def file_rmdir(self, svpath:str, scope:str="client", client_data:Path = None,
|
|
120
|
-
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
121
|
-
"""
|
|
122
|
-
サーバー上のディレクトリを削除する
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
svpath (Path): サーバー上のディレクトリパス
|
|
126
|
-
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
127
|
-
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
128
|
-
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
129
|
-
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
130
|
-
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
131
|
-
|
|
132
|
-
Returns:
|
|
133
|
-
dict: Redisサーバーからの応答
|
|
134
|
-
"""
|
|
135
|
-
if scope == "client":
|
|
136
|
-
if client_data is not None:
|
|
137
|
-
f = filer.Filer(client_data, self.logger)
|
|
138
|
-
_, res_json = f.file_rmdir(svpath)
|
|
139
|
-
return res_json
|
|
140
|
-
else:
|
|
141
|
-
self.logger.warning(f"client_data is empty.")
|
|
142
|
-
return dict(warn=f"client_data is empty.")
|
|
143
|
-
elif scope == "current":
|
|
144
|
-
f = filer.Filer(Path.cwd(), self.logger)
|
|
145
|
-
_, res_json = f.file_rmdir(svpath)
|
|
146
|
-
return res_json
|
|
147
|
-
elif scope == "server":
|
|
148
|
-
res_json = self.redis_cli.send_cmd('file_rmdir', [convert.str2b64str(str(svpath))],
|
|
149
|
-
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
150
|
-
return res_json
|
|
151
|
-
else:
|
|
152
|
-
self.logger.warning(f"scope is invalid. {scope}")
|
|
153
|
-
return dict(warn=f"scope is invalid. {scope}")
|
|
154
|
-
|
|
155
|
-
def file_download(self, svpath:str, download_file:Path, scope:str="client", client_data:Path = None, rpath:str="", img_thumbnail:float=0.0,
|
|
156
|
-
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
157
|
-
"""
|
|
158
|
-
サーバー上のファイルをダウンロードする
|
|
159
|
-
|
|
160
|
-
Args:
|
|
161
|
-
svpath (Path): サーバー上のファイルパス
|
|
162
|
-
download_file (Path): ローカルのファイルパス
|
|
163
|
-
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
164
|
-
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
165
|
-
rpath (str, optional): リクエストパス. Defaults to "".
|
|
166
|
-
img_thumbnail (float, optional): サムネイル画像のサイズ. Defaults to 0.0.
|
|
167
|
-
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
168
|
-
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
169
|
-
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
bytes: ダウンロードファイルの内容
|
|
173
|
-
"""
|
|
174
|
-
if scope == "client":
|
|
175
|
-
if client_data is not None:
|
|
176
|
-
f = filer.Filer(client_data, self.logger)
|
|
177
|
-
_, res_json = f.file_download(svpath, img_thumbnail)
|
|
178
|
-
else:
|
|
179
|
-
self.logger.warning(f"client_data is empty.")
|
|
180
|
-
return dict(warn=f"client_data is empty.")
|
|
181
|
-
elif scope == "current":
|
|
182
|
-
f = filer.Filer(Path.cwd(), self.logger)
|
|
183
|
-
_, res_json = f.file_download(svpath, img_thumbnail)
|
|
184
|
-
elif scope == "server":
|
|
185
|
-
res_json = self.redis_cli.send_cmd('file_download', [convert.str2b64str(str(svpath)), str(img_thumbnail)],
|
|
186
|
-
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
187
|
-
else:
|
|
188
|
-
self.logger.warning(f"scope is invalid. {scope}")
|
|
189
|
-
return dict(warn=f"scope is invalid. {scope}")
|
|
190
|
-
if "success" in res_json:
|
|
191
|
-
res_json["success"]["rpath"] = rpath
|
|
192
|
-
res_json["success"]["svpath"] = svpath
|
|
193
|
-
if download_file is not None:
|
|
194
|
-
if download_file.is_dir():
|
|
195
|
-
download_file = download_file / res_json["success"]["name"]
|
|
196
|
-
if download_file.exists():
|
|
197
|
-
self.logger.warning(f"download_file {download_file} already exists.")
|
|
198
|
-
return dict(warn=f"download_file {download_file} already exists.")
|
|
199
|
-
|
|
200
|
-
f.write(base64.b64decode(res_json["success"]["data"]))
|
|
201
|
-
del res_json["success"]["data"]
|
|
202
|
-
res_json["success"]["download_file"] = str(download_file.absolute())
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
convert.str2b64str(
|
|
250
|
-
convert.
|
|
251
|
-
|
|
252
|
-
str(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from cmdbox.app import common, filer
|
|
3
|
+
from cmdbox.app.commons import convert, redis_client
|
|
4
|
+
import base64
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Client(object):
|
|
9
|
+
def __init__(self, logger:logging.Logger, redis_host:str = "localhost", redis_port:int = 6379, redis_password:str = None, svname:str = 'server'):
|
|
10
|
+
"""
|
|
11
|
+
Redisサーバーとの通信を行うクラス
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
logger (logging): ロガー
|
|
15
|
+
redis_host (str, optional): Redisサーバーのホスト名. Defaults to "localhost".
|
|
16
|
+
redis_port (int, optional): Redisサーバーのポート番号. Defaults to 6379.
|
|
17
|
+
redis_password (str, optional): Redisサーバーのパスワード. Defaults to None.
|
|
18
|
+
svname (str, optional): サーバーのサービス名. Defaults to 'server'.
|
|
19
|
+
"""
|
|
20
|
+
self.logger = logger
|
|
21
|
+
if svname is None or svname == "":
|
|
22
|
+
raise Exception("svname is empty.")
|
|
23
|
+
if svname.find('-') >= 0:
|
|
24
|
+
raise ValueError(f"Server name is invalid. '-' is not allowed. svname={svname}")
|
|
25
|
+
self.redis_cli = redis_client.RedisClient(logger, host=redis_host, port=redis_port, password=redis_password, svname=svname)
|
|
26
|
+
self.is_running = False
|
|
27
|
+
|
|
28
|
+
def __exit__(self, a, b, c):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def stop_server(self, retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
32
|
+
"""
|
|
33
|
+
Redisサーバーを停止する
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
37
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
38
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
dict: Redisサーバーからの応答
|
|
42
|
+
"""
|
|
43
|
+
res_json = self.redis_cli.send_cmd('stop_server', [], retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
44
|
+
return res_json
|
|
45
|
+
|
|
46
|
+
def file_list(self, svpath:str, recursive:bool, scope:str="client", client_data:Path = None,
|
|
47
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
48
|
+
"""
|
|
49
|
+
サーバー上のファイルリストを取得する
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
svpath (Path): サーバー上のファイルパス
|
|
53
|
+
recursive (bool): 再帰的に取得するかどうか
|
|
54
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
55
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
56
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
57
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
58
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
dict: Redisサーバーからの応答
|
|
62
|
+
"""
|
|
63
|
+
if scope == "client":
|
|
64
|
+
if client_data is not None:
|
|
65
|
+
f = filer.Filer(client_data, self.logger)
|
|
66
|
+
_, res_json = f.file_list(svpath, recursive)
|
|
67
|
+
return res_json
|
|
68
|
+
else:
|
|
69
|
+
self.logger.warning(f"client_data is empty.")
|
|
70
|
+
return dict(warn=f"client_data is empty.")
|
|
71
|
+
elif scope == "current":
|
|
72
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
73
|
+
_, res_json = f.file_list(svpath, recursive)
|
|
74
|
+
return res_json
|
|
75
|
+
elif scope == "server":
|
|
76
|
+
res_json = self.redis_cli.send_cmd('file_list', [convert.str2b64str(str(svpath)), str(recursive)],
|
|
77
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
78
|
+
return res_json
|
|
79
|
+
else:
|
|
80
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
81
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
82
|
+
|
|
83
|
+
def file_mkdir(self, svpath:str, scope:str="client", client_data:Path = None,
|
|
84
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
85
|
+
"""
|
|
86
|
+
サーバー上にディレクトリを作成する
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
svpath (Path): サーバー上のディレクトリパス
|
|
90
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
91
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
92
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
93
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
94
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
dict: Redisサーバーからの応答
|
|
98
|
+
"""
|
|
99
|
+
if scope == "client":
|
|
100
|
+
if client_data is not None:
|
|
101
|
+
f = filer.Filer(client_data, self.logger)
|
|
102
|
+
_, res_json = f.file_mkdir(svpath)
|
|
103
|
+
return res_json
|
|
104
|
+
else:
|
|
105
|
+
self.logger.warning(f"client_data is empty.")
|
|
106
|
+
return dict(warn=f"client_data is empty.")
|
|
107
|
+
elif scope == "current":
|
|
108
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
109
|
+
_, res_json = f.file_mkdir(svpath)
|
|
110
|
+
return res_json
|
|
111
|
+
elif scope == "server":
|
|
112
|
+
res_json = self.redis_cli.send_cmd('file_mkdir', [convert.str2b64str(str(svpath))],
|
|
113
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
114
|
+
return res_json
|
|
115
|
+
else:
|
|
116
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
117
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
118
|
+
|
|
119
|
+
def file_rmdir(self, svpath:str, scope:str="client", client_data:Path = None,
|
|
120
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
121
|
+
"""
|
|
122
|
+
サーバー上のディレクトリを削除する
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
svpath (Path): サーバー上のディレクトリパス
|
|
126
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
127
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
128
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
129
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
130
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
dict: Redisサーバーからの応答
|
|
134
|
+
"""
|
|
135
|
+
if scope == "client":
|
|
136
|
+
if client_data is not None:
|
|
137
|
+
f = filer.Filer(client_data, self.logger)
|
|
138
|
+
_, res_json = f.file_rmdir(svpath)
|
|
139
|
+
return res_json
|
|
140
|
+
else:
|
|
141
|
+
self.logger.warning(f"client_data is empty.")
|
|
142
|
+
return dict(warn=f"client_data is empty.")
|
|
143
|
+
elif scope == "current":
|
|
144
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
145
|
+
_, res_json = f.file_rmdir(svpath)
|
|
146
|
+
return res_json
|
|
147
|
+
elif scope == "server":
|
|
148
|
+
res_json = self.redis_cli.send_cmd('file_rmdir', [convert.str2b64str(str(svpath))],
|
|
149
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
150
|
+
return res_json
|
|
151
|
+
else:
|
|
152
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
153
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
154
|
+
|
|
155
|
+
def file_download(self, svpath:str, download_file:Path, scope:str="client", client_data:Path = None, rpath:str="", img_thumbnail:float=0.0,
|
|
156
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
157
|
+
"""
|
|
158
|
+
サーバー上のファイルをダウンロードする
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
svpath (Path): サーバー上のファイルパス
|
|
162
|
+
download_file (Path): ローカルのファイルパス
|
|
163
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
164
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
165
|
+
rpath (str, optional): リクエストパス. Defaults to "".
|
|
166
|
+
img_thumbnail (float, optional): サムネイル画像のサイズ. Defaults to 0.0.
|
|
167
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
168
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
169
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
bytes: ダウンロードファイルの内容
|
|
173
|
+
"""
|
|
174
|
+
if scope == "client":
|
|
175
|
+
if client_data is not None:
|
|
176
|
+
f = filer.Filer(client_data, self.logger)
|
|
177
|
+
_, res_json = f.file_download(svpath, img_thumbnail)
|
|
178
|
+
else:
|
|
179
|
+
self.logger.warning(f"client_data is empty.")
|
|
180
|
+
return dict(warn=f"client_data is empty.")
|
|
181
|
+
elif scope == "current":
|
|
182
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
183
|
+
_, res_json = f.file_download(svpath, img_thumbnail)
|
|
184
|
+
elif scope == "server":
|
|
185
|
+
res_json = self.redis_cli.send_cmd('file_download', [convert.str2b64str(str(svpath)), str(img_thumbnail)],
|
|
186
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
187
|
+
else:
|
|
188
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
189
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
190
|
+
if "success" in res_json:
|
|
191
|
+
res_json["success"]["rpath"] = rpath
|
|
192
|
+
res_json["success"]["svpath"] = svpath
|
|
193
|
+
if download_file is not None:
|
|
194
|
+
if download_file.is_dir():
|
|
195
|
+
download_file = download_file / res_json["success"]["name"]
|
|
196
|
+
if download_file.exists():
|
|
197
|
+
self.logger.warning(f"download_file {download_file} already exists.")
|
|
198
|
+
return dict(warn=f"download_file {download_file} already exists.")
|
|
199
|
+
def _wd(f):
|
|
200
|
+
f.write(base64.b64decode(res_json["success"]["data"]))
|
|
201
|
+
del res_json["success"]["data"]
|
|
202
|
+
res_json["success"]["download_file"] = str(download_file.absolute())
|
|
203
|
+
common.save_file(download_file, _wd, mode='wb')
|
|
204
|
+
return res_json
|
|
205
|
+
|
|
206
|
+
def file_upload(self, svpath:str, upload_file:Path, scope:str="client", client_data:Path=None, mkdir:bool=False, orverwrite:bool=False,
|
|
207
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
208
|
+
"""
|
|
209
|
+
サーバー上にファイルをアップロードする
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
svpath (Path): サーバー上のファイルパス
|
|
213
|
+
upload_file (Path): ローカルのファイルパス
|
|
214
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
215
|
+
mkdir (bool, optional): ディレクトリを作成するかどうか. Defaults to False.
|
|
216
|
+
orverwrite (bool, optional): 上書きするかどうか. Defaults to False.
|
|
217
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
218
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
219
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
220
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
dict: Redisサーバーからの応答
|
|
224
|
+
"""
|
|
225
|
+
if upload_file is None:
|
|
226
|
+
self.logger.warning(f"upload_file is empty.")
|
|
227
|
+
return dict(warn=f"upload_file is empty.")
|
|
228
|
+
if not upload_file.exists():
|
|
229
|
+
self.logger.warning(f"input_file {upload_file} does not exist.")
|
|
230
|
+
return dict(warn=f"input_file {upload_file} does not exist.")
|
|
231
|
+
if upload_file.is_dir():
|
|
232
|
+
self.logger.warning(f"input_file {upload_file} is directory.")
|
|
233
|
+
return dict(warn=f"input_file {upload_file} is directory.")
|
|
234
|
+
with open(upload_file, "rb") as f:
|
|
235
|
+
if scope == "client":
|
|
236
|
+
if client_data is not None:
|
|
237
|
+
fi = filer.Filer(client_data, self.logger)
|
|
238
|
+
_, res_json = fi.file_upload(svpath, upload_file.name, f.read(), mkdir, orverwrite)
|
|
239
|
+
return res_json
|
|
240
|
+
else:
|
|
241
|
+
self.logger.warning(f"client_data is empty.")
|
|
242
|
+
return dict(warn=f"client_data is empty.")
|
|
243
|
+
elif scope == "current":
|
|
244
|
+
fi = filer.Filer(Path.cwd(), self.logger)
|
|
245
|
+
_, res_json = fi.file_upload(svpath, upload_file.name, f.read(), mkdir, orverwrite)
|
|
246
|
+
return res_json
|
|
247
|
+
elif scope == "server":
|
|
248
|
+
res_json = self.redis_cli.send_cmd('file_upload',
|
|
249
|
+
[convert.str2b64str(str(svpath)),
|
|
250
|
+
convert.str2b64str(upload_file.name),
|
|
251
|
+
convert.bytes2b64str(f.read()),
|
|
252
|
+
str(mkdir),
|
|
253
|
+
str(orverwrite)],
|
|
254
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
255
|
+
return res_json
|
|
256
|
+
else:
|
|
257
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
258
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
259
|
+
|
|
260
|
+
def file_remove(self, svpath:str, scope:str="client", client_data:Path = None,
|
|
261
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
262
|
+
"""
|
|
263
|
+
サーバー上のファイルを削除する
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
svpath (Path): サーバー上のファイルパス
|
|
267
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
268
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
269
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
270
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
271
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
dict: Redisサーバーからの応答
|
|
275
|
+
"""
|
|
276
|
+
if scope == "client":
|
|
277
|
+
if client_data is not None:
|
|
278
|
+
f = filer.Filer(client_data, self.logger)
|
|
279
|
+
_, res_json = f.file_remove(svpath)
|
|
280
|
+
return res_json
|
|
281
|
+
else:
|
|
282
|
+
self.logger.warning(f"client_data is empty.")
|
|
283
|
+
return dict(warn=f"client_data is empty.")
|
|
284
|
+
elif scope == "current":
|
|
285
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
286
|
+
_, res_json = f.file_remove(svpath)
|
|
287
|
+
return res_json
|
|
288
|
+
elif scope == "server":
|
|
289
|
+
res_json = self.redis_cli.send_cmd('file_remove', [convert.str2b64str(str(svpath))],
|
|
290
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
291
|
+
return res_json
|
|
292
|
+
else:
|
|
293
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
294
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
295
|
+
|
|
296
|
+
def file_copy(self, from_path:str, to_path:str, orverwrite:bool=False, scope:str="client", client_data:Path = None,
|
|
297
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
298
|
+
"""
|
|
299
|
+
サーバー上のファイルをコピーする
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
from_path (Path): コピー元のファイルパス
|
|
303
|
+
to_path (Path): コピー先のファイルパス
|
|
304
|
+
orverwrite (bool, optional): 上書きするかどうか. Defaults to False.
|
|
305
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
306
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
307
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
308
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
309
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
dict: Redisサーバーからの応答
|
|
313
|
+
"""
|
|
314
|
+
if scope == "client":
|
|
315
|
+
if client_data is not None:
|
|
316
|
+
f = filer.Filer(client_data, self.logger)
|
|
317
|
+
_, res_json = f.file_copy(from_path, to_path, orverwrite)
|
|
318
|
+
return res_json
|
|
319
|
+
else:
|
|
320
|
+
self.logger.warning(f"client_data is empty.")
|
|
321
|
+
return dict(warn=f"client_data is empty.")
|
|
322
|
+
elif scope == "current":
|
|
323
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
324
|
+
_, res_json = f.file_copy(from_path, to_path, orverwrite)
|
|
325
|
+
return res_json
|
|
326
|
+
elif scope == "server":
|
|
327
|
+
res_json = self.redis_cli.send_cmd('file_copy', [convert.str2b64str(str(from_path)), convert.str2b64str(str(to_path)), str(orverwrite)],
|
|
328
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
329
|
+
return res_json
|
|
330
|
+
else:
|
|
331
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
332
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
333
|
+
|
|
334
|
+
def file_move(self, from_path:str, to_path:str, scope:str="client", client_data:Path = None,
|
|
335
|
+
retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
336
|
+
"""
|
|
337
|
+
サーバー上のファイルを移動する
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
from_path (Path): 移動元のファイルパス
|
|
341
|
+
to_path (Path): 移動先のファイルパス
|
|
342
|
+
scope (str, optional): 参照先のスコープ. Defaults to "client".
|
|
343
|
+
client_data (Path, optional): ローカルを参照させる場合のデータフォルダ. Defaults to None.
|
|
344
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
345
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
346
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
dict: Redisサーバーからの応答
|
|
350
|
+
"""
|
|
351
|
+
if scope == "client":
|
|
352
|
+
if client_data is not None:
|
|
353
|
+
f = filer.Filer(client_data, self.logger)
|
|
354
|
+
_, res_json = f.file_move(from_path, to_path)
|
|
355
|
+
return res_json
|
|
356
|
+
else:
|
|
357
|
+
self.logger.warning(f"client_data is empty.")
|
|
358
|
+
return dict(warn=f"client_data is empty.")
|
|
359
|
+
elif scope == "current":
|
|
360
|
+
f = filer.Filer(Path.cwd(), self.logger)
|
|
361
|
+
_, res_json = f.file_move(from_path, to_path)
|
|
362
|
+
return res_json
|
|
363
|
+
elif scope == "server":
|
|
364
|
+
res_json = self.redis_cli.send_cmd('file_move', [convert.str2b64str(str(from_path)), convert.str2b64str(str(to_path))],
|
|
365
|
+
retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
366
|
+
return res_json
|
|
367
|
+
else:
|
|
368
|
+
self.logger.warning(f"scope is invalid. {scope}")
|
|
369
|
+
return dict(warn=f"scope is invalid. {scope}")
|
|
370
|
+
|
|
371
|
+
def server_info(self, retry_count:int=3, retry_interval:int=5, timeout:int=60):
|
|
372
|
+
"""
|
|
373
|
+
サーバーの情報を取得する
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
retry_count (int, optional): リトライ回数. Defaults to 3.
|
|
377
|
+
retry_interval (int, optional): リトライ間隔. Defaults to 5.
|
|
378
|
+
timeout (int, optional): タイムアウト時間. Defaults to 60.
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
dict: Redisサーバーからの応答
|
|
382
|
+
"""
|
|
383
|
+
res_json = self.redis_cli.send_cmd('server_info', [], retry_count=retry_count, retry_interval=retry_interval, timeout=timeout)
|
|
384
|
+
return res_json
|