zrb 1.0.0a16__py3-none-any.whl → 1.0.0a20__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.
Files changed (196) hide show
  1. zrb/__init__.py +5 -0
  2. zrb/__main__.py +3 -0
  3. zrb/builtin/__init__.py +2 -2
  4. zrb/builtin/git.py +10 -2
  5. zrb/builtin/git_subtree.py +4 -0
  6. zrb/builtin/llm/tool/rag.py +2 -2
  7. zrb/builtin/project/add/fastapp/fastapp_input.py +16 -0
  8. zrb/builtin/project/add/fastapp/fastapp_task.py +78 -0
  9. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.flake8 +3 -0
  10. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/create_column_task.py +14 -0
  11. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +128 -0
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +213 -0
  13. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +27 -0
  14. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/my_entity_usecase.py +9 -10
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/factory.py +13 -0
  16. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_db_repository.py +14 -9
  17. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_repository.py +6 -7
  18. zrb/builtin/project/add/{fastapp_template/_zrb/entity/schema.template.py → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py} +8 -0
  19. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +17 -0
  20. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/input.py +1 -4
  21. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +85 -0
  22. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +154 -0
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/any_client.py +7 -0
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +6 -0
  25. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +6 -0
  26. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +9 -0
  27. zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/env.py +2 -4
  28. zrb/builtin/project/add/{fastapp_template/module/auth → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/script.py.mako +1 -0
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +33 -0
  30. zrb/builtin/project/add/{fastapp_template/_zrb/main.py → fastapp/fastapp_template/my_app_name/_zrb/task.py} +12 -14
  31. zrb/builtin/project/add/{fastapp_template/_zrb/helper.py → fastapp/fastapp_template/my_app_name/_zrb/util.py} +1 -1
  32. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/venv_task.py +1 -1
  33. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/app.py +2 -2
  34. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/base_db_repository.py +1 -1
  35. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/base_usecase.py +19 -6
  36. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/db_engine.py +1 -1
  37. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/config.py +1 -0
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +7 -0
  39. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/migrate.py +3 -0
  40. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/client/any_client.py +10 -4
  41. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +7 -0
  42. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +6 -0
  43. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +9 -0
  44. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration/env.py +2 -4
  45. zrb/builtin/project/add/{fastapp_template/module/gateway → fastapp/fastapp_template/my_app_name/module/auth}/migration/script.py.mako +1 -0
  46. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration_metadata.py +1 -1
  47. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +37 -0
  48. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/repository/user_db_repository.py +13 -7
  49. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +42 -0
  50. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +13 -0
  51. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/user_usecase.py +13 -12
  52. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +6 -0
  53. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration/env.py +2 -4
  54. zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/module/gateway}/migration/script.py.mako +1 -0
  55. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +37 -0
  56. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +44 -0
  57. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/requirements.txt +1 -1
  58. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/permission.py +8 -0
  59. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/role.py +8 -0
  60. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/user.py +8 -0
  61. zrb/builtin/project/add/fastapp/fastapp_util.py +46 -0
  62. zrb/builtin/project/create/{create.py → project_task.py} +1 -1
  63. zrb/builtin/python.py +4 -1
  64. zrb/builtin/setup/asdf/asdf_helper.py +4 -8
  65. zrb/builtin/setup/tmux/tmux.py +7 -12
  66. zrb/builtin/todo.py +42 -26
  67. zrb/callback/callback.py +0 -1
  68. zrb/cmd/cmd_val.py +2 -2
  69. zrb/config.py +18 -0
  70. zrb/content_transformer/content_transformer.py +8 -7
  71. zrb/context/any_context.py +6 -6
  72. zrb/group/group.py +0 -1
  73. zrb/input/any_input.py +4 -0
  74. zrb/input/base_input.py +17 -5
  75. zrb/input/bool_input.py +1 -1
  76. zrb/input/float_input.py +2 -2
  77. zrb/input/int_input.py +1 -1
  78. zrb/input/option_input.py +2 -2
  79. zrb/input/password_input.py +2 -2
  80. zrb/input/text_input.py +6 -6
  81. zrb/runner/cli.py +9 -35
  82. zrb/runner/common_util.py +31 -0
  83. zrb/runner/web_app.py +169 -46
  84. zrb/runner/web_config.py +288 -0
  85. zrb/runner/web_controller/error_page/controller.py +27 -0
  86. zrb/runner/web_controller/error_page/view.html +33 -0
  87. zrb/runner/web_controller/group_info_page/controller.py +40 -0
  88. zrb/runner/web_controller/group_info_page/view.html +36 -0
  89. zrb/runner/web_controller/home_page/controller.py +14 -57
  90. zrb/runner/web_controller/home_page/view.html +29 -20
  91. zrb/runner/web_controller/login_page/controller.py +25 -0
  92. zrb/runner/web_controller/login_page/view.html +50 -0
  93. zrb/runner/web_controller/logout_page/controller.py +26 -0
  94. zrb/runner/web_controller/logout_page/view.html +40 -0
  95. zrb/runner/web_controller/{task_ui → session_page}/controller.py +36 -34
  96. zrb/runner/web_controller/{task_ui → session_page}/partial/input.html +1 -1
  97. zrb/runner/web_controller/session_page/view.html +91 -0
  98. zrb/runner/web_controller/static/common.css +11 -0
  99. zrb/runner/web_controller/static/login/event.js +33 -0
  100. zrb/runner/web_controller/static/logout/event.js +20 -0
  101. zrb/runner/web_controller/static/pico.min.css +1 -1
  102. zrb/runner/web_controller/static/session/common-util.js +63 -0
  103. zrb/runner/web_controller/static/session/current-session.js +164 -0
  104. zrb/runner/web_controller/static/session/event.js +120 -0
  105. zrb/runner/web_controller/static/session/past-session.js +138 -0
  106. zrb/runner/web_util.py +53 -0
  107. zrb/session_state_logger/any_session_state_logger.py +0 -1
  108. zrb/session_state_logger/file_session_state_logger.py +4 -8
  109. zrb/task/base_trigger.py +0 -1
  110. zrb/task/cmd_task.py +1 -1
  111. zrb/task/llm_task.py +3 -6
  112. zrb/task/make_task.py +0 -1
  113. zrb/task/scaffolder.py +18 -4
  114. zrb/task/scheduler.py +0 -1
  115. zrb/util/cmd/command.py +0 -1
  116. zrb/util/codemod/{add_code_to_class.py → append_code_to_class.py} +4 -4
  117. zrb/util/codemod/{add_code_to_function.py → append_code_to_function.py} +5 -3
  118. zrb/util/codemod/{add_code_to_method.py → append_code_to_method.py} +3 -3
  119. zrb/util/codemod/{add_key_to_dict.py → append_key_to_dict.py} +1 -1
  120. zrb/util/codemod/{add_param_to_function_call.py → append_param_to_function_call.py} +1 -1
  121. zrb/util/codemod/{add_code_to_module.py → prepend_code_to_module.py} +2 -2
  122. zrb/util/codemod/{add_parent_to_class.py → prepend_parent_to_class.py} +1 -1
  123. zrb/util/codemod/{add_property_to_class.py → prepend_property_to_class.py} +1 -1
  124. zrb/util/file.py +18 -0
  125. zrb/util/git_subtree.py +3 -4
  126. zrb/util/todo.py +105 -24
  127. zrb/xcom/xcom.py +0 -1
  128. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/METADATA +3 -2
  129. zrb-1.0.0a20.dist-info/RECORD +243 -0
  130. zrb/builtin/project/add/fastapp.py +0 -87
  131. zrb/builtin/project/add/fastapp_template/_zrb/column/create_column_task.py +0 -11
  132. zrb/builtin/project/add/fastapp_template/_zrb/entity/create_entity_task.py +0 -196
  133. zrb/builtin/project/add/fastapp_template/_zrb/entity/module_template/service/my_entity/repository/factory.py +0 -13
  134. zrb/builtin/project/add/fastapp_template/_zrb/module/create_module_task.py +0 -136
  135. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/any_client.py +0 -27
  136. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/api_client.py +0 -6
  137. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/direct_client.py +0 -6
  138. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/factory.py +0 -9
  139. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/route.py +0 -19
  140. zrb/builtin/project/add/fastapp_template/main.py +0 -7
  141. zrb/builtin/project/add/fastapp_template/migrate.py +0 -3
  142. zrb/builtin/project/add/fastapp_template/module/auth/client/api_client.py +0 -7
  143. zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +0 -6
  144. zrb/builtin/project/add/fastapp_template/module/auth/client/factory.py +0 -9
  145. zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
  146. zrb/builtin/project/add/fastapp_template/module/auth/route.py +0 -22
  147. zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/factory.py +0 -13
  148. zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/user_repository.py +0 -34
  149. zrb/builtin/project/add/fastapp_template/module/gateway/route.py +0 -27
  150. zrb/runner/web_controller/group_info_ui/controller.py +0 -91
  151. zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -2
  152. zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -1
  153. zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -2
  154. zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -1
  155. zrb/runner/web_controller/group_info_ui/view.html +0 -31
  156. zrb/runner/web_controller/home_page/partial/group_info.html +0 -2
  157. zrb/runner/web_controller/home_page/partial/group_li.html +0 -1
  158. zrb/runner/web_controller/home_page/partial/task_info.html +0 -2
  159. zrb/runner/web_controller/home_page/partial/task_li.html +0 -1
  160. zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
  161. zrb/runner/web_controller/task_ui/partial/main.js +0 -195
  162. zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
  163. zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
  164. zrb/runner/web_controller/task_ui/view.html +0 -87
  165. zrb-1.0.0a16.dist-info/RECORD +0 -231
  166. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/.gitignore +0 -0
  167. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/README.md +0 -0
  168. /zrb/builtin/project/add/{__init__.py → fastapp/fastapp_template/my_app_name/__init__.py} +0 -0
  169. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/config.py +0 -0
  170. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/group.py +0 -0
  171. /zrb/builtin/project/add/{fastapp_template/__init__.py → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py} +0 -0
  172. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/alembic.ini +0 -0
  173. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/README +0 -0
  174. /zrb/builtin/project/add/{fastapp_template/module/gateway → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/versions/.gitkeep +0 -0
  175. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration_metadata.py +0 -0
  176. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/service/__init__.py +0 -0
  177. /zrb/builtin/project/add/{fastapp_template/_zrb/module/run_module.template.py → fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py} +0 -0
  178. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/__init__.py +0 -0
  179. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/error.py +0 -0
  180. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/schema.py +0 -0
  181. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/__init__.py +0 -0
  182. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/alembic.ini +0 -0
  183. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration/README +0 -0
  184. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/module/auth}/migration/versions/3093c7336477_add_user_table.py +0 -0
  185. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/__init__.py +0 -0
  186. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/__init__.py +0 -0
  187. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/alembic.ini +0 -0
  188. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration/README +0 -0
  189. /zrb/builtin/project/add/{fastapp_template/module/auth/service/user/repository/__init__.py → fastapp/fastapp_template/my_app_name/module/gateway/migration/versions/.gitkeep} +0 -0
  190. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration_metadata.py +0 -0
  191. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/__init__.py +0 -0
  192. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/template.env +0 -0
  193. /zrb/runner/web_controller/{group_info_ui → group_info_page}/__init__.py +0 -0
  194. /zrb/runner/web_controller/{task_ui → session_page}/__init__.py +0 -0
  195. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/WHEEL +0 -0
  196. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/entry_points.txt +0 -0
@@ -1,91 +0,0 @@
1
- import os
2
-
3
- from zrb.group.any_group import AnyGroup
4
- from zrb.util.group import get_non_empty_subgroups, get_subtasks
5
- from zrb.util.string.format import fstring_format
6
-
7
- _DIR = os.path.dirname(__file__)
8
-
9
- with open(os.path.join(_DIR, "view.html"), "r") as f:
10
- _VIEW_TEMPLATE = f.read()
11
-
12
- with open(os.path.join(_DIR, "partial", "group_info.html")) as f:
13
- _GROUP_INFO_TEMPLATE = f.read()
14
-
15
- with open(os.path.join(_DIR, "partial", "group_li.html")) as f:
16
- _GROUP_LI_TEMPLATE = f.read()
17
-
18
- with open(os.path.join(_DIR, "partial", "task_info.html")) as f:
19
- _TASK_INFO_TEMPLATE = f.read()
20
-
21
- with open(os.path.join(_DIR, "partial", "task_li.html")) as f:
22
- _TASK_LI_TEMPLATE = f.read()
23
-
24
-
25
- def handle_group_info_ui(root_group: AnyGroup, group: AnyGroup, url: str):
26
- from fastapi.responses import HTMLResponse
27
-
28
- url_parts = url.split("/")
29
- parent_url_parts = url_parts[:-2] + [""]
30
- parent_url = "/".join(parent_url_parts)
31
- subgroups = get_non_empty_subgroups(group, web_only=True)
32
- group_info = (
33
- ""
34
- if len(subgroups) == 0
35
- else fstring_format(
36
- _GROUP_INFO_TEMPLATE,
37
- {
38
- "group_li": "\n".join(
39
- [
40
- fstring_format(
41
- _GROUP_LI_TEMPLATE,
42
- {
43
- "caption": name,
44
- "url": url,
45
- "description": group.description,
46
- },
47
- )
48
- for name, group in subgroups.items()
49
- ]
50
- )
51
- },
52
- )
53
- )
54
- subtasks = get_subtasks(group, web_only=True)
55
- task_info = (
56
- ""
57
- if len(subtasks) == 0
58
- else fstring_format(
59
- _TASK_INFO_TEMPLATE,
60
- {
61
- "task_li": "\n".join(
62
- [
63
- fstring_format(
64
- _TASK_LI_TEMPLATE,
65
- {
66
- "caption": name,
67
- "url": url,
68
- "description": task.description,
69
- },
70
- )
71
- for name, task in subtasks.items()
72
- ]
73
- )
74
- },
75
- )
76
- )
77
- return HTMLResponse(
78
- fstring_format(
79
- _VIEW_TEMPLATE,
80
- {
81
- "group_info": group_info,
82
- "task_info": task_info,
83
- "name": group.name,
84
- "description": group.description,
85
- "root_name": root_group.name,
86
- "root_description": root_group.description,
87
- "url": url,
88
- "parent_url": parent_url,
89
- },
90
- )
91
- )
@@ -1,2 +0,0 @@
1
- <h5>Groups</h5>
2
- <ul>{group_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="{url}{caption}">{caption}</a> {description}</li>
@@ -1,2 +0,0 @@
1
- <h5>Tasks</h5>
2
- <ul>{task_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="{url}{caption}">{caption}</a> {description}</li>
@@ -1,31 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="color-scheme" content="light dark">
7
- <link rel="stylesheet" href="/static/pico.min.css">
8
- <link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
9
- <title>Zrb</title>
10
- </head>
11
- <body>
12
- <header class="container">
13
- <hgroup>
14
- <h1>{root_name}</h1>
15
- <p>{root_description}</p>
16
- <nav>
17
- <ul>
18
- <li><a href="/">🏠 Home</a></li>
19
- <li><a href="{parent_url}">🔙 Parent</a></li>
20
- </ul>
21
- </nav>
22
- </hgroup>
23
- </header>
24
- <main class="container">
25
- <h3>{name}</h3>
26
- <p>{description}</p>
27
- {group_info}
28
- {task_info}
29
- </main>
30
- </body>
31
- </html>
@@ -1,2 +0,0 @@
1
- <h5>Groups</h5>
2
- <ul>{group_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="/ui/{caption}">{caption}</a> {description}</li>
@@ -1,2 +0,0 @@
1
- <h5>Tasks</h5>
2
- <ul>{task_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="/ui/{caption}">{caption}</a> {description}</li>
@@ -1,37 +0,0 @@
1
- function getFinalColor(finalStatus) {
2
- switch(finalStatus) {
3
- case "started":
4
- return "#3498db";
5
- case "ready":
6
- return "#f39c12";
7
- case "completed":
8
- return "#2ecc71";
9
- case "skipped":
10
- return "#95a5a6";
11
- case "failed":
12
- return "#e74c3c";
13
- case "permanently-failed":
14
- return "#c0392b";
15
- case "terminated":
16
- return "#ffffff";
17
- default:
18
- return "#ffffff";
19
- }
20
- }
21
-
22
- function getFinalTaskStatus(taskStatus) {
23
- if (taskStatus.is_completed) {
24
- return "completed";
25
- }
26
- if (taskStatus.is_terminated) {
27
- return "terminated"
28
- }
29
- if (taskStatus.is_permanently_failed) {
30
- return "permanently-failed"
31
- }
32
- const histories = taskStatus.history;
33
- if (histories.length > 0) {
34
- return histories[histories.length - 1].status;
35
- }
36
- return "";
37
- }
@@ -1,195 +0,0 @@
1
- window.addEventListener("load", async function () {
2
- // Get current session
3
- if (SESSION_NAME != "") {
4
- pollSession();
5
- }
6
- // set maxStartDate to today
7
- const tomorrow = new Date();
8
- tomorrow.setDate(tomorrow.getDate() + 1); // Move to the next day
9
- tomorrow.setHours(0, 0, 0, 0);
10
- const formattedTomorrow = toLocalDateInputValue(tomorrow);
11
- const maxStartAtInput = document.getElementById("max-start-at-input");
12
- maxStartAtInput.value = formattedTomorrow;
13
- // set minStartDate to yesterday
14
- const today = new Date();
15
- today.setHours(0, 0, 0, 0); // Set time to 00:00:00
16
- const formattedToday = toLocalDateInputValue(today);
17
- const minStartAtInput = document.getElementById("min-start-at-input");
18
- minStartAtInput.value = formattedToday;
19
- // Update session
20
- pollExistingSessions(PAGE);
21
- });
22
-
23
- async function pollExistingSessions() {
24
- while (true) {
25
- await getExistingSessions(PAGE);
26
- await delay(5000);
27
- }
28
- }
29
-
30
- async function getExistingSessions(page) {
31
- PAGE=page
32
- const minStartAtInput = document.getElementById("min-start-at-input");
33
- const minStartAt = formatDate(minStartAtInput.value);
34
- const maxStartAtInput = document.getElementById("max-start-at-input");
35
- const maxStartAt = formatDate(maxStartAtInput.value);
36
- console.log(minStartAt);
37
- const queryString = new URLSearchParams({
38
- page: page,
39
- from: minStartAt,
40
- to: maxStartAt,
41
- }).toString();
42
- try {
43
- // Send the AJAX request
44
- const response = await fetch(`${API_URL}list?${queryString}`, {
45
- method: "GET",
46
- headers: {
47
- "Content-Type": "application/json"
48
- },
49
- });
50
- const {total, data} = await response.json();
51
- showExistingSession(page, total, data);
52
- console.log("Success:", data);
53
- } catch (error) {
54
- console.error("Error:", error);
55
- }
56
- }
57
-
58
-
59
- function toLocalDateInputValue(date) {
60
- const year = date.getFullYear();
61
- const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
62
- const day = String(date.getDate()).padStart(2, '0');
63
- const hours = String(date.getHours()).padStart(2, '0');
64
- const minutes = String(date.getMinutes()).padStart(2, '0');
65
- return `${year}-${month}-${day}T${hours}:${minutes}`;
66
- }
67
-
68
-
69
- function formatDate(dateString) {
70
- const date = new Date(dateString);
71
- const year = date.getFullYear();
72
- const month = String(date.getMonth() + 1).padStart(2, '0');
73
- const day = String(date.getDate()).padStart(2, '0');
74
- const hours = String(date.getHours()).padStart(2, '0');
75
- const minutes = String(date.getMinutes()).padStart(2, '0');
76
- const seconds = String(date.getSeconds()).padStart(2, '0');
77
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
78
- }
79
-
80
- function openDialog(event) {
81
- event.preventDefault();
82
- const dialog = document.getElementById("session-history-dialog")
83
- dialog.showModal();
84
- }
85
-
86
-
87
- function closeDialog(event) {
88
- event.preventDefault();
89
- const dialog = document.getElementById("session-history-dialog")
90
- dialog.close();
91
- }
92
-
93
-
94
- async function submitForm(event) {
95
- // Prevent the form from submitting the traditional way
96
- event.preventDefault();
97
- // Select the form
98
- const form = document.getElementById("submit-task-form");
99
- // Initialize an empty object to hold form data
100
- const formData = {};
101
- // Iterate through each input in the form
102
- Array.from(form.elements).forEach(element => {
103
- // Only include inputs with a name attribute and ignore buttons
104
- if (element.name && (element.type !== "button" && element.type !== "submit")) {
105
- formData[element.name] = element.value;
106
- }
107
- });
108
- // Convert formData to JSON
109
- const jsonData = JSON.stringify(formData);
110
- try {
111
- // Send the AJAX request
112
- const response = await fetch(API_URL, {
113
- method: "POST",
114
- headers: {
115
- "Content-Type": "application/json"
116
- },
117
- body: jsonData
118
- });
119
- const data = await response.json();
120
- console.log("Success:", data);
121
- SESSION_NAME = data.session_name;
122
- history.pushState(null, "", `${CURRENT_URL}${SESSION_NAME}`);
123
- getExistingSessions(0);
124
- await pollSession();
125
- } catch (error) {
126
- console.error("Error:", error);
127
- }
128
- }
129
-
130
-
131
- async function pollSession() {
132
- const resultTextarea = document.getElementById("result-textarea");
133
- const logTextarea = document.getElementById("log-textarea");
134
- const submitTaskForm = document.getElementById("submit-task-form");
135
- let isFinished = false;
136
- let errorCount = 0;
137
- while (!isFinished) {
138
- try {
139
- const data = await getSession();
140
- // update inputs
141
- const dataInputs = data.input;
142
- for (const inputName in dataInputs) {
143
- const inputValue = dataInputs[inputName];
144
- const input = submitTaskForm.querySelector(`[name="${inputName}"]`);
145
- input.value = inputValue;
146
- }
147
- resultLineCount = data.final_result.split("\n").length;
148
- resultTextarea.rows = resultLineCount <= 5 ? resultLineCount : 5;
149
- // update text areas
150
- resultTextarea.value = data.final_result;
151
- logTextarea.value = data.log.join("\n");
152
- logTextarea.scrollTop = logTextarea.scrollHeight;
153
- // visualize history
154
- visualizeHistory(data.task_status, data.finished);
155
- if (data.finished) {
156
- isFinished = true;
157
- } else {
158
- await delay(200);
159
- }
160
- } catch (error) {
161
- console.error("Error fetching session status:", error);
162
- errorCount++;
163
- if (errorCount > 5) {
164
- console.error("Exceeding maximum error count, quitting");
165
- return;
166
- }
167
- continue;
168
- }
169
- }
170
- }
171
-
172
-
173
- async function getSession() {
174
- try {
175
- const response = await fetch(`${API_URL}${SESSION_NAME}`, {
176
- method: "GET",
177
- headers: {
178
- "Content-Type": "application/json"
179
- },
180
- });
181
- return await response.json();
182
- } catch (error) {
183
- console.error("Error:", error);
184
- }
185
- }
186
-
187
-
188
- function rstripSlash(str) {
189
- return str.replace(/\/+$/, ""); // Removes one or more trailing slashes
190
- }
191
-
192
-
193
- function delay(ms) {
194
- return new Promise(resolve => setTimeout(resolve, ms));
195
- }
@@ -1,97 +0,0 @@
1
- function showExistingSession(page, total, data) {
2
- const ul = document.getElementById("session-history-ul");
3
- ul.innerHTML = ''; // Clear existing content
4
- data.forEach(item => {
5
- const taskStatus = item.task_status[item.main_task_name];
6
- const finalStatus = getFinalTaskStatus(taskStatus);
7
- const finalColor = getFinalColor(finalStatus);
8
- const taskHistories = taskStatus.history;
9
- const taskStartTime = taskHistories.length > 0 ? taskHistories[0].time : ""
10
- const li = document.createElement('li');
11
- const a = document.createElement('a');
12
- const dateSpan = document.createElement('span');
13
- const statusSpan = document.createElement('span');
14
- a.textContent = item.name;
15
- a.target = '_blank';
16
- a.href = `${UI_URL}${item.name}`;
17
- li.appendChild(a);
18
- statusSpan.style.marginLeft = "10px";
19
- statusSpan.style.display = 'inline-block';
20
- statusSpan.style.width = '15px';
21
- statusSpan.style.height = '15px';
22
- statusSpan.style.borderRadius = '50%';
23
- statusSpan.style.border = '2px solid black';
24
- statusSpan.style.backgroundColor = finalColor;
25
- li.appendChild(statusSpan);
26
- dateSpan.style.marginLeft = "10px";
27
- dateSpan.textContent = taskStartTime;
28
- li.appendChild(dateSpan);
29
- ul.appendChild(li);
30
- });
31
- const paginationUl = document.getElementById("session-history-pagination-ul");
32
- paginationUl.innerHTML = ''; // Clear previous pagination
33
-
34
- const totalPages = Math.ceil(total / 10); // Calculate total pages based on page size
35
- const maxPagesToShow = 5; // Number of pages to display around the current page
36
- const halfMaxPages = Math.floor(maxPagesToShow / 2);
37
-
38
- // Add first page and previous controls
39
- if (page > 0) {
40
- paginationUl.appendChild(createPageLink("⟪", 0)); // Go to first page
41
- paginationUl.appendChild(createPageLink("⟨", page - 1)); // Go to previous page
42
- }
43
-
44
- let startPage = Math.max(0, page - halfMaxPages);
45
- let endPage = Math.min(totalPages - 1, page + halfMaxPages);
46
-
47
- if (page <= halfMaxPages) {
48
- endPage = Math.min(totalPages - 1, maxPagesToShow - 1);
49
- } else if (page + halfMaxPages >= totalPages) {
50
- startPage = Math.max(0, totalPages - maxPagesToShow);
51
- }
52
-
53
- if (startPage > 1) {
54
- paginationUl.appendChild(createEllipsis());
55
- }
56
-
57
- // Add page links within the calculated range
58
- for (let i = startPage; i <= endPage; i++) {
59
- if (i === page) {
60
- const pageLi = document.createElement('li');
61
- pageLi.textContent = i + 1;
62
- paginationUl.append(pageLi)
63
- } else {
64
- paginationUl.appendChild(createPageLink(i + 1, i))
65
- }
66
- }
67
-
68
- // Add ellipsis after the end page if needed
69
- if (endPage < totalPages - 2) {
70
- paginationUl.appendChild(createEllipsis());
71
- }
72
-
73
- // Add next and last page controls
74
- if (page < totalPages - 1) {
75
- paginationUl.appendChild(createPageLink("⟩", page + 1)); // Go to next page
76
- paginationUl.appendChild(createPageLink("⟫", totalPages - 1)); // Go to last page
77
- }
78
- }
79
-
80
- function createPageLink(text, page) {
81
- const li = document.createElement('li');
82
- const link = document.createElement('a');
83
- link.textContent = text;
84
- link.href = '#';
85
- link.onclick = (e) => {
86
- e.preventDefault();
87
- getExistingSessions(page);
88
- };
89
- li.appendChild(link);
90
- return li;
91
- }
92
-
93
- function createEllipsis() {
94
- const li = document.createElement('li');
95
- li.textContent = '...';
96
- return li;
97
- }
@@ -1,104 +0,0 @@
1
- function visualizeHistory(allTaskStatus, finished) {
2
- const taskNames = Object.keys(allTaskStatus);
3
- const now = Date.now();
4
-
5
- // Set up canvas context
6
- const canvas = document.getElementById("history-canvas");
7
- canvas.height = taskNames.length * 50 + 10;
8
- const ctx = canvas.getContext("2d");
9
- ctx.clearRect(0, 0, canvas.width, canvas.height);
10
- ctx.fillStyle = "#EEE";
11
- ctx.fillRect(0, 0, canvas.width, canvas.height);
12
-
13
- // Calculate start and end times
14
- let minDateTime = null;
15
- let maxDateTime = null;
16
- for (let taskName in allTaskStatus) {
17
- let history = allTaskStatus[taskName].history;
18
- if (history.length == 0) {
19
- continue;
20
- }
21
- let startTime = new Date(history[0].time);
22
- if (minDateTime === null || minDateTime > startTime) {
23
- minDateTime = startTime;
24
- }
25
- let lastTime = new Date(history[history.length - 1].time);
26
- if (maxDateTime === null || maxDateTime < lastTime) {
27
- maxDateTime = lastTime;
28
- }
29
- }
30
- if (minDateTime === null || maxDateTime === null) {
31
- return
32
- }
33
- if (!finished) {
34
- maxDateTime = now;
35
- }
36
- if (maxDateTime - minDateTime == 0) {
37
- maxDateTime.setSeconds(maxDateTime.getSeconds() + 1)
38
- }
39
- // Canvas settings
40
- const chartWidth = canvas.width;
41
- const barHeight = 20;
42
- const gap = 10;
43
- const timeScale = (chartWidth - 200) / (maxDateTime - minDateTime);
44
-
45
- // Draw labels and bars
46
- taskNames.forEach((taskName, index) => {
47
- const taskHistories = allTaskStatus[taskName].history;
48
- if (taskHistories.length == 0) {
49
- return
50
- }
51
- // Get last status
52
- const finalStatus = getFinalTaskStatus(allTaskStatus[taskName]);
53
- const startDateTime = new Date(taskHistories[0].time);
54
- const endDateTime = getTaskEndDateTime(allTaskStatus[taskName], now);
55
- const startX = 100 + (startDateTime - minDateTime) * timeScale;
56
- const barWidth = (endDateTime - startDateTime) * timeScale;
57
- const startY = index * (barHeight + gap + 20) + 5;
58
-
59
- // Draw task label
60
- ctx.fillStyle = "#000";
61
- ctx.font = "12px Arial";
62
- ctx.textAlign = "right";
63
- ctx.fillText(taskName, 90, startY + barHeight / 1.5);
64
-
65
- // Draw task bar
66
- ctx.fillStyle = getFinalColor(finalStatus);
67
- ctx.fillRect(startX, startY, barWidth, barHeight);
68
-
69
- ctx.fillStyle = "#000";
70
- ctx.textAlign = "left";
71
- // Combine captions if time overlap
72
- let labels = {};
73
- for (let taskHistory of taskHistories) {
74
- let status = taskHistory.status;
75
- let dateTime = new Date(taskHistory.time);
76
- let statusStartX = 100 + (dateTime - minDateTime) * timeScale;
77
- if (!(statusStartX in labels)) {
78
- labels[statusStartX] = {dateTime: dateTime, caption: status};
79
- } else {
80
- labels[statusStartX].caption += `, ${status}`
81
- }
82
- }
83
- // Draw start and end time below the bar
84
- for (let statusStartX in labels) {
85
- const {dateTime, caption} = labels[statusStartX];
86
- const [dateStr, timeStr] = dateTime.toISOString().split("T");
87
- ctx.font = "10px Arial";
88
- ctx.fillText(caption, statusStartX, startY + 10);
89
- ctx.font = "8px Arial";
90
- ctx.fillText(dateStr, statusStartX, startY + barHeight + 10);
91
- ctx.fillText(timeStr, statusStartX, startY + barHeight + 20);
92
- }
93
- });
94
- }
95
-
96
- function getTaskEndDateTime(taskStatus, now) {
97
- if (taskStatus.is_completed || taskStatus.is_terminated || taskStatus.is_skipped || taskStatus.is_permanently_failed) {
98
- histories = taskStatus.history;
99
- if (histories.length > 0) {
100
- return new Date(histories[histories.length - 1].time);
101
- }
102
- }
103
- return now;
104
- }
@@ -1,87 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="color-scheme" content="light dark">
7
- <link rel="stylesheet" href="/static/pico.min.css">
8
- <link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
9
- <title>Zrb</title>
10
- </head>
11
- <body>
12
-
13
- <header class="container">
14
- <hgroup>
15
- <h1>{root_name}</h1>
16
- <p>{root_description}</p>
17
- <nav>
18
- <ul>
19
- <li><a href="/">🏠 Home</a></li>
20
- <li><a href="{parent_url}">🔙 Parent</a></li>
21
- <li><a href="{ui_url}">🆕 New Session</a></li>
22
- <li><a href="#" onclick="openDialog(event)">📂 Existing Session</a></li>
23
- </ul>
24
- </nav>
25
- </hgroup>
26
- </header>
27
-
28
- <dialog id="session-history-dialog">
29
- <article>
30
- <header>
31
- <button aria-label="Close" rel="prev" onclick="closeDialog(event)"></button>
32
- <p>
33
- <strong>📂 Existing Session</strong>
34
- </p>
35
- </header>
36
- <main>
37
- <form>
38
- <fieldset class="grid">
39
- <input type="datetime-local" id="min-start-at-input" placeholder="Minimum Start Time" aria-label="Minimum Start Time" />
40
- <input type="datetime-local" id="max-start-at-input" placeholder="Maximum Start Time" aria-label="Maximum Start Time" />
41
- </fieldset>
42
- </form>
43
- <ul id="session-history-ul" style="font-family:monospace;"></ul>
44
- </main>
45
- <footer>
46
- <nav>
47
- <ul id="session-history-pagination-ul"></ul>
48
- </nav>
49
- </footer>
50
- </article>
51
- </dialog>
52
-
53
- <main class="container">
54
- <h3>{name}</h3>
55
- <p>{description}</p>
56
- <canvas id="history-canvas" height="0" width="1000" style="width: 100%;"></canvas>
57
- <hr />
58
- <form id="submit-task-form" onsubmit="submitForm(event)">
59
- {task_inputs}
60
- <button>🚀 Run</button>
61
- </form>
62
- <hr />
63
- <label>
64
- Result
65
- <textarea id="result-textarea" rows="1" readonly style="font-family:monospace;">
66
- </textarea>
67
- </label>
68
- <label>
69
- Log
70
- <textarea id="log-textarea" rows="5" readonly style="font-family:monospace;">
71
- </textarea>
72
- </label>
73
- </main>
74
-
75
- </body>
76
- <script>
77
- const CURRENT_URL = '{url}';
78
- const API_URL = '{api_url}';
79
- const UI_URL = `{ui_url}`;
80
- let SESSION_NAME = '{session_name}';
81
- let PAGE = 0;
82
- {main_script}
83
- {common_util_script}
84
- {show_existing_session_script}
85
- {visualize_history_script}
86
- </script>
87
- </html>