cmdbox 0.5.2__py3-none-any.whl → 0.5.3.1__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.

Files changed (114) hide show
  1. cmdbox/app/auth/signin.py +1 -0
  2. cmdbox/app/feature.py +2 -0
  3. cmdbox/app/features/cli/audit_base.py +5 -2
  4. cmdbox/app/features/cli/cmdbox_audit_createdb.py +1 -1
  5. cmdbox/app/features/cli/cmdbox_audit_delete.py +27 -18
  6. cmdbox/app/features/cli/cmdbox_audit_search.py +128 -62
  7. cmdbox/app/features/cli/cmdbox_audit_write.py +31 -20
  8. cmdbox/app/features/cli/cmdbox_client_file_copy.py +1 -1
  9. cmdbox/app/features/cli/cmdbox_client_file_download.py +1 -1
  10. cmdbox/app/features/cli/cmdbox_client_file_list.py +1 -1
  11. cmdbox/app/features/cli/cmdbox_client_file_mkdir.py +1 -1
  12. cmdbox/app/features/cli/cmdbox_client_file_move.py +1 -1
  13. cmdbox/app/features/cli/cmdbox_client_file_remove.py +1 -1
  14. cmdbox/app/features/cli/cmdbox_client_file_rmdir.py +1 -1
  15. cmdbox/app/features/cli/cmdbox_client_file_upload.py +1 -1
  16. cmdbox/app/features/cli/cmdbox_client_server_info.py +1 -1
  17. cmdbox/app/features/cli/cmdbox_gui_start.py +1 -1
  18. cmdbox/app/features/cli/cmdbox_server_start.py +1 -1
  19. cmdbox/app/features/cli/cmdbox_server_stop.py +1 -1
  20. cmdbox/app/features/cli/cmdbox_web_apikey_add.py +1 -1
  21. cmdbox/app/features/cli/cmdbox_web_apikey_del.py +1 -1
  22. cmdbox/app/features/cli/cmdbox_web_group_add.py +1 -1
  23. cmdbox/app/features/cli/cmdbox_web_group_del.py +1 -1
  24. cmdbox/app/features/cli/cmdbox_web_group_edit.py +1 -1
  25. cmdbox/app/features/cli/cmdbox_web_group_list.py +1 -1
  26. cmdbox/app/features/cli/cmdbox_web_start.py +1 -1
  27. cmdbox/app/features/cli/cmdbox_web_user_add.py +1 -1
  28. cmdbox/app/features/cli/cmdbox_web_user_del.py +1 -1
  29. cmdbox/app/features/cli/cmdbox_web_user_edit.py +1 -1
  30. cmdbox/app/features/cli/cmdbox_web_user_list.py +1 -1
  31. cmdbox/app/features/web/cmdbox_web_audit.py +87 -0
  32. cmdbox/app/features/web/cmdbox_web_audit_metrics.py +72 -0
  33. cmdbox/app/features/web/cmdbox_web_exec_cmd.py +10 -5
  34. cmdbox/app/features/web/cmdbox_web_user_data.py +58 -0
  35. cmdbox/app/options.py +49 -19
  36. cmdbox/app/server.py +15 -3
  37. cmdbox/app/web.py +7 -1
  38. cmdbox/extensions/features.yml +11 -8
  39. cmdbox/extensions/sample_project/sample/app/features/cli/sample_server_time.py +1 -1
  40. cmdbox/extensions/user_list.yml +5 -0
  41. cmdbox/licenses/LICENSE.Jinja2.3.1.4(BSD License).txt +28 -0
  42. cmdbox/licenses/LICENSE.Pygments.2.18.0(BSD License).txt +25 -0
  43. cmdbox/licenses/LICENSE.Sphinx.8.1.3(BSD License).txt +31 -0
  44. cmdbox/licenses/LICENSE.anyio.4.6.2.post1(MIT License).txt +20 -0
  45. cmdbox/licenses/LICENSE.argcomplete.3.5.1(Apache Software License).txt +177 -0
  46. cmdbox/licenses/LICENSE.argcomplete.3.6.2(Apache Software License).txt +177 -0
  47. cmdbox/licenses/LICENSE.babel.2.16.0(BSD License).txt +27 -0
  48. cmdbox/licenses/LICENSE.certifi.2024.8.30(Mozilla Public License 2.0 (MPL 2.0)).txt +20 -0
  49. cmdbox/licenses/LICENSE.charset-normalizer.3.4.0(MIT License).txt +21 -0
  50. cmdbox/licenses/LICENSE.click.8.1.7(BSD License).txt +28 -0
  51. cmdbox/licenses/LICENSE.cryptography.43.0.3(Apache Software License; BSD License).txt +3 -0
  52. cmdbox/licenses/LICENSE.fastapi.0.115.5(MIT License).txt +21 -0
  53. cmdbox/licenses/LICENSE.gevent.25.4.1(MIT).txt +25 -0
  54. cmdbox/licenses/LICENSE.greenlet.3.2.0(MIT AND Python-2.0).txt +30 -0
  55. cmdbox/licenses/LICENSE.importlib_metadata.8.5.0(Apache Software License).txt +202 -0
  56. cmdbox/licenses/LICENSE.keyring.25.5.0(MIT License).txt +17 -0
  57. cmdbox/licenses/LICENSE.more-itertools.10.5.0(MIT License).txt +19 -0
  58. cmdbox/licenses/LICENSE.nh3.0.2.18(MIT).txt +1 -0
  59. cmdbox/licenses/LICENSE.numpy.2.1.3(BSD License).txt +950 -0
  60. cmdbox/licenses/LICENSE.pillow.11.0.0(CMU License (MIT-CMU)).txt +1226 -0
  61. cmdbox/licenses/LICENSE.pillow.11.2.1(UNKNOWN).txt +1200 -0
  62. cmdbox/licenses/LICENSE.pkginfo.1.10.0(MIT License).txt +21 -0
  63. cmdbox/licenses/LICENSE.prettytable.3.12.0(BSD License).txt +30 -0
  64. cmdbox/licenses/LICENSE.prompt_toolkit.3.0.51(BSD License).txt +27 -0
  65. cmdbox/licenses/LICENSE.pydantic.2.10.2(MIT License).txt +21 -0
  66. cmdbox/licenses/LICENSE.pydantic.2.11.3(MIT License).txt +21 -0
  67. cmdbox/licenses/LICENSE.pydantic_core.2.27.1(MIT License).txt +21 -0
  68. cmdbox/licenses/LICENSE.pydantic_core.2.33.1(MIT License).txt +21 -0
  69. cmdbox/licenses/LICENSE.python-dotenv.1.0.1(BSD License).txt +27 -0
  70. cmdbox/licenses/LICENSE.python-multipart.0.0.17(Apache Software License).txt +14 -0
  71. cmdbox/licenses/LICENSE.redis.5.2.0(MIT License).txt +21 -0
  72. cmdbox/licenses/LICENSE.rich.13.9.4(MIT License).txt +19 -0
  73. cmdbox/licenses/LICENSE.six.1.16.0(MIT License).txt +18 -0
  74. cmdbox/licenses/LICENSE.sphinx-intl.2.3.0(BSD License).txt +25 -0
  75. cmdbox/licenses/LICENSE.starlette.0.41.3(BSD License).txt +27 -0
  76. cmdbox/licenses/LICENSE.starlette.0.46.2(BSD License).txt +27 -0
  77. cmdbox/licenses/LICENSE.tomli.2.1.0(MIT License).txt +21 -0
  78. cmdbox/licenses/LICENSE.twine.5.1.1(Apache Software License).txt +174 -0
  79. cmdbox/licenses/LICENSE.typing_extensions.4.12.2(Python Software Foundation License).txt +279 -0
  80. cmdbox/licenses/LICENSE.typing_extensions.4.13.2(UNKNOWN).txt +279 -0
  81. cmdbox/licenses/LICENSE.urllib3.2.2.3(MIT License).txt +21 -0
  82. cmdbox/licenses/LICENSE.urllib3.2.4.0(UNKNOWN).txt +21 -0
  83. cmdbox/licenses/LICENSE.uvicorn.0.32.1(BSD License).txt +27 -0
  84. cmdbox/licenses/LICENSE.uvicorn.0.34.1(BSD License).txt +27 -0
  85. cmdbox/licenses/LICENSE.watchfiles.1.0.0(MIT License).txt +21 -0
  86. cmdbox/licenses/LICENSE.watchfiles.1.0.5(MIT License).txt +21 -0
  87. cmdbox/licenses/LICENSE.websockets.14.1(BSD License).txt +24 -0
  88. cmdbox/licenses/LICENSE.zope.interface.7.1.1(Zope Public License).txt +44 -0
  89. cmdbox/licenses/files.txt +12 -13
  90. cmdbox/version.py +2 -2
  91. cmdbox/web/assets/apexcharts/apexcharts.css +679 -0
  92. cmdbox/web/assets/apexcharts/apexcharts.min.js +38 -0
  93. cmdbox/web/assets/cmdbox/audit.js +404 -0
  94. cmdbox/web/assets/cmdbox/color_mode.css +4 -0
  95. cmdbox/web/assets/cmdbox/common.js +397 -24
  96. cmdbox/web/assets/cmdbox/filer_modal.js +1 -1
  97. cmdbox/web/assets/cmdbox/list_cmd.js +7 -271
  98. cmdbox/web/assets/cmdbox/list_pipe.js +3 -3
  99. cmdbox/web/assets/cmdbox/users.js +17 -17
  100. cmdbox/web/assets/cmdbox/view_raw.js +1 -1
  101. cmdbox/web/assets/cmdbox/view_result.js +11 -13
  102. cmdbox/web/assets/filer/filer.js +2 -2
  103. cmdbox/web/assets_license_list.txt +4 -1
  104. cmdbox/web/audit.html +293 -0
  105. cmdbox/web/filer.html +21 -10
  106. cmdbox/web/gui.html +21 -52
  107. cmdbox/web/result.html +9 -2
  108. cmdbox/web/users.html +7 -3
  109. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/METADATA +13 -10
  110. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/RECORD +114 -59
  111. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/LICENSE +0 -0
  112. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/WHEEL +0 -0
  113. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/entry_points.txt +0 -0
  114. {cmdbox-0.5.2.dist-info → cmdbox-0.5.3.1.dist-info}/top_level.txt +0 -0
@@ -47,7 +47,7 @@ class ClientFileList(feature.OneshotResultEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="svpath", type=Options.T_STR, default="/", required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientFileMkdir(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="svpath", type=Options.T_STR, default="/", required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientFileMove(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="from_path", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientFileRemove(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="svpath", type=Options.T_STR, default="/", required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientFileRmdir(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="svpath", type=Options.T_STR, default="/", required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientFileUpload(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="svpath", type=Options.T_STR, default="/", required=True, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ClientServerInfo(feature.OneshotResultEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="retry_count", type=Options.T_INT, default=3, required=False, multi=False, hide=True, choice=None,
@@ -47,7 +47,7 @@ class GuiStart(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class ServerStart(feature.OneshotNotifyEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class ServerStop(feature.OneshotNotifyEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="retry_count", type=Options.T_INT, default=3, required=False, multi=False, hide=True, choice=None,
@@ -46,7 +46,7 @@ class WebApikeyAdd(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebApikeyDel(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebGroupAdd(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebGroupDel(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebGroupEdit(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebGroupList(feature.OneshotResultEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -47,7 +47,7 @@ class WebStart(feature.UnsupportEdgeFeature):
47
47
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
48
48
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
49
49
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
50
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
50
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
51
51
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
52
52
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
53
53
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebUserAdd(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebUserDel(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebUserEdit(feature.UnsupportEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -46,7 +46,7 @@ class WebUserList(feature.OneshotResultEdgeFeature):
46
46
  dict(opt="password", type=Options.T_STR, default=self.default_pass, required=True, multi=False, hide=True, choice=None, web="mask",
47
47
  discription_ja="Redisサーバーのアクセスパスワード(任意)を指定します。省略時は `password` を使用します。",
48
48
  discription_en="Specify the access password of the Redis server (optional). If omitted, `password` is used."),
49
- dict(opt="svname", type=Options.T_STR, default="server", required=True, multi=False, hide=True, choice=None, web="readonly",
49
+ dict(opt="svname", type=Options.T_STR, default=self.default_svname, required=True, multi=False, hide=True, choice=None, web="readonly",
50
50
  discription_ja="サーバーのサービス名を指定します。省略時は `server` を使用します。",
51
51
  discription_en="Specify the service name of the inference server. If omitted, `server` is used."),
52
52
  dict(opt="data", type=Options.T_FILE, default=common.HOME_DIR / f".{self.ver.__appid__}", required=False, multi=False, hide=False, choice=None,
@@ -0,0 +1,87 @@
1
+ from cmdbox.app import common, feature
2
+ from cmdbox.app.web import Web
3
+ from fastapi import FastAPI, Request, Response
4
+ from fastapi.responses import HTMLResponse
5
+ from typing import Dict, Any
6
+ import argparse
7
+ import time
8
+
9
+
10
+ class Audit(feature.WebFeature):
11
+
12
+ def route(self, web:Web, app:FastAPI) -> None:
13
+ """
14
+ webモードのルーティングを設定します
15
+
16
+ Args:
17
+ web (Web): Webオブジェクト
18
+ app (FastAPI): FastAPIオブジェクト
19
+ """
20
+ if web.audit_html is not None:
21
+ if not web.audit_html.is_file():
22
+ raise FileNotFoundError(f'audit_html is not found. ({web.audit_html})')
23
+ with open(web.audit_html, 'r', encoding='utf-8') as f:
24
+ web.audit_html_data = f.read()
25
+
26
+ @app.get('/audit', response_class=HTMLResponse)
27
+ @app.post('/audit', response_class=HTMLResponse)
28
+ async def audit(req:Request, res:Response):
29
+ signin = web.signin.check_signin(req, res)
30
+ if signin is not None:
31
+ return signin
32
+ res.headers['Access-Control-Allow-Origin'] = '*'
33
+ web.options.audit_exec(req, res, web)
34
+ return web.audit_html_data
35
+
36
+ @app.post('/audit/rawlog')
37
+ async def audit_rawlog(req:Request, res:Response):
38
+ signin = web.signin.check_signin(req, res)
39
+ if signin is not None:
40
+ return signin
41
+ if web.signin.get_data() is None:
42
+ return dict(error='signin_file_data is None.')
43
+ if not hasattr(web.options, 'audit_search') or web.options.audit_search is None:
44
+ return dict(warn='audit feature is disabled.')
45
+ opt = await req.json()
46
+ opt = {**opt, **web.options.audit_search_args.copy()}
47
+ opt['host'] = web.redis_host
48
+ opt['port'] = web.redis_port
49
+ opt['password'] = web.redis_password
50
+ opt['svname'] = web.svname
51
+ args = argparse.Namespace(**{k:common.chopdq(v) for k,v in opt.items()})
52
+ status, ret_main, _ = web.options.audit_search.apprun(web.logger, args, time.perf_counter(), [])
53
+ if status != 0:
54
+ return dict(error=ret_main)
55
+ return ret_main
56
+
57
+ @app.get('/audit/mode_cmd')
58
+ async def audit_mode_cmd(req:Request, res:Response):
59
+ signin = web.signin.check_signin(req, res)
60
+ if signin is not None:
61
+ return signin
62
+ if not hasattr(web.options, 'audit_search_args'):
63
+ return dict(warn='audit feature is disabled.')
64
+ return dict(success=web.options.audit_search_args)
65
+
66
+ def toolmenu(self, web:Web) -> Dict[str, Any]:
67
+ """
68
+ ツールメニューの情報を返します
69
+
70
+ Args:
71
+ web (Web): Webオブジェクト
72
+
73
+ Returns:
74
+ Dict[str, Any]: ツールメニュー情報
75
+
76
+ Sample:
77
+ {
78
+ 'filer': {
79
+ 'html': 'Filer',
80
+ 'href': 'filer',
81
+ 'target': '_blank',
82
+ 'css_class': 'dropdown-item'
83
+ 'onclick': 'alert("filer")'
84
+ }
85
+ }
86
+ """
87
+ return dict(audit=dict(html='Audit', href='audit', target='_blank', css_class='dropdown-item'))
@@ -0,0 +1,72 @@
1
+ from cmdbox.app import common, feature
2
+ from cmdbox.app.web import Web
3
+ from fastapi import FastAPI, Request, Response, HTTPException
4
+ from typing import Dict, Any
5
+ import json
6
+
7
+
8
+ class AuditMetrics(feature.WebFeature):
9
+ def route(self, web:Web, app:FastAPI) -> None:
10
+ """
11
+ webモードのルーティングを設定します
12
+
13
+ Args:
14
+ web (Web): Webオブジェクト
15
+ app (FastAPI): FastAPIオブジェクト
16
+ """
17
+ @app.post('/audit/metrics/save')
18
+ async def save_metrics(req:Request, res:Response):
19
+ signin = web.signin.check_signin(req, res)
20
+ if signin is not None:
21
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
22
+ form = await req.form()
23
+ title = form.get('title')
24
+ opt = json.loads(form.get('opt'))
25
+ if common.check_fname(title):
26
+ return dict(warn=f'The title contains invalid characters."{title}"')
27
+ opt_path = web.audit_path / f"metrics-{title}.json"
28
+ web.logger.info(f"save_metrics: opt_path={opt_path}, opt={opt}")
29
+ common.saveopt(opt, opt_path, True)
30
+ ret = dict(success=f'Metrics "{title}" saved in "{opt_path}".')
31
+ web.options.audit_exec(req, res, web, title=title)
32
+ return ret
33
+
34
+ @app.post('/audit/metrics/load')
35
+ async def load_metrics(req:Request, res:Response):
36
+ signin = web.signin.check_signin(req, res)
37
+ if signin is not None:
38
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
39
+ form = await req.form()
40
+ title = form.get('title')
41
+ opt_path = web.audit_path / f"metrics-{title}.json"
42
+ if not opt_path.is_file():
43
+ return dict(warn=f'The metrics file is not found."{opt_path}"')
44
+ with open(opt_path, 'r', encoding='utf-8') as f:
45
+ opt = json.load(f)
46
+ return dict(success=opt)
47
+
48
+ @app.post('/audit/metrics/delete')
49
+ async def delete_metrics(req:Request, res:Response):
50
+ signin = web.signin.check_signin(req, res)
51
+ if signin is not None:
52
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
53
+ form = await req.form()
54
+ title = form.get('title')
55
+ opt_path = web.audit_path / f"metrics-{title}.json"
56
+ if not opt_path.is_file():
57
+ return dict(warn=f'The metrics file is not found."{opt_path}"')
58
+ opt_path.unlink()
59
+ return dict(success=f'Metrics "{title}" deleted.')
60
+
61
+ @app.post('/audit/metrics/list')
62
+ async def list_metrics(req:Request, res:Response):
63
+ signin = web.signin.check_signin(req, res)
64
+ if signin is not None:
65
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
66
+ files = web.audit_path.glob('metrics-*.json')
67
+ ret = []
68
+ for f in files:
69
+ with open(f, 'r', encoding='utf-8') as f:
70
+ opt = json.load(f)
71
+ ret.append(opt)
72
+ return dict(success=ret)
@@ -1,6 +1,6 @@
1
1
  from cmdbox.app import app, client, common, options, server, web as _web
2
2
  from cmdbox.app.commons import convert, loghandler
3
- from cmdbox.app.features.cli import audit_base
3
+ from cmdbox.app.features.cli import cmdbox_audit_search, cmdbox_audit_write
4
4
  from cmdbox.app.features.web import cmdbox_web_load_cmd
5
5
  from cmdbox.app.web import Web
6
6
  from fastapi import FastAPI, Request, Response, HTTPException
@@ -96,7 +96,6 @@ class ExecCmd(cmdbox_web_load_cmd.LoadCmd):
96
96
  return True, output
97
97
  return False, None
98
98
 
99
- @options.Options.audit()
100
99
  def exec_cmd(self, req:Request, res:Response, web:Web,
101
100
  title:str, opt:Dict[str, Any], nothread:bool=False, appcls=None) -> List[Dict[str, Any]]:
102
101
  """
@@ -113,6 +112,10 @@ class ExecCmd(cmdbox_web_load_cmd.LoadCmd):
113
112
  Returns:
114
113
  list: コマンド実行結果
115
114
  """
115
+ tags = []
116
+ if 'tag' in opt and isinstance(opt['tag'], list):
117
+ tags = [t for t in opt['tag'] if t is not None and t != '']
118
+ web.options.audit_exec(req, res, web, tags=tags, title=title)
116
119
  appcls = self.appcls if appcls is None else appcls
117
120
  appcls = app.CmdBoxApp if appcls is None else appcls
118
121
  web.container['cmdbox_app'] = ap = appcls.getInstance(appcls=appcls, ver=self.ver)
@@ -133,8 +136,10 @@ class ExecCmd(cmdbox_web_load_cmd.LoadCmd):
133
136
  found = True
134
137
  if not found or o not in loaded: continue
135
138
  opt[o] = loaded[o]
136
- if isinstance(feat, audit_base.AuditBase) and o in _options.audit_args:
137
- opt[o] = _options.audit_args[o]
139
+ if isinstance(feat, cmdbox_audit_write.AuditWrite) and hasattr(_options, 'audit_write_args') and o in _options.audit_write_args:
140
+ opt[o] = _options.audit_write_args[o]
141
+ elif isinstance(feat, cmdbox_audit_search.AuditSearch) and hasattr(_options, 'audit_search_args') and o in _options.audit_search_args:
142
+ opt[o] = _options.audit_search_args[o]
138
143
  except:
139
144
  pass
140
145
  if 'host' in opt: opt['host'] = web.redis_host
@@ -175,7 +180,7 @@ class ExecCmd(cmdbox_web_load_cmd.LoadCmd):
175
180
  logsize = 1024
176
181
  try:
177
182
  old_stdout.write(loghandler.colorize_msg(f'EXEC: {opt_list}\n'[:logsize]))
178
- status, ret_main, obj = cmdbox_app.main(args_list=opt_list, file_dict=file_dict, webcall=True)
183
+ status, ret_main, obj = cmdbox_app.main(args_list=[common.chopdq(o) for o in opt_list], file_dict=file_dict, webcall=True)
179
184
  if isinstance(obj, server.Server):
180
185
  cmdbox_app.sv = obj
181
186
  elif isinstance(obj, client.Client):
@@ -0,0 +1,58 @@
1
+ from cmdbox.app import common, feature
2
+ from cmdbox.app.web import Web
3
+ from fastapi import FastAPI, Request, Response, HTTPException
4
+ from typing import Dict, Any
5
+
6
+
7
+ class UserData(feature.WebFeature):
8
+ def route(self, web:Web, app:FastAPI) -> None:
9
+ """
10
+ webモードのルーティングを設定します
11
+
12
+ Args:
13
+ web (Web): Webオブジェクト
14
+ app (FastAPI): FastAPIオブジェクト
15
+ """
16
+ @app.post('/gui/user_data/load')
17
+ async def load(req:Request, res:Response):
18
+ signin = web.signin.check_signin(req, res)
19
+ if signin is not None:
20
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
21
+ if 'signin' not in req.session or req.session['signin'] is None:
22
+ return dict(warn='Please sign in.')
23
+ form = await req.form()
24
+ categoly = form.get('categoly')
25
+ key = form.get('key')
26
+ sess = req.session['signin']
27
+ ret = web.user_data(req, sess['uid'], sess['name'], categoly, key)
28
+ return dict(success=ret)
29
+
30
+ @app.post('/gui/user_data/save')
31
+ async def save(req:Request, res:Response):
32
+ signin = web.signin.check_signin(req, res)
33
+ if signin is not None:
34
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
35
+ if 'signin' not in req.session or req.session['signin'] is None:
36
+ return dict(warn='Please sign in.')
37
+ form = await req.form()
38
+ categoly = form.get('categoly')
39
+ key = form.get('key')
40
+ val = form.get('val')
41
+ sess = req.session['signin']
42
+ web.user_data(req, sess['uid'], sess['name'], categoly, key, val)
43
+ return dict(success=f'user_data "{categoly}:{key}:val" saved.')
44
+
45
+ @app.post('/gui/user_data/delete')
46
+ async def delete(req:Request, res:Response):
47
+ signin = web.signin.check_signin(req, res)
48
+ if signin is not None:
49
+ raise HTTPException(status_code=401, detail=self.DEFAULT_401_MESSAGE)
50
+ if 'signin' not in req.session or req.session['signin'] is None:
51
+ return dict(warn='Please sign in.')
52
+ form = await req.form()
53
+ categoly = form.get('categoly')
54
+ key = form.get('key')
55
+ val = form.get('val')
56
+ sess = req.session['signin']
57
+ web.user_data(req, sess['uid'], sess['name'], categoly, key, delkey=True)
58
+ return dict(success=f'user_data "{categoly}:{key}:val" deleted.')