PyBreeze 1.0.22__tar.gz → 1.0.24__tar.gz

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 (152) hide show
  1. {pybreeze-1.0.22 → pybreeze-1.0.24}/PKG-INFO +1 -1
  2. pybreeze-1.0.24/pybreeze/extend/process_executor/api_testka/api_testka_process.py +42 -0
  3. pybreeze-1.0.24/pybreeze/extend/process_executor/auto_control/auto_control_process.py +42 -0
  4. pybreeze-1.0.24/pybreeze/extend/process_executor/file_automation/file_automation_process.py +42 -0
  5. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/file_runner_process.py +20 -23
  6. pybreeze-1.0.24/pybreeze/extend/process_executor/load_density/load_density_process.py +42 -0
  7. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/process_executor_utils.py +26 -1
  8. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/python_task_process_manager.py +42 -19
  9. pybreeze-1.0.24/pybreeze/extend/process_executor/queue_pump.py +40 -0
  10. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/test_pioneer/test_pioneer_process_manager.py +25 -15
  11. pybreeze-1.0.24/pybreeze/extend/process_executor/web_runner/web_runner_process.py +42 -0
  12. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend_multi_language/extend_traditional_chinese.py +1 -1
  13. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_command_widget.py +47 -19
  14. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_file_viewer_widget.py +81 -28
  15. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_host_key_policy.py +2 -3
  16. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/url/ai_code_review_gui.py +17 -10
  17. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_editor_widget.py +28 -5
  18. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_items.py +21 -2
  19. pybreeze-1.0.24/pybreeze/pybreeze_ui/diagram_editor/diagram_mermaid_parser.py +520 -0
  20. pybreeze-1.0.24/pybreeze/pybreeze_ui/diagram_editor/diagram_net_utils.py +102 -0
  21. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_property_panel.py +11 -6
  22. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_scene.py +59 -22
  23. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py +39 -10
  24. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py +41 -13
  25. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_code_review_gui.py +19 -0
  26. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py +13 -6
  27. pybreeze-1.0.24/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_file_io.py +27 -0
  28. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py +11 -4
  29. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/skills/skills_send_gui.py +35 -7
  30. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_thread.py +56 -23
  31. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_widget.py +9 -2
  32. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/build_test_pioneer_menu.py +5 -4
  33. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/plugin_menu/build_plugin_menu.py +9 -6
  34. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/show_code_window/code_window.py +6 -0
  35. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/syntax/syntax_extend.py +4 -2
  36. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/syntax/syntax_keyword.py +135 -28
  37. pybreeze-1.0.24/pybreeze/utils/app_dirs.py +18 -0
  38. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/file_process/get_dir_file_list.py +9 -4
  39. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/json_format/json_process.py +5 -3
  40. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/logging/logger.py +4 -2
  41. pybreeze-1.0.24/pybreeze/utils/network/http_client.py +63 -0
  42. pybreeze-1.0.24/pybreeze/utils/network/url_validation.py +95 -0
  43. pybreeze-1.0.24/pybreeze/utils/subprocess_util.py +33 -0
  44. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze.egg-info/PKG-INFO +1 -1
  45. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze.egg-info/SOURCES.txt +4 -0
  46. {pybreeze-1.0.22 → pybreeze-1.0.24}/pyproject.toml +1 -1
  47. pybreeze-1.0.22/pybreeze/extend/process_executor/api_testka/api_testka_process.py +0 -63
  48. pybreeze-1.0.22/pybreeze/extend/process_executor/auto_control/auto_control_process.py +0 -63
  49. pybreeze-1.0.22/pybreeze/extend/process_executor/file_automation/file_automation_process.py +0 -63
  50. pybreeze-1.0.22/pybreeze/extend/process_executor/load_density/load_density_process.py +0 -63
  51. pybreeze-1.0.22/pybreeze/extend/process_executor/queue_pump.py +0 -33
  52. pybreeze-1.0.22/pybreeze/extend/process_executor/web_runner/web_runner_process.py +0 -61
  53. pybreeze-1.0.22/pybreeze/pybreeze_ui/diagram_editor/diagram_mermaid_parser.py +0 -324
  54. pybreeze-1.0.22/pybreeze/pybreeze_ui/diagram_editor/diagram_net_utils.py +0 -55
  55. pybreeze-1.0.22/pybreeze/utils/network/url_validation.py +0 -47
  56. {pybreeze-1.0.22 → pybreeze-1.0.24}/LICENSE +0 -0
  57. {pybreeze-1.0.22 → pybreeze-1.0.24}/README.md +0 -0
  58. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/__init__.py +0 -0
  59. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/__main__.py +0 -0
  60. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/__init__.py +0 -0
  61. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/mail_thunder_extend/__init__.py +0 -0
  62. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/mail_thunder_extend/mail_thunder_setting.py +0 -0
  63. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/__init__.py +0 -0
  64. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/api_testka/__init__.py +0 -0
  65. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/auto_control/__init__.py +0 -0
  66. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/file_automation/__init__.py +0 -0
  67. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/load_density/__init__.py +0 -0
  68. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/mail_thunder/__init__.py +0 -0
  69. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/mail_thunder/mail_thunder_process.py +0 -0
  70. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/test_pioneer/__init__.py +0 -0
  71. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend/process_executor/web_runner/__init__.py +0 -0
  72. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend_multi_language/__init__.py +0 -0
  73. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend_multi_language/extend_english.py +0 -0
  74. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/extend_multi_language/update_language_dict.py +0 -0
  75. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/__init__.py +0 -0
  76. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/__init__.py +0 -0
  77. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/__init__.py +0 -0
  78. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +0 -0
  79. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_login_widget.py +0 -0
  80. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_main_widget.py +0 -0
  81. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/connect_gui/url/__init__.py +0 -0
  82. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/__init__.py +0 -0
  83. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_commands.py +0 -0
  84. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/diagram_editor/diagram_view.py +0 -0
  85. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/editor_main/__init__.py +0 -0
  86. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/editor_main/main_ui.py +0 -0
  87. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/__init__.py +0 -0
  88. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/ai_gui_global_variable.py +0 -0
  89. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/__init__.py +0 -0
  90. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/__init__.py +0 -0
  91. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/__init__.py +0 -0
  92. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/code_smell_detector.py +0 -0
  93. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_code_review.py +0 -0
  94. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_summary_prompt.py +0 -0
  95. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/global_rule.py +0 -0
  96. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge.py +0 -0
  97. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge_single_review.py +0 -0
  98. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/linter.py +0 -0
  99. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/step_by_step_analysis.py +0 -0
  100. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/total_summary.py +0 -0
  101. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/__init__.py +0 -0
  102. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_explainer.py +0 -0
  103. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_review.py +0 -0
  104. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/extend_ai_gui/skills/__init__.py +0 -0
  105. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/jupyter_lab_gui/__init__.py +0 -0
  106. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/__init__.py +0 -0
  107. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/__init__.py +0 -0
  108. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/__init__.py +0 -0
  109. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +0 -0
  110. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/__init__.py +0 -0
  111. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/build_autocontrol_menu.py +0 -0
  112. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/__init__.py +0 -0
  113. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +0 -0
  114. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/automation_menu_factory.py +0 -0
  115. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/__init__.py +0 -0
  116. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +0 -0
  117. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/__init__.py +0 -0
  118. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/build_mail_thunder_menu.py +0 -0
  119. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/__init__.py +0 -0
  120. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/__init__.py +0 -0
  121. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +0 -0
  122. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/build_menubar.py +0 -0
  123. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/__init__.py +0 -0
  124. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/jupyter_lab_tab.py +0 -0
  125. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/__init__.py +0 -0
  126. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/__init__.py +0 -0
  127. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/build_automation_install_menu.py +0 -0
  128. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/install_utils.py +0 -0
  129. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/__init__.py +0 -0
  130. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/build_tool_install_menu.py +0 -0
  131. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/menu_utils.py +0 -0
  132. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/plugin_menu/__init__.py +0 -0
  133. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/plugin_menu/build_run_with_menu.py +0 -0
  134. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/tools/__init__.py +0 -0
  135. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/menu/tools/tools_menu.py +0 -0
  136. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/show_code_window/__init__.py +0 -0
  137. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/pybreeze_ui/syntax/__init__.py +0 -0
  138. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/__init__.py +0 -0
  139. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/exception/__init__.py +0 -0
  140. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/exception/exception_tags.py +0 -0
  141. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/exception/exceptions.py +0 -0
  142. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/file_process/__init__.py +0 -0
  143. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/json_format/__init__.py +0 -0
  144. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/logging/__init__.py +0 -0
  145. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/manager/__init__.py +0 -0
  146. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/manager/package_manager/__init__.py +0 -0
  147. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/manager/package_manager/package_manager_class.py +0 -0
  148. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze/utils/network/__init__.py +0 -0
  149. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze.egg-info/dependency_links.txt +0 -0
  150. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze.egg-info/requires.txt +0 -0
  151. {pybreeze-1.0.22 → pybreeze-1.0.24}/pybreeze.egg-info/top_level.txt +0 -0
  152. {pybreeze-1.0.22 → pybreeze-1.0.24}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybreeze
3
- Version: 1.0.22
3
+ Version: 1.0.24
4
4
  Summary: IDE for multi automation
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/AutomationEditor
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pybreeze.extend.process_executor.process_executor_utils import (
6
+ build_process, run_dir_files_with_package,
7
+ )
8
+
9
+ if TYPE_CHECKING:
10
+ from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
11
+
12
+ _PACKAGE = "je_api_testka"
13
+
14
+
15
+ def call_api_testka(
16
+ main_window: PyBreezeMainWindow,
17
+ exec_str: str | None = None,
18
+ program_buffer: int = 1024000
19
+ ):
20
+ build_process(main_window, _PACKAGE, exec_str, False, program_buffer)
21
+
22
+
23
+ def call_api_testka_with_send(
24
+ main_window: PyBreezeMainWindow,
25
+ exec_str: str | None = None,
26
+ program_buffer: int = 1024000
27
+ ):
28
+ build_process(main_window, _PACKAGE, exec_str, True, program_buffer)
29
+
30
+
31
+ def call_api_testka_multi_file(
32
+ main_window: PyBreezeMainWindow,
33
+ program_buffer: int = 1024000
34
+ ):
35
+ run_dir_files_with_package(main_window, _PACKAGE, False, program_buffer)
36
+
37
+
38
+ def call_api_testka_multi_file_and_send(
39
+ main_window: PyBreezeMainWindow,
40
+ program_buffer: int = 1024000
41
+ ):
42
+ run_dir_files_with_package(main_window, _PACKAGE, True, program_buffer)
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pybreeze.extend.process_executor.process_executor_utils import (
6
+ build_process, run_dir_files_with_package,
7
+ )
8
+
9
+ if TYPE_CHECKING:
10
+ from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
11
+
12
+ _PACKAGE = "je_auto_control"
13
+
14
+
15
+ def call_auto_control(
16
+ main_window: PyBreezeMainWindow,
17
+ exec_str: str | None = None,
18
+ program_buffer: int = 1024000
19
+ ):
20
+ build_process(main_window, _PACKAGE, exec_str, False, program_buffer)
21
+
22
+
23
+ def call_auto_control_with_send(
24
+ main_window: PyBreezeMainWindow,
25
+ exec_str: str | None = None,
26
+ program_buffer: int = 1024000
27
+ ):
28
+ build_process(main_window, _PACKAGE, exec_str, True, program_buffer)
29
+
30
+
31
+ def call_auto_control_multi_file(
32
+ main_window: PyBreezeMainWindow,
33
+ program_buffer: int = 1024000
34
+ ):
35
+ run_dir_files_with_package(main_window, _PACKAGE, False, program_buffer)
36
+
37
+
38
+ def call_auto_control_multi_file_and_send(
39
+ main_window: PyBreezeMainWindow,
40
+ program_buffer: int = 1024000
41
+ ):
42
+ run_dir_files_with_package(main_window, _PACKAGE, True, program_buffer)
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pybreeze.extend.process_executor.process_executor_utils import (
6
+ build_process, run_dir_files_with_package,
7
+ )
8
+
9
+ if TYPE_CHECKING:
10
+ from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
11
+
12
+ _PACKAGE = "automation_file"
13
+
14
+
15
+ def call_file_automation_test(
16
+ main_window: PyBreezeMainWindow,
17
+ exec_str: str | None = None,
18
+ program_buffer: int = 1024000
19
+ ):
20
+ build_process(main_window, _PACKAGE, exec_str, False, program_buffer)
21
+
22
+
23
+ def call_file_automation_test_with_send(
24
+ main_window: PyBreezeMainWindow,
25
+ exec_str: str | None = None,
26
+ program_buffer: int = 1024000
27
+ ):
28
+ build_process(main_window, _PACKAGE, exec_str, True, program_buffer)
29
+
30
+
31
+ def call_file_automation_test_multi_file(
32
+ main_window: PyBreezeMainWindow,
33
+ program_buffer: int = 1024000
34
+ ):
35
+ run_dir_files_with_package(main_window, _PACKAGE, False, program_buffer)
36
+
37
+
38
+ def call_file_automation_test_multi_file_and_send(
39
+ main_window: PyBreezeMainWindow,
40
+ program_buffer: int = 1024000
41
+ ):
42
+ run_dir_files_with_package(main_window, _PACKAGE, True, program_buffer)
@@ -21,6 +21,8 @@ from PySide6.QtGui import QTextCharFormat
21
21
  from je_editor.pyside_ui.main_ui.save_settings.user_color_setting_file import actually_color_dict
22
22
 
23
23
  from pybreeze.pybreeze_ui.show_code_window.code_window import CodeWindow
24
+ from pybreeze.utils.logging.logger import pybreeze_logger
25
+ from pybreeze.utils.subprocess_util import no_window_creationflags, utf8_subprocess_env
24
26
 
25
27
 
26
28
  class FileRunnerProcess:
@@ -81,6 +83,7 @@ class FileRunnerProcess:
81
83
  compile_cmd,
82
84
  capture_output=True,
83
85
  timeout=60,
86
+ creationflags=no_window_creationflags(),
84
87
  )
85
88
  except FileNotFoundError:
86
89
  self._append_text(f"[Error] Compiler not found: {compiler}\n", is_error=True)
@@ -117,6 +120,8 @@ class FileRunnerProcess:
117
120
  stderr=subprocess.PIPE,
118
121
  stdin=subprocess.PIPE,
119
122
  shell=False,
123
+ creationflags=no_window_creationflags(),
124
+ env=utf8_subprocess_env(self.program_encoding),
120
125
  )
121
126
  except FileNotFoundError:
122
127
  self._append_text(f"[Error] Command not found: {command[0]}\n", is_error=True)
@@ -189,8 +194,8 @@ class FileRunnerProcess:
189
194
  if self._cleanup_binary:
190
195
  try:
191
196
  os.remove(self._cleanup_binary)
192
- except OSError:
193
- pass
197
+ except OSError as error:
198
+ pybreeze_logger.debug("Could not remove compiled binary %s: %s", self._cleanup_binary, error)
194
199
 
195
200
  def _drain_queues(self) -> None:
196
201
  """Drain all remaining messages from output/error queues to UI."""
@@ -211,37 +216,29 @@ class FileRunnerProcess:
211
216
  except queue.Empty:
212
217
  break
213
218
 
214
- def _read_stdout(self) -> None:
219
+ def _read_stream(self, stream_name: str, target_queue: Queue) -> None:
220
+ # Empty read from readline means the pipe reached EOF (the child closed
221
+ # the stream), so stop immediately rather than spinning on a closed pipe
222
+ # until the process is reaped.
215
223
  try:
216
224
  while self.still_running:
217
225
  proc = self.process
218
226
  if proc is None:
219
227
  break
220
- data = proc.stdout.readline(self.program_buffer_size)
221
- if not data and proc.poll() is not None:
228
+ data = getattr(proc, stream_name).readline(self.program_buffer_size)
229
+ if not data:
222
230
  break
223
231
  if isinstance(data, bytes):
224
232
  data = data.decode(self.program_encoding, "replace")
225
- if data:
226
- self.output_queue.put(data)
227
- except (OSError, ValueError):
228
- pass
233
+ target_queue.put(data)
234
+ except (OSError, ValueError) as error:
235
+ pybreeze_logger.debug("Reader for %s stopped: %s", stream_name, error)
236
+
237
+ def _read_stdout(self) -> None:
238
+ self._read_stream("stdout", self.output_queue)
229
239
 
230
240
  def _read_stderr(self) -> None:
231
- try:
232
- while self.still_running:
233
- proc = self.process
234
- if proc is None:
235
- break
236
- data = proc.stderr.readline(self.program_buffer_size)
237
- if not data and proc.poll() is not None:
238
- break
239
- if isinstance(data, bytes):
240
- data = data.decode(self.program_encoding, "replace")
241
- if data:
242
- self.error_queue.put(data)
243
- except (OSError, ValueError):
244
- pass
241
+ self._read_stream("stderr", self.error_queue)
245
242
 
246
243
  def _append_text(self, text: str, is_error: bool) -> None:
247
244
  """Append text to the code result widget."""
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pybreeze.extend.process_executor.process_executor_utils import (
6
+ build_process, run_dir_files_with_package,
7
+ )
8
+
9
+ if TYPE_CHECKING:
10
+ from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
11
+
12
+ _PACKAGE = "je_load_density"
13
+
14
+
15
+ def call_load_density(
16
+ main_window: PyBreezeMainWindow,
17
+ exec_str: str | None = None,
18
+ program_buffer: int = 1024000
19
+ ):
20
+ build_process(main_window, _PACKAGE, exec_str, False, program_buffer)
21
+
22
+
23
+ def call_load_density_with_send(
24
+ main_window: PyBreezeMainWindow,
25
+ exec_str: str | None = None,
26
+ program_buffer: int = 1024000
27
+ ):
28
+ build_process(main_window, _PACKAGE, exec_str, True, program_buffer)
29
+
30
+
31
+ def call_load_density_multi_file(
32
+ main_window: PyBreezeMainWindow,
33
+ program_buffer: int = 1024000
34
+ ):
35
+ run_dir_files_with_package(main_window, _PACKAGE, False, program_buffer)
36
+
37
+
38
+ def call_load_density_multi_file_and_send(
39
+ main_window: PyBreezeMainWindow,
40
+ program_buffer: int = 1024000
41
+ ):
42
+ run_dir_files_with_package(main_window, _PACKAGE, True, program_buffer)
@@ -10,6 +10,7 @@ from pybreeze.extend.mail_thunder_extend.mail_thunder_setting import send_after_
10
10
  from pybreeze.extend.process_executor.python_task_process_manager import TaskProcessManager
11
11
  from pybreeze.utils.exception.exception_tags import wrong_test_data_format_exception_tag
12
12
  from pybreeze.utils.exception.exceptions import ITETestExecutorException
13
+ from pybreeze.utils.file_process.get_dir_file_list import ask_and_get_dir_files_as_list
13
14
  from pybreeze.utils.logging.logger import pybreeze_logger
14
15
 
15
16
  if TYPE_CHECKING:
@@ -31,7 +32,7 @@ def build_process(
31
32
  test_format_code = exec_str
32
33
  start_process(main_window, package, test_format_code, send_mail, program_buffer)
33
34
  except json.decoder.JSONDecodeError as error:
34
- pybreeze_logger.error(f"{repr(error)}\n{wrong_test_data_format_exception_tag}")
35
+ pybreeze_logger.error(f"{error!r}\n{wrong_test_data_format_exception_tag}")
35
36
  except ITETestExecutorException as error:
36
37
  pybreeze_logger.error(repr(error))
37
38
 
@@ -70,6 +71,30 @@ def build_process_from_file(
70
71
  pybreeze_logger.error(repr(error))
71
72
 
72
73
 
74
+ def run_dir_files_with_package(
75
+ main_window: PyBreezeMainWindow,
76
+ package: str,
77
+ send_mail: bool = False,
78
+ program_buffer: int = 1024000,
79
+ ) -> None:
80
+ """Prompt for a directory and run every matching file through *package*.
81
+
82
+ Each file is executed via its on-disk path (``--execute_file``) so large
83
+ action JSON never trips the Windows ~32K command-line limit, and one run
84
+ window is opened per file. ``build_process_from_file`` already logs and
85
+ contains per-file executor errors; the broad guard here only keeps a single
86
+ bad directory pick from crashing the menu callback.
87
+ """
88
+ try:
89
+ execute_list = ask_and_get_dir_files_as_list(main_window)
90
+ if not execute_list:
91
+ return
92
+ for execute_file in execute_list:
93
+ build_process_from_file(main_window, package, execute_file, send_mail, program_buffer)
94
+ except Exception as error: # noqa: BLE001 — batch UI action must not abort on one bad entry
95
+ pybreeze_logger.error("%s multi file error: %r", package, error)
96
+
97
+
73
98
  def _build_task_process(
74
99
  main_window: PyBreezeMainWindow,
75
100
  send_mail: bool,
@@ -13,11 +13,13 @@ from threading import Thread
13
13
  from PySide6.QtCore import QTimer
14
14
  from PySide6.QtGui import QTextCharFormat
15
15
  from je_editor.pyside_ui.main_ui.save_settings.user_color_setting_file import actually_color_dict
16
+ from je_editor.utils.exception.exceptions import JEditorExecException
16
17
  from je_editor.utils.venv_check.check_venv import check_and_choose_venv
17
18
 
18
19
  from pybreeze.extend.process_executor.queue_pump import pump_message_queue
19
20
  from pybreeze.pybreeze_ui.show_code_window.code_window import CodeWindow
20
21
  from pybreeze.utils.logging.logger import pybreeze_logger
22
+ from pybreeze.utils.subprocess_util import no_window_creationflags, utf8_subprocess_env
21
23
 
22
24
 
23
25
  def find_venv_path() -> Path:
@@ -65,15 +67,26 @@ class TaskProcessManager:
65
67
  self.error_trigger_function: Callable = error_trigger_function
66
68
  self.program_buffer_size = program_buffer_size
67
69
 
68
- def renew_path(self) -> None:
70
+ def renew_path(self) -> bool:
71
+ """Resolve the interpreter path. Returns False (without raising) when no
72
+ Python can be found, surfacing the error in the run window instead of
73
+ crashing the menu callback."""
69
74
  if self.main_window.python_compiler is None:
70
75
  venv_path = find_venv_path()
71
- self.compiler_path = check_and_choose_venv(venv_path)
76
+ try:
77
+ self.compiler_path = check_and_choose_venv(venv_path)
78
+ except JEditorExecException as error:
79
+ pybreeze_logger.error("No Python interpreter found for run: %r", error)
80
+ self._append_text(f"[Error] No Python interpreter found: {error}", is_error=True)
81
+ self.main_window.show()
82
+ return False
72
83
  else:
73
84
  self.compiler_path = self.main_window.python_compiler
85
+ return True
74
86
 
75
87
  def start_test_process(self, package: str, exec_str: str):
76
- self.renew_path()
88
+ if not self.renew_path():
89
+ return
77
90
  if sys.platform in ["win32", "cygwin", "msys"]:
78
91
  exec_str = json.dumps(exec_str)
79
92
  args = [
@@ -88,7 +101,8 @@ class TaskProcessManager:
88
101
  def start_test_process_file(self, package: str, file_path: str):
89
102
  # Pass the action JSON as a path so we never hit the Windows ~32K
90
103
  # command-line cap when scripts are large. Caller owns the file.
91
- self.renew_path()
104
+ if not self.renew_path():
105
+ return
92
106
  args = [
93
107
  str(self.compiler_path),
94
108
  "-m",
@@ -106,6 +120,8 @@ class TaskProcessManager:
106
120
  args,
107
121
  stdout=subprocess.PIPE,
108
122
  stderr=subprocess.PIPE,
123
+ creationflags=no_window_creationflags(),
124
+ env=utf8_subprocess_env(self.program_encoding),
109
125
  )
110
126
  self.still_run_program = True
111
127
  self.read_program_output_from_thread = Thread(
@@ -186,24 +202,31 @@ class TaskProcessManager:
186
202
  except queue.Empty:
187
203
  break
188
204
 
189
- def read_program_output_from_process(self):
205
+ def _read_stream_into_queue(self, stream_name: str, target_queue: Queue) -> None:
206
+ # Block on readline until a line arrives or the pipe hits EOF. Stopping on
207
+ # EOF (empty read) is essential: without it the loop spins at 100% CPU
208
+ # re-reading a closed pipe until the QTimer notices the process exited.
190
209
  while self.still_run_program:
191
210
  proc = self.process
192
211
  if proc is None:
193
212
  break
194
- program_output_data = proc.stdout.readline(self.program_buffer_size)
195
- if isinstance(program_output_data, bytes):
196
- program_output_data = program_output_data.decode(self.program_encoding, "replace")
197
- if program_output_data.strip():
198
- self.run_output_queue.put(program_output_data)
213
+ stream = getattr(proc, stream_name)
214
+ if stream is None:
215
+ break
216
+ try:
217
+ line = stream.readline(self.program_buffer_size)
218
+ except (ValueError, OSError):
219
+ # Pipe closed underneath us during shutdown.
220
+ break
221
+ if not line:
222
+ break
223
+ if isinstance(line, bytes):
224
+ line = line.decode(self.program_encoding, "replace")
225
+ if line.strip():
226
+ target_queue.put(line)
227
+
228
+ def read_program_output_from_process(self):
229
+ self._read_stream_into_queue("stdout", self.run_output_queue)
199
230
 
200
231
  def read_program_error_output_from_process(self):
201
- while self.still_run_program:
202
- proc = self.process
203
- if proc is None:
204
- break
205
- program_error_output_data = proc.stderr.readline(self.program_buffer_size)
206
- if isinstance(program_error_output_data, bytes):
207
- program_error_output_data = program_error_output_data.decode(self.program_encoding, "replace")
208
- if program_error_output_data.strip():
209
- self.run_error_queue.put(program_error_output_data)
232
+ self._read_stream_into_queue("stderr", self.run_error_queue)
@@ -0,0 +1,40 @@
1
+ """Shared helper for the process-executor QTimer pump loop.
2
+
3
+ The Python task runner and the Test Pioneer runner both drain the same
4
+ ``(output_queue, error_queue) → append_text`` pattern on a ~100 ms timer.
5
+ This module factors the per-tick drain into a single function so changes
6
+ (e.g., multi-message batching) can be made in one place.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import queue
11
+ from collections.abc import Callable
12
+ from queue import Queue
13
+
14
+ # Drain up to this many messages per timer tick. Draining one line per ~100 ms
15
+ # tick caps throughput at ~10 lines/s and makes chatty scripts crawl; batching
16
+ # many lines per tick keeps up with bursty output while the bound keeps the UI
17
+ # thread from stalling when a process floods stdout.
18
+ MAX_MESSAGES_PER_PUMP = 256
19
+
20
+
21
+ def pump_message_queue(
22
+ q: Queue,
23
+ append_fn: Callable[[str, bool], None],
24
+ *,
25
+ is_error: bool,
26
+ max_messages: int = MAX_MESSAGES_PER_PUMP,
27
+ ) -> None:
28
+ """Drain up to *max_messages* pending messages from *q* into *append_fn*.
29
+
30
+ Stops early when the queue empties. Empty strings (after stripping) are
31
+ skipped. ``queue.Empty`` from the racy non-blocking get is treated as a
32
+ clean stop, not an error.
33
+ """
34
+ for _ in range(max_messages):
35
+ try:
36
+ message = str(q.get_nowait()).strip()
37
+ except queue.Empty:
38
+ return
39
+ if message:
40
+ append_fn(message, is_error)
@@ -14,6 +14,7 @@ from je_editor.utils.venv_check.check_venv import check_and_choose_venv
14
14
  from pybreeze.extend.process_executor.python_task_process_manager import find_venv_path
15
15
  from pybreeze.extend.process_executor.queue_pump import pump_message_queue
16
16
  from pybreeze.pybreeze_ui.show_code_window.code_window import CodeWindow
17
+ from pybreeze.utils.subprocess_util import no_window_creationflags, utf8_subprocess_env
17
18
 
18
19
  if TYPE_CHECKING:
19
20
  from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
@@ -61,6 +62,8 @@ class TestPioneerProcess:
61
62
  stdin=subprocess.PIPE,
62
63
  stdout=subprocess.PIPE,
63
64
  stderr=subprocess.PIPE,
65
+ creationflags=no_window_creationflags(),
66
+ env=utf8_subprocess_env(self._program_encoding),
64
67
  )
65
68
 
66
69
  def _append_text(self, text: str, is_error: bool = False) -> None:
@@ -119,27 +122,34 @@ class TestPioneerProcess:
119
122
  except queue.Empty:
120
123
  break
121
124
 
122
- def read_program_output_from_process(self):
125
+ def _read_stream_into_queue(self, stream_name: str, target_queue: Queue) -> None:
126
+ # Block on readline until a line arrives or the pipe hits EOF. Stopping on
127
+ # EOF (empty read) is essential: without it the loop spins at 100% CPU
128
+ # re-reading a closed pipe until the QTimer notices the process exited.
123
129
  while self._still_run_program:
124
130
  proc = self._process
125
131
  if proc is None:
126
132
  break
127
- program_output_data = proc.stdout.readline(self._program_buffer_size)
128
- if isinstance(program_output_data, bytes):
129
- program_output_data = program_output_data.decode(self._program_encoding, "replace")
130
- if program_output_data.strip():
131
- self._run_output_queue.put(program_output_data)
133
+ stream = getattr(proc, stream_name)
134
+ if stream is None:
135
+ break
136
+ try:
137
+ line = stream.readline(self._program_buffer_size)
138
+ except (ValueError, OSError):
139
+ # Pipe closed underneath us during shutdown.
140
+ break
141
+ if not line:
142
+ break
143
+ if isinstance(line, bytes):
144
+ line = line.decode(self._program_encoding, "replace")
145
+ if line.strip():
146
+ target_queue.put(line)
147
+
148
+ def read_program_output_from_process(self):
149
+ self._read_stream_into_queue("stdout", self._run_output_queue)
132
150
 
133
151
  def read_program_error_output_from_process(self):
134
- while self._still_run_program:
135
- proc = self._process
136
- if proc is None:
137
- break
138
- program_error_output_data = proc.stderr.readline(self._program_buffer_size)
139
- if isinstance(program_error_output_data, bytes):
140
- program_error_output_data = program_error_output_data.decode(self._program_encoding, "replace")
141
- if program_error_output_data.strip():
142
- self._run_error_queue.put(program_error_output_data)
152
+ self._read_stream_into_queue("stderr", self._run_error_queue)
143
153
 
144
154
  def start_test_pioneer_process(self):
145
155
  self._still_run_program = True
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pybreeze.extend.process_executor.process_executor_utils import (
6
+ build_process, run_dir_files_with_package,
7
+ )
8
+
9
+ if TYPE_CHECKING:
10
+ from pybreeze.pybreeze_ui.editor_main.main_ui import PyBreezeMainWindow
11
+
12
+ _PACKAGE = "je_web_runner"
13
+
14
+
15
+ def call_web_runner_test(
16
+ main_window: PyBreezeMainWindow,
17
+ exec_str: str | None = None,
18
+ program_buffer: int = 1024000
19
+ ):
20
+ build_process(main_window, _PACKAGE, exec_str, False, program_buffer)
21
+
22
+
23
+ def call_web_runner_test_with_send(
24
+ main_window: PyBreezeMainWindow,
25
+ exec_str: str | None = None,
26
+ program_buffer: int = 1024000
27
+ ):
28
+ build_process(main_window, _PACKAGE, exec_str, True, program_buffer)
29
+
30
+
31
+ def call_web_runner_test_multi_file(
32
+ main_window: PyBreezeMainWindow,
33
+ program_buffer: int = 1024000
34
+ ):
35
+ run_dir_files_with_package(main_window, _PACKAGE, False, program_buffer)
36
+
37
+
38
+ def call_web_runner_test_multi_file_and_send(
39
+ main_window: PyBreezeMainWindow,
40
+ program_buffer: int = 1024000
41
+ ):
42
+ run_dir_files_with_package(main_window, _PACKAGE, True, program_buffer)
@@ -125,7 +125,7 @@ pybreeze_traditional_chinese_word_dict = {
125
125
  "ssh_command_widget_status_label_disconnected": "已斷線",
126
126
  "ssh_command_widget_log_message_connected": "已連線至",
127
127
  "ssh_command_widget_log_message_error": "[錯誤]",
128
- "ssh_command_widget_error_message_decode_failed": "<解碼錯誤> {error}",
128
+ "ssh_command_widget_error_message_decode_failed": "<解碼錯誤> ",
129
129
  "ssh_command_widget_log_message_channel_closed": "[通道已關閉]",
130
130
  "ssh_command_widget_error_message_reader_failed": "讀取錯誤",
131
131
  "ssh_command_widget_log_message_reader_closed": "讀取已關閉",