PyBreeze 1.0.30__tar.gz → 1.0.32__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.
- {pybreeze-1.0.30 → pybreeze-1.0.32}/PKG-INFO +36 -34
- {pybreeze-1.0.30 → pybreeze-1.0.32}/README.md +31 -29
- pybreeze-1.0.32/pybreeze/__init__.py +58 -0
- pybreeze-1.0.32/pybreeze/__main__.py +13 -0
- pybreeze-1.0.32/pybreeze/extend/mail_thunder_extend/mail_thunder_setting.py +129 -0
- pybreeze-1.0.32/pybreeze/extend/process_executor/file_runner_process.py +317 -0
- pybreeze-1.0.32/pybreeze/extend/process_executor/process_executor_utils.py +271 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/prthinker/prthinker_process.py +2 -10
- pybreeze-1.0.32/pybreeze/extend/process_executor/python_task_process_manager.py +319 -0
- pybreeze-1.0.32/pybreeze/extend/process_executor/queue_pump.py +194 -0
- pybreeze-1.0.32/pybreeze/extend/process_executor/test_pioneer/test_pioneer_process_manager.py +22 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/prthinker_extend/prthinker_setting.py +156 -23
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend_multi_language/extend_english.py +88 -9
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend_multi_language/extend_traditional_chinese.py +153 -22
- pybreeze-1.0.32/pybreeze/extend_multi_language/update_language_dict.py +29 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/closing.py +43 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/sftp_session.py +473 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_command_widget.py +448 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_connect_thread.py +60 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_file_viewer_widget.py +725 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_host_key_policy.py +268 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +85 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_login_widget.py +19 -1
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_main_widget.py +33 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/connect_gui/url/ai_code_review_gui.py +385 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/diagram_editor/diagram_commands.py +48 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_editor_widget.py +143 -48
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_items.py +172 -37
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_mermaid_parser.py +121 -28
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_net_utils.py +25 -12
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_property_panel.py +51 -19
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_scene.py +325 -60
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/diagram_view.py +30 -10
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/dialog/prthinker_setting_dialog.py +27 -7
- pybreeze-1.0.32/pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py +497 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/editor_main/main_ui.py +212 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/error_text.py +56 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/exact_text.py +23 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py +27 -11
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_chain.py +19 -2
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_code_review_gui.py +30 -14
- pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_editor_widget.py +275 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_file_io.py +9 -4
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_store.py +31 -7
- pybreeze-1.0.32/pybreeze/pybreeze_ui/extend_ai_gui/skills/skills_send_gui.py +255 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/gui_thread_gc.py +58 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_thread.py +254 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_widget.py +100 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +42 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/build_autocontrol_menu.py +89 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +39 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/automation_menu_factory.py +163 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +43 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/build_mail_thunder_menu.py +30 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu/build_prthinker_menu.py +16 -2
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/build_test_pioneer_menu.py +107 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +39 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/jupyter_lab_tab.py +1 -1
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/build_automation_install_menu.py +7 -3
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/install_menu/install_utils.py +32 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/build_tool_install_menu.py +3 -4
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/plugin_menu/build_plugin_menu.py +153 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/menu/plugin_menu/build_run_with_menu.py +198 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/tools/tools_menu.py +13 -2
- pybreeze-1.0.32/pybreeze/pybreeze_ui/plain_text.py +20 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/show_code_window/code_window.py +174 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/syntax/syntax_extend.py +5 -4
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/syntax/syntax_keyword.py +4 -0
- pybreeze-1.0.32/pybreeze/pybreeze_ui/thread_keeper.py +63 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/curl_import_gui.py +19 -8
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/diff_gui.py +49 -6
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/har_import_gui.py +54 -10
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/hash_gui.py +2 -1
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/header_analyzer_gui.py +6 -1
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/json_format_gui.py +4 -2
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/jwt_decoder_gui.py +7 -6
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/output_actions.py +21 -10
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/query_json_gui.py +14 -4
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/regex_gui.py +77 -12
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/response_inspector_gui.py +15 -7
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/timestamp_gui.py +2 -1
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/url_builder_gui.py +15 -6
- pybreeze-1.0.32/pybreeze/utils/app_dirs.py +30 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/curl_import/curl_parser.py +270 -61
- pybreeze-1.0.32/pybreeze/utils/curl_import/request_body.py +157 -0
- pybreeze-1.0.32/pybreeze/utils/curl_import/request_codegen.py +267 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/curl_import/script_templates.py +51 -29
- pybreeze-1.0.32/pybreeze/utils/diff_tools/text_diff.py +241 -0
- pybreeze-1.0.32/pybreeze/utils/exception/error_templates.py +26 -0
- pybreeze-1.0.32/pybreeze/utils/exception/exception_tags.py +106 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/file_process/get_dir_file_list.py +0 -14
- pybreeze-1.0.32/pybreeze/utils/file_process/read_capped.py +35 -0
- pybreeze-1.0.32/pybreeze/utils/file_process/replace_file.py +87 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/har_import/har_codegen.py +33 -10
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/har_import/har_parser.py +85 -21
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/header_tools/header_analyzer.py +20 -3
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/http_reference/status_codes.py +13 -0
- pybreeze-1.0.32/pybreeze/utils/json_format/json_process.py +175 -0
- pybreeze-1.0.32/pybreeze/utils/json_format/view_safe.py +38 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/jwt_tools/jwt_decoder.py +77 -16
- pybreeze-1.0.32/pybreeze/utils/logging/logger.py +138 -0
- pybreeze-1.0.32/pybreeze/utils/network/http_client.py +189 -0
- pybreeze-1.0.32/pybreeze/utils/network/public_http.py +264 -0
- pybreeze-1.0.32/pybreeze/utils/network/url_validation.py +193 -0
- pybreeze-1.0.32/pybreeze/utils/query_tools/query_convert.py +165 -0
- pybreeze-1.0.32/pybreeze/utils/regex_tools/regex_tester.py +324 -0
- pybreeze-1.0.32/pybreeze/utils/response_inspector/response_analyzer.py +178 -0
- pybreeze-1.0.32/pybreeze/utils/subprocess_util.py +72 -0
- pybreeze-1.0.32/pybreeze/utils/terminal_text.py +99 -0
- pybreeze-1.0.32/pybreeze/utils/timestamp_tools/timestamp_converter.py +236 -0
- pybreeze-1.0.32/pybreeze/utils/url_tools/url_convert.py +232 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze.egg-info/PKG-INFO +36 -34
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze.egg-info/SOURCES.txt +14 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze.egg-info/requires.txt +2 -2
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pyproject.toml +5 -5
- pybreeze-1.0.30/pybreeze/__init__.py +0 -19
- pybreeze-1.0.30/pybreeze/__main__.py +0 -5
- pybreeze-1.0.30/pybreeze/extend/mail_thunder_extend/mail_thunder_setting.py +0 -52
- pybreeze-1.0.30/pybreeze/extend/process_executor/file_runner_process.py +0 -250
- pybreeze-1.0.30/pybreeze/extend/process_executor/process_executor_utils.py +0 -117
- pybreeze-1.0.30/pybreeze/extend/process_executor/python_task_process_manager.py +0 -250
- pybreeze-1.0.30/pybreeze/extend/process_executor/queue_pump.py +0 -40
- pybreeze-1.0.30/pybreeze/extend/process_executor/test_pioneer/test_pioneer_process_manager.py +0 -181
- pybreeze-1.0.30/pybreeze/extend_multi_language/update_language_dict.py +0 -10
- pybreeze-1.0.30/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_command_widget.py +0 -282
- pybreeze-1.0.30/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_file_viewer_widget.py +0 -572
- pybreeze-1.0.30/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_host_key_policy.py +0 -110
- pybreeze-1.0.30/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +0 -32
- pybreeze-1.0.30/pybreeze/pybreeze_ui/connect_gui/url/ai_code_review_gui.py +0 -197
- pybreeze-1.0.30/pybreeze/pybreeze_ui/diagram_editor/diagram_commands.py +0 -28
- pybreeze-1.0.30/pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py +0 -292
- pybreeze-1.0.30/pybreeze/pybreeze_ui/editor_main/main_ui.py +0 -116
- pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_editor_widget.py +0 -165
- pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/skills/skills_send_gui.py +0 -170
- pybreeze-1.0.30/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_thread.py +0 -175
- pybreeze-1.0.30/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_widget.py +0 -71
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +0 -44
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/build_autocontrol_menu.py +0 -70
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +0 -40
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/automation_menu_factory.py +0 -110
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +0 -44
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/build_mail_thunder_menu.py +0 -31
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/build_test_pioneer_menu.py +0 -63
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +0 -40
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/install_menu/install_utils.py +0 -21
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/plugin_menu/build_plugin_menu.py +0 -188
- pybreeze-1.0.30/pybreeze/pybreeze_ui/menu/plugin_menu/build_run_with_menu.py +0 -98
- pybreeze-1.0.30/pybreeze/pybreeze_ui/show_code_window/code_window.py +0 -39
- pybreeze-1.0.30/pybreeze/utils/app_dirs.py +0 -18
- pybreeze-1.0.30/pybreeze/utils/curl_import/request_body.py +0 -67
- pybreeze-1.0.30/pybreeze/utils/curl_import/request_codegen.py +0 -154
- pybreeze-1.0.30/pybreeze/utils/diff_tools/text_diff.py +0 -76
- pybreeze-1.0.30/pybreeze/utils/exception/exception_tags.py +0 -71
- pybreeze-1.0.30/pybreeze/utils/json_format/json_process.py +0 -50
- pybreeze-1.0.30/pybreeze/utils/logging/logger.py +0 -58
- pybreeze-1.0.30/pybreeze/utils/network/http_client.py +0 -63
- pybreeze-1.0.30/pybreeze/utils/network/url_validation.py +0 -95
- pybreeze-1.0.30/pybreeze/utils/query_tools/query_convert.py +0 -89
- pybreeze-1.0.30/pybreeze/utils/regex_tools/regex_tester.py +0 -113
- pybreeze-1.0.30/pybreeze/utils/response_inspector/response_analyzer.py +0 -128
- pybreeze-1.0.30/pybreeze/utils/subprocess_util.py +0 -33
- pybreeze-1.0.30/pybreeze/utils/timestamp_tools/timestamp_converter.py +0 -104
- pybreeze-1.0.30/pybreeze/utils/url_tools/url_convert.py +0 -117
- {pybreeze-1.0.30 → pybreeze-1.0.32}/LICENSE +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/mail_thunder_extend/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/api_testka/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/api_testka/api_testka_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/auto_control/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/auto_control/auto_control_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/file_automation/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/file_automation/file_automation_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/load_density/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/load_density/load_density_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/mail_thunder/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/mail_thunder/mail_thunder_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/prthinker/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/test_pioneer/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/web_runner/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/process_executor/web_runner/web_runner_process.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend/prthinker_extend/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/extend_multi_language/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/connect_gui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/connect_gui/ssh/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/connect_gui/url/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/diagram_editor/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/dialog/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/editor_main/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/ai_gui_global_variable.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/code_smell_detector.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_code_review.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_summary_prompt.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/global_rule.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge_single_review.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/linter.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/step_by_step_analysis.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/total_summary.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_explainer.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_review.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/extend_ai_gui/skills/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/jupyter_lab_gui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/build_menubar.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/install_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/menu_utils.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/plugin_menu/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/menu/tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/show_code_window/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/syntax/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/http_status_gui.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/pybreeze_ui/tools_gui/tool_tabs.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/curl_import/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/diff_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/exception/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/exception/exceptions.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/file_process/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/har_import/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/hash_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/hash_tools/hash_text.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/header_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/header_tools/header_merge.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/http_reference/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/json_format/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/jwt_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/logging/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/manager/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/manager/package_manager/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/manager/package_manager/package_manager_class.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/network/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/query_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/regex_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/response_inspector/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/timestamp_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze/utils/url_tools/__init__.py +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze.egg-info/dependency_links.txt +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/pybreeze.egg-info/top_level.txt +0 -0
- {pybreeze-1.0.30 → pybreeze-1.0.32}/setup.cfg +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pybreeze
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.32
|
|
4
4
|
Summary: IDE for multi automation
|
|
5
5
|
Author-email: JE-Chen <jechenmailman@gmail.com>
|
|
6
|
-
Project-URL: Homepage, https://github.com/
|
|
7
|
-
Project-URL: Code, https://github.com/
|
|
6
|
+
Project-URL: Homepage, https://github.com/Integration-Automation/PyBreeze
|
|
7
|
+
Project-URL: Code, https://github.com/Integration-Automation/PyBreeze
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -18,14 +18,14 @@ Classifier: Operating System :: OS Independent
|
|
|
18
18
|
Requires-Python: >=3.10
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: je-editor
|
|
21
|
+
Requires-Dist: je-editor>=1.0.27
|
|
22
22
|
Requires-Dist: je_auto_control
|
|
23
23
|
Requires-Dist: je_web_runner
|
|
24
24
|
Requires-Dist: je_load_density
|
|
25
25
|
Requires-Dist: je_api_testka
|
|
26
26
|
Requires-Dist: je-mail-thunder
|
|
27
27
|
Requires-Dist: automation-file
|
|
28
|
-
Requires-Dist: PySide6==6.11.
|
|
28
|
+
Requires-Dist: PySide6==6.11.2
|
|
29
29
|
Requires-Dist: test_pioneer
|
|
30
30
|
Requires-Dist: paramiko
|
|
31
31
|
Requires-Dist: jupyterlab
|
|
@@ -90,27 +90,27 @@ PyBreeze covers the full spectrum of automation testing out of the box:
|
|
|
90
90
|
|
|
91
91
|
| Dimension | Module | What it does |
|
|
92
92
|
|---|---|---|
|
|
93
|
-
| **API** | [APITestka](https://github.com/
|
|
94
|
-
| **Web** | [WebRunner](https://github.com/
|
|
95
|
-
| **GUI** | [AutoControl](https://github.com/
|
|
96
|
-
| **Load** | [LoadDensity](https://github.com/
|
|
93
|
+
| **API** | [APITestka](https://github.com/Integration-Automation/APITestka) | RESTful testing with request builders, response analyzers, mock servers and assertions |
|
|
94
|
+
| **Web** | [WebRunner](https://github.com/Integration-Automation/WebRunner) | Browser-driven interaction and testing with driver and locator integration |
|
|
95
|
+
| **GUI** | [AutoControl](https://github.com/Integration-Automation/AutoControlGUI) | Desktop automation via image recognition, coordinates, keyboard/mouse control and recording |
|
|
96
|
+
| **Load** | [LoadDensity](https://github.com/Integration-Automation/LoadDensity) | High-concurrency performance testing for stability under pressure |
|
|
97
97
|
|
|
98
98
|
Plus:
|
|
99
99
|
|
|
100
|
-
- **File Automation** — file and directory operations via [automation-file](https://github.com/
|
|
101
|
-
- **Mail Automation** — report delivery via [MailThunder](https://github.com/
|
|
102
|
-
- **Test Framework** — YAML-driven execution via [TestPioneer](https://github.com/
|
|
100
|
+
- **File Automation** — file and directory operations via [automation-file](https://github.com/Integration-Automation/FileAutomation)
|
|
101
|
+
- **Mail Automation** — report delivery via [MailThunder](https://github.com/Integration-Automation/MailThunder)
|
|
102
|
+
- **Test Framework** — YAML-driven execution via [TestPioneer](https://github.com/Integration-Automation/TestPioneer)
|
|
103
103
|
|
|
104
104
|
Each module gets the same menu shape: **Run** (single script, batch directory, with or without an emailed report), **Help** (docs and GitHub open as in-IDE browser tabs), **Project** (scaffold a template directory), and where available a native GUI tab.
|
|
105
105
|
|
|
106
106
|
### IDE core
|
|
107
107
|
|
|
108
|
-
- **Automation-aware syntax highlighting** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml`, on top of JEditor's language support
|
|
109
|
-
- **Code editor** — built on [JEditor](https://github.com/
|
|
110
|
-
- **Script execution** — single or batch;
|
|
108
|
+
- **Automation-aware syntax highlighting** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml` and `.yaml`, on top of JEditor's language support
|
|
109
|
+
- **Code editor** — built on [JEditor](https://github.com/Integration-Automation/JEDITOR): tabs, project tree, format checker, debugger, terminal, variable inspector and a git client pane
|
|
110
|
+
- **Script execution** — single or batch, each run in a window of its own with a Stop button; action files are passed by path, and a script from the tab in front that is too long for a Windows command line (~32 KB) goes through a temporary file
|
|
111
111
|
- **Report generation** — HTML / JSON / XML after a run, with optional email delivery
|
|
112
112
|
- **Integrated JupyterLab** — launches as a tab, installing JupyterLab into the project venv if it is missing
|
|
113
|
-
- **Virtual environment awareness** — `venv/` and `.venv/` are detected and used automatically
|
|
113
|
+
- **Virtual environment awareness** — `venv/` and `.venv/` are detected and used automatically; without one, scripts run on the interpreter the IDE runs on
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
@@ -132,7 +132,7 @@ Targets: Python `requests`, a ready-to-run **pytest** test, **APITestka** (Pytho
|
|
|
132
132
|
|
|
133
133
|

|
|
134
134
|
|
|
135
|
-
Select what you want — or take everything listed — and generate one script using the same targets as the cURL importer. Repeated endpoints get numbered test names so no test silently replaces another; HTTP/2 pseudo-headers are dropped, and a `Cookie` header duplicating the recorded cookie list is removed so each value is sent once. A single selected request produces exactly what the cURL importer would. HAR is JSON, so this needs nothing beyond the standard library, and nothing is ever replayed for you.
|
|
135
|
+
Select what you want — or take everything listed — and generate one script using the same targets as the cURL importer. Repeated endpoints get numbered test names so no test silently replaces another; HTTP/2 pseudo-headers are dropped, and a `Cookie` header duplicating the recorded cookie list is removed so each value is sent once (cookies sharing a name, which a dictionary cannot hold, go as the header instead). An entry that cannot become a request, such as one with a malformed URL or method, is skipped and the rest load. A single selected request produces exactly what the cURL importer would. HAR is JSON, so this needs nothing beyond the standard library, and nothing is ever replayed for you.
|
|
136
136
|
|
|
137
137
|
### Response Inspector — paste a response, read everything in it
|
|
138
138
|
|
|
@@ -159,13 +159,13 @@ Each is a tab or a dock, each has the same copy / open-in-editor / save-to-file
|
|
|
159
159
|

|
|
160
160
|
|
|
161
161
|
- **JWT Decoder** — header and payload as pretty JSON, with `exp` / `iat` / `nbf` / `auth_time` as readable UTC. Inspection only: the signature is never verified and the token is never trusted.
|
|
162
|
-
- **Regex Tester** — `IGNORECASE` / `MULTILINE` / `DOTALL` / `VERBOSE`, every match with offsets, numbered groups and named groups. An invalid pattern reports a friendly error instead of crashing.
|
|
162
|
+
- **Regex Tester** — `IGNORECASE` / `MULTILINE` / `DOTALL` / `VERBOSE`, every match with offsets, numbered groups and named groups. Enter in the pattern runs it. An invalid pattern reports a friendly error instead of crashing.
|
|
163
163
|
- **HTTP Status Reference** — search the full status table (sourced from the standard library, so it stays current) by code prefix or keyword.
|
|
164
164
|
- **JSON Format** — pretty-print or minify, with a clear validation error when the input is not JSON.
|
|
165
165
|
|
|
166
166
|

|
|
167
167
|
|
|
168
|
-
- **Timestamp Converter** — a Unix epoch (seconds or
|
|
168
|
+
- **Timestamp Converter** — a Unix epoch (seconds, milliseconds, microseconds or nanoseconds, auto-detected) or an ISO-8601 date-time (with `Z`, `+08`, `+0800` or `+08:00`, any number of fraction digits, basic or extended) in, every representation out in UTC. Deterministic and independent of the local time zone.
|
|
169
169
|
- **Hash Generator** — SHA-256, SHA-512, SHA-1 and MD5 at once (MD5/SHA-1 for interoperability with `usedforsecurity=False`, never for security decisions).
|
|
170
170
|
- **Query ⇄ JSON** — `application/x-www-form-urlencoded` to pretty JSON and back; repeated keys become arrays and vice versa.
|
|
171
171
|
- **URL Parser / Builder** — scheme, host, port, path, query, fragment and credentials as an editable JSON object, and back again. Brackets IPv6 literals and re-encodes query parameters for you.
|
|
@@ -182,12 +182,12 @@ A WYSIWYG `QGraphicsScene` editor: rectangle, rounded, ellipse and diamond nodes
|
|
|
182
182
|
|
|
183
183
|

|
|
184
184
|
|
|
185
|
-
Password or private-key authentication, an interactive shell with ANSI handling and keepalive, and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`.
|
|
185
|
+
Password or private-key authentication (the key file picked with Browse, starting in `~/.ssh`), an interactive shell with ANSI handling and keepalive, and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download. Every SFTP request runs in the background, so a stalled link never freezes the IDE. An upload asks before it replaces a file on the server, and a transfer can be cancelled from the tree's menu. Both directions write to a temporary file first, so a dropped link leaves the old copy whole. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`.
|
|
186
186
|
|
|
187
187
|
### And also
|
|
188
188
|
|
|
189
|
-
- **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager. Renaming or deleting a file open in an editor tab keeps the tab in sync.
|
|
190
|
-
- **Package Manager** — install automation modules and build tools from the menu, output in
|
|
189
|
+
- **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager (a file shown selected in Explorer and Finder). Renaming or deleting a file open in an editor tab keeps the tab in sync.
|
|
190
|
+
- **Package Manager** — install automation modules and build tools from the menu, output in a run window.
|
|
191
191
|
- **Integrated Documentation** — each module's docs and GitHub page open as in-IDE browser tabs.
|
|
192
192
|
|
|
193
193
|
---
|
|
@@ -198,7 +198,7 @@ Password or private-key authentication, an interactive shell with ANSI handling
|
|
|
198
198
|
|
|
199
199
|

|
|
200
200
|
|
|
201
|
-
*Shown in the pre-send state.* Send a selection to an LLM endpoint, then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, redirects are not followed, and the response body is size-capped before it reaches the panel.
|
|
201
|
+
*Shown in the pre-send state.* Send a selection to an LLM endpoint, then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, the connection goes only to the address that was checked, redirects are not followed, and the response body is size-capped before it reaches the panel.
|
|
202
202
|
|
|
203
203
|
### Chain-of-Thought Code Review (prthinker)
|
|
204
204
|
|
|
@@ -206,13 +206,15 @@ Run the [prthinker](https://github.com/JE-Chen/Code-Review-Framework-Combining-L
|
|
|
206
206
|
|
|
207
207
|

|
|
208
208
|
|
|
209
|
-
One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs.
|
|
209
|
+
One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs. The model name goes to whichever backend is chosen. Rule retrieval (RAG) is `off` unless set to `remote`, which asks the prthinker server's `/rag`: prthinker's local rule index ships with its repository, not with the package installed from it. The review runs with the interpreter chosen in `Python Env`, so PyBreeze itself can stay on an older Python than the 3.12 prthinker needs.
|
|
210
210
|
|
|
211
211
|
### CoT Prompt Editor
|
|
212
212
|
|
|
213
213
|

|
|
214
214
|
|
|
215
|
-
Create and manage the multi-step review chain: first summary → first code review → linter → code smell detector → total summary. Each step
|
|
215
|
+
Create and manage the multi-step review chain: first summary → first code review → a judge of that review → linter → code smell detector → step-by-step analysis → total summary → a judge of the summary. Each step quotes the answers it needs from the steps before it. Files are watched, so an external edit shows up immediately.
|
|
216
|
+
|
|
217
|
+
Run the chain from **Tools → AI → CoT Code Review** (a tab, or a dock from the Dock menu): paste the code, give the endpoint URL, and each step's answer appears in the selector as it arrives.
|
|
216
218
|
|
|
217
219
|
### Skill Prompt Editor & Skill Send
|
|
218
220
|
|
|
@@ -233,7 +235,7 @@ PyBreeze inherits JEditor's plugin architecture, auto-discovered from a `jeditor
|
|
|
233
235
|
- **Run configurations** — "Run with…" for interpreted (`go run main.go`) and compiled (`gcc main.c -o main` then run) languages, executed through PyBreeze's `FileRunnerProcess` with the compiled artifact cleaned up afterwards
|
|
234
236
|
- **Plugin Browser** — browse and install plugins from remote repositories inside the IDE
|
|
235
237
|
|
|
236
|
-
Loaded plugins appear under their own **Plugins** menu with an About entry and one run action
|
|
238
|
+
Loaded plugins appear under their own **Plugins** menu with an About entry and one run action, labelled with the suffixes it runs. [PLUGIN_GUIDE.md](PLUGIN_GUIDE.md) covers what PyBreeze adds and links JEditor's guide, which has the full API and worked examples (C, C++, Go, Java, Rust, and a French translation).
|
|
237
239
|
|
|
238
240
|
---
|
|
239
241
|
|
|
@@ -242,7 +244,7 @@ Loaded plugins appear under their own **Plugins** menu with an About entry and o
|
|
|
242
244
|
- **English** (default)
|
|
243
245
|
- **Traditional Chinese** (繁體中文)
|
|
244
246
|
|
|
245
|
-
Both dictionaries carry the same
|
|
247
|
+
Both dictionaries carry the same 708 keys, and a test enforces that parity so a new string can never land in one language only. Further languages can be added via translation plugins.
|
|
246
248
|
|
|
247
249
|
---
|
|
248
250
|
|
|
@@ -329,8 +331,8 @@ pip install pybreeze
|
|
|
329
331
|
### From source
|
|
330
332
|
|
|
331
333
|
```bash
|
|
332
|
-
git clone https://github.com/
|
|
333
|
-
cd
|
|
334
|
+
git clone https://github.com/Integration-Automation/PyBreeze.git
|
|
335
|
+
cd PyBreeze
|
|
334
336
|
pip install -r requirements.txt
|
|
335
337
|
```
|
|
336
338
|
|
|
@@ -338,7 +340,7 @@ pip install -r requirements.txt
|
|
|
338
340
|
|
|
339
341
|
- **Python**: 3.10 – 3.14
|
|
340
342
|
- **OS**: Windows, macOS, Linux
|
|
341
|
-
- **GUI**: PySide6 6.11.
|
|
343
|
+
- **GUI**: PySide6 6.11.2 (installed automatically)
|
|
342
344
|
|
|
343
345
|
---
|
|
344
346
|
|
|
@@ -393,7 +395,7 @@ PyBreeze/
|
|
|
393
395
|
│ │ │ ├── python_task_process_manager.py # TaskProcessManager (core)
|
|
394
396
|
│ │ │ ├── process_executor_utils.py # build_process / start_process
|
|
395
397
|
│ │ │ ├── file_runner_process.py # Plugin run configs (any language)
|
|
396
|
-
│ │ │ ├── queue_pump.py # Shared QTimer drain
|
|
398
|
+
│ │ │ ├── queue_pump.py # Shared pipe reader + QTimer drain
|
|
397
399
|
│ │ │ ├── api_testka/ auto_control/ web_runner/
|
|
398
400
|
│ │ │ ├── load_density/ file_automation/ mail_thunder/
|
|
399
401
|
│ │ │ ├── test_pioneer/ prthinker/
|
|
@@ -432,7 +434,7 @@ PyBreeze/
|
|
|
432
434
|
|
|
433
435
|
| Package | Purpose |
|
|
434
436
|
|---|---|
|
|
435
|
-
| `PySide6` (6.11.
|
|
437
|
+
| `PySide6` (6.11.2) | GUI framework (Qt for Python) |
|
|
436
438
|
| `je-editor` | Base code editor engine |
|
|
437
439
|
| `je_api_testka` | API testing automation |
|
|
438
440
|
| `je_auto_control` | GUI/desktop automation |
|
|
@@ -446,7 +448,7 @@ PyBreeze/
|
|
|
446
448
|
|
|
447
449
|
### Development
|
|
448
450
|
|
|
449
|
-
`build`, `twine`, `sphinx`, `sphinx-rtd-theme`, `auto-py-to-exe`, `pytest`, `hypothesis`
|
|
451
|
+
`build`, `twine`, `sphinx`, `sphinx-rtd-theme`, `auto-py-to-exe`, `pytest`, `pytest-cov`, `hypothesis`, `ruff`
|
|
450
452
|
|
|
451
453
|
---
|
|
452
454
|
|
|
@@ -457,7 +459,7 @@ python -m pip install -r dev_requirements.txt
|
|
|
457
459
|
python -m pytest test/test_utils/ -v --tb=short
|
|
458
460
|
```
|
|
459
461
|
|
|
460
|
-
- **Unit tests** — `test/test_utils/`,
|
|
462
|
+
- **Unit tests** — `test/test_utils/`, covering the pure-logic layer (curl and HAR parsing, header analysis, SSRF validation, JWT, hashing, timestamps, diffing) plus headless Qt widget tests via `QT_QPA_PLATFORM=offscreen`, with Hypothesis property tests over the parsers
|
|
461
463
|
- **Startup tests** — `test/unit_test/start_automation/` launches the IDE in debug mode and verifies it comes up and exits cleanly
|
|
462
464
|
- **CI** — GitHub Actions on Windows across Python 3.10 – 3.14, on every push and PR plus a nightly run
|
|
463
465
|
- **Static analysis** — SonarCloud, Codacy and Bandit
|
|
@@ -57,27 +57,27 @@ PyBreeze covers the full spectrum of automation testing out of the box:
|
|
|
57
57
|
|
|
58
58
|
| Dimension | Module | What it does |
|
|
59
59
|
|---|---|---|
|
|
60
|
-
| **API** | [APITestka](https://github.com/
|
|
61
|
-
| **Web** | [WebRunner](https://github.com/
|
|
62
|
-
| **GUI** | [AutoControl](https://github.com/
|
|
63
|
-
| **Load** | [LoadDensity](https://github.com/
|
|
60
|
+
| **API** | [APITestka](https://github.com/Integration-Automation/APITestka) | RESTful testing with request builders, response analyzers, mock servers and assertions |
|
|
61
|
+
| **Web** | [WebRunner](https://github.com/Integration-Automation/WebRunner) | Browser-driven interaction and testing with driver and locator integration |
|
|
62
|
+
| **GUI** | [AutoControl](https://github.com/Integration-Automation/AutoControlGUI) | Desktop automation via image recognition, coordinates, keyboard/mouse control and recording |
|
|
63
|
+
| **Load** | [LoadDensity](https://github.com/Integration-Automation/LoadDensity) | High-concurrency performance testing for stability under pressure |
|
|
64
64
|
|
|
65
65
|
Plus:
|
|
66
66
|
|
|
67
|
-
- **File Automation** — file and directory operations via [automation-file](https://github.com/
|
|
68
|
-
- **Mail Automation** — report delivery via [MailThunder](https://github.com/
|
|
69
|
-
- **Test Framework** — YAML-driven execution via [TestPioneer](https://github.com/
|
|
67
|
+
- **File Automation** — file and directory operations via [automation-file](https://github.com/Integration-Automation/FileAutomation)
|
|
68
|
+
- **Mail Automation** — report delivery via [MailThunder](https://github.com/Integration-Automation/MailThunder)
|
|
69
|
+
- **Test Framework** — YAML-driven execution via [TestPioneer](https://github.com/Integration-Automation/TestPioneer)
|
|
70
70
|
|
|
71
71
|
Each module gets the same menu shape: **Run** (single script, batch directory, with or without an emailed report), **Help** (docs and GitHub open as in-IDE browser tabs), **Project** (scaffold a template directory), and where available a native GUI tab.
|
|
72
72
|
|
|
73
73
|
### IDE core
|
|
74
74
|
|
|
75
|
-
- **Automation-aware syntax highlighting** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml`, on top of JEditor's language support
|
|
76
|
-
- **Code editor** — built on [JEditor](https://github.com/
|
|
77
|
-
- **Script execution** — single or batch;
|
|
75
|
+
- **Automation-aware syntax highlighting** — the `AT_*` / GUI / Web / Load keyword sets are registered for `.json`, and TestPioneer's schema for `.yml` and `.yaml`, on top of JEditor's language support
|
|
76
|
+
- **Code editor** — built on [JEditor](https://github.com/Integration-Automation/JEDITOR): tabs, project tree, format checker, debugger, terminal, variable inspector and a git client pane
|
|
77
|
+
- **Script execution** — single or batch, each run in a window of its own with a Stop button; action files are passed by path, and a script from the tab in front that is too long for a Windows command line (~32 KB) goes through a temporary file
|
|
78
78
|
- **Report generation** — HTML / JSON / XML after a run, with optional email delivery
|
|
79
79
|
- **Integrated JupyterLab** — launches as a tab, installing JupyterLab into the project venv if it is missing
|
|
80
|
-
- **Virtual environment awareness** — `venv/` and `.venv/` are detected and used automatically
|
|
80
|
+
- **Virtual environment awareness** — `venv/` and `.venv/` are detected and used automatically; without one, scripts run on the interpreter the IDE runs on
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
@@ -99,7 +99,7 @@ Targets: Python `requests`, a ready-to-run **pytest** test, **APITestka** (Pytho
|
|
|
99
99
|
|
|
100
100
|

|
|
101
101
|
|
|
102
|
-
Select what you want — or take everything listed — and generate one script using the same targets as the cURL importer. Repeated endpoints get numbered test names so no test silently replaces another; HTTP/2 pseudo-headers are dropped, and a `Cookie` header duplicating the recorded cookie list is removed so each value is sent once. A single selected request produces exactly what the cURL importer would. HAR is JSON, so this needs nothing beyond the standard library, and nothing is ever replayed for you.
|
|
102
|
+
Select what you want — or take everything listed — and generate one script using the same targets as the cURL importer. Repeated endpoints get numbered test names so no test silently replaces another; HTTP/2 pseudo-headers are dropped, and a `Cookie` header duplicating the recorded cookie list is removed so each value is sent once (cookies sharing a name, which a dictionary cannot hold, go as the header instead). An entry that cannot become a request, such as one with a malformed URL or method, is skipped and the rest load. A single selected request produces exactly what the cURL importer would. HAR is JSON, so this needs nothing beyond the standard library, and nothing is ever replayed for you.
|
|
103
103
|
|
|
104
104
|
### Response Inspector — paste a response, read everything in it
|
|
105
105
|
|
|
@@ -126,13 +126,13 @@ Each is a tab or a dock, each has the same copy / open-in-editor / save-to-file
|
|
|
126
126
|

|
|
127
127
|
|
|
128
128
|
- **JWT Decoder** — header and payload as pretty JSON, with `exp` / `iat` / `nbf` / `auth_time` as readable UTC. Inspection only: the signature is never verified and the token is never trusted.
|
|
129
|
-
- **Regex Tester** — `IGNORECASE` / `MULTILINE` / `DOTALL` / `VERBOSE`, every match with offsets, numbered groups and named groups. An invalid pattern reports a friendly error instead of crashing.
|
|
129
|
+
- **Regex Tester** — `IGNORECASE` / `MULTILINE` / `DOTALL` / `VERBOSE`, every match with offsets, numbered groups and named groups. Enter in the pattern runs it. An invalid pattern reports a friendly error instead of crashing.
|
|
130
130
|
- **HTTP Status Reference** — search the full status table (sourced from the standard library, so it stays current) by code prefix or keyword.
|
|
131
131
|
- **JSON Format** — pretty-print or minify, with a clear validation error when the input is not JSON.
|
|
132
132
|
|
|
133
133
|

|
|
134
134
|
|
|
135
|
-
- **Timestamp Converter** — a Unix epoch (seconds or
|
|
135
|
+
- **Timestamp Converter** — a Unix epoch (seconds, milliseconds, microseconds or nanoseconds, auto-detected) or an ISO-8601 date-time (with `Z`, `+08`, `+0800` or `+08:00`, any number of fraction digits, basic or extended) in, every representation out in UTC. Deterministic and independent of the local time zone.
|
|
136
136
|
- **Hash Generator** — SHA-256, SHA-512, SHA-1 and MD5 at once (MD5/SHA-1 for interoperability with `usedforsecurity=False`, never for security decisions).
|
|
137
137
|
- **Query ⇄ JSON** — `application/x-www-form-urlencoded` to pretty JSON and back; repeated keys become arrays and vice versa.
|
|
138
138
|
- **URL Parser / Builder** — scheme, host, port, path, query, fragment and credentials as an editable JSON object, and back again. Brackets IPv6 literals and re-encodes query parameters for you.
|
|
@@ -149,12 +149,12 @@ A WYSIWYG `QGraphicsScene` editor: rectangle, rounded, ellipse and diamond nodes
|
|
|
149
149
|
|
|
150
150
|

|
|
151
151
|
|
|
152
|
-
Password or private-key authentication, an interactive shell with ANSI handling and keepalive, and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`.
|
|
152
|
+
Password or private-key authentication (the key file picked with Browse, starting in `~/.ssh`), an interactive shell with ANSI handling and keepalive, and a lazy-loading SFTP tree with create-folder / rename / delete / upload / download. Every SFTP request runs in the background, so a stalled link never freezes the IDE. An upload asks before it replaces a file on the server, and a transfer can be cancelled from the tree's menu. Both directions write to a temporary file first, so a dropped link leaves the old copy whole. Unknown host keys are **not** auto-accepted: the SHA256 fingerprint is shown for confirmation on first connection (trust on first use) and persisted to `~/.pybreeze/ssh_known_hosts`.
|
|
153
153
|
|
|
154
154
|
### And also
|
|
155
155
|
|
|
156
|
-
- **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager. Renaming or deleting a file open in an editor tab keeps the tab in sync.
|
|
157
|
-
- **Package Manager** — install automation modules and build tools from the menu, output in
|
|
156
|
+
- **File Tree Context Menu** — right-click to create, rename, delete, copy absolute or relative paths, or reveal the item in your platform file manager (a file shown selected in Explorer and Finder). Renaming or deleting a file open in an editor tab keeps the tab in sync.
|
|
157
|
+
- **Package Manager** — install automation modules and build tools from the menu, output in a run window.
|
|
158
158
|
- **Integrated Documentation** — each module's docs and GitHub page open as in-IDE browser tabs.
|
|
159
159
|
|
|
160
160
|
---
|
|
@@ -165,7 +165,7 @@ Password or private-key authentication, an interactive shell with ANSI handling
|
|
|
165
165
|
|
|
166
166
|

|
|
167
167
|
|
|
168
|
-
*Shown in the pre-send state.* Send a selection to an LLM endpoint, then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, redirects are not followed, and the response body is size-capped before it reaches the panel.
|
|
168
|
+
*Shown in the pre-send state.* Send a selection to an LLM endpoint, then accept or reject the suggestion — the tally is kept in `~/.pybreeze/response_stats.txt`. The URL is SSRF-validated, the connection goes only to the address that was checked, redirects are not followed, and the response body is size-capped before it reaches the panel.
|
|
169
169
|
|
|
170
170
|
### Chain-of-Thought Code Review (prthinker)
|
|
171
171
|
|
|
@@ -173,13 +173,15 @@ Run the [prthinker](https://github.com/JE-Chen/Code-Review-Framework-Combining-L
|
|
|
173
173
|
|
|
174
174
|

|
|
175
175
|
|
|
176
|
-
One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs.
|
|
176
|
+
One settings form holds the inference backend (`remote`, `local`, OpenAI-compatible, Anthropic, Gemini, Cohere, Mistral, `claude-cli`, `codex-cli`), the code host (GitHub / GitLab / Gitea) and the repository. **Keys and tokens are handed to the review as environment variables, never on a command line** where a process list would show them — and they are masked in logs. The model name goes to whichever backend is chosen. Rule retrieval (RAG) is `off` unless set to `remote`, which asks the prthinker server's `/rag`: prthinker's local rule index ships with its repository, not with the package installed from it. The review runs with the interpreter chosen in `Python Env`, so PyBreeze itself can stay on an older Python than the 3.12 prthinker needs.
|
|
177
177
|
|
|
178
178
|
### CoT Prompt Editor
|
|
179
179
|
|
|
180
180
|

|
|
181
181
|
|
|
182
|
-
Create and manage the multi-step review chain: first summary → first code review → linter → code smell detector → total summary. Each step
|
|
182
|
+
Create and manage the multi-step review chain: first summary → first code review → a judge of that review → linter → code smell detector → step-by-step analysis → total summary → a judge of the summary. Each step quotes the answers it needs from the steps before it. Files are watched, so an external edit shows up immediately.
|
|
183
|
+
|
|
184
|
+
Run the chain from **Tools → AI → CoT Code Review** (a tab, or a dock from the Dock menu): paste the code, give the endpoint URL, and each step's answer appears in the selector as it arrives.
|
|
183
185
|
|
|
184
186
|
### Skill Prompt Editor & Skill Send
|
|
185
187
|
|
|
@@ -200,7 +202,7 @@ PyBreeze inherits JEditor's plugin architecture, auto-discovered from a `jeditor
|
|
|
200
202
|
- **Run configurations** — "Run with…" for interpreted (`go run main.go`) and compiled (`gcc main.c -o main` then run) languages, executed through PyBreeze's `FileRunnerProcess` with the compiled artifact cleaned up afterwards
|
|
201
203
|
- **Plugin Browser** — browse and install plugins from remote repositories inside the IDE
|
|
202
204
|
|
|
203
|
-
Loaded plugins appear under their own **Plugins** menu with an About entry and one run action
|
|
205
|
+
Loaded plugins appear under their own **Plugins** menu with an About entry and one run action, labelled with the suffixes it runs. [PLUGIN_GUIDE.md](PLUGIN_GUIDE.md) covers what PyBreeze adds and links JEditor's guide, which has the full API and worked examples (C, C++, Go, Java, Rust, and a French translation).
|
|
204
206
|
|
|
205
207
|
---
|
|
206
208
|
|
|
@@ -209,7 +211,7 @@ Loaded plugins appear under their own **Plugins** menu with an About entry and o
|
|
|
209
211
|
- **English** (default)
|
|
210
212
|
- **Traditional Chinese** (繁體中文)
|
|
211
213
|
|
|
212
|
-
Both dictionaries carry the same
|
|
214
|
+
Both dictionaries carry the same 708 keys, and a test enforces that parity so a new string can never land in one language only. Further languages can be added via translation plugins.
|
|
213
215
|
|
|
214
216
|
---
|
|
215
217
|
|
|
@@ -296,8 +298,8 @@ pip install pybreeze
|
|
|
296
298
|
### From source
|
|
297
299
|
|
|
298
300
|
```bash
|
|
299
|
-
git clone https://github.com/
|
|
300
|
-
cd
|
|
301
|
+
git clone https://github.com/Integration-Automation/PyBreeze.git
|
|
302
|
+
cd PyBreeze
|
|
301
303
|
pip install -r requirements.txt
|
|
302
304
|
```
|
|
303
305
|
|
|
@@ -305,7 +307,7 @@ pip install -r requirements.txt
|
|
|
305
307
|
|
|
306
308
|
- **Python**: 3.10 – 3.14
|
|
307
309
|
- **OS**: Windows, macOS, Linux
|
|
308
|
-
- **GUI**: PySide6 6.11.
|
|
310
|
+
- **GUI**: PySide6 6.11.2 (installed automatically)
|
|
309
311
|
|
|
310
312
|
---
|
|
311
313
|
|
|
@@ -360,7 +362,7 @@ PyBreeze/
|
|
|
360
362
|
│ │ │ ├── python_task_process_manager.py # TaskProcessManager (core)
|
|
361
363
|
│ │ │ ├── process_executor_utils.py # build_process / start_process
|
|
362
364
|
│ │ │ ├── file_runner_process.py # Plugin run configs (any language)
|
|
363
|
-
│ │ │ ├── queue_pump.py # Shared QTimer drain
|
|
365
|
+
│ │ │ ├── queue_pump.py # Shared pipe reader + QTimer drain
|
|
364
366
|
│ │ │ ├── api_testka/ auto_control/ web_runner/
|
|
365
367
|
│ │ │ ├── load_density/ file_automation/ mail_thunder/
|
|
366
368
|
│ │ │ ├── test_pioneer/ prthinker/
|
|
@@ -399,7 +401,7 @@ PyBreeze/
|
|
|
399
401
|
|
|
400
402
|
| Package | Purpose |
|
|
401
403
|
|---|---|
|
|
402
|
-
| `PySide6` (6.11.
|
|
404
|
+
| `PySide6` (6.11.2) | GUI framework (Qt for Python) |
|
|
403
405
|
| `je-editor` | Base code editor engine |
|
|
404
406
|
| `je_api_testka` | API testing automation |
|
|
405
407
|
| `je_auto_control` | GUI/desktop automation |
|
|
@@ -413,7 +415,7 @@ PyBreeze/
|
|
|
413
415
|
|
|
414
416
|
### Development
|
|
415
417
|
|
|
416
|
-
`build`, `twine`, `sphinx`, `sphinx-rtd-theme`, `auto-py-to-exe`, `pytest`, `hypothesis`
|
|
418
|
+
`build`, `twine`, `sphinx`, `sphinx-rtd-theme`, `auto-py-to-exe`, `pytest`, `pytest-cov`, `hypothesis`, `ruff`
|
|
417
419
|
|
|
418
420
|
---
|
|
419
421
|
|
|
@@ -424,7 +426,7 @@ python -m pip install -r dev_requirements.txt
|
|
|
424
426
|
python -m pytest test/test_utils/ -v --tb=short
|
|
425
427
|
```
|
|
426
428
|
|
|
427
|
-
- **Unit tests** — `test/test_utils/`,
|
|
429
|
+
- **Unit tests** — `test/test_utils/`, covering the pure-logic layer (curl and HAR parsing, header analysis, SSRF validation, JWT, hashing, timestamps, diffing) plus headless Qt widget tests via `QT_QPA_PLATFORM=offscreen`, with Hypothesis property tests over the parsers
|
|
428
430
|
- **Startup tests** — `test/unit_test/start_automation/` launches the IDE in debug mode and verifies it comes up and exits cleanly
|
|
429
431
|
- **CI** — GitHub Actions on Windows across Python 3.10 – 3.14, on every push and PR plus a nightly run
|
|
430
432
|
- **Static analysis** — SonarCloud, Codacy and Bandit
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""PyBreeze's public names, imported the first time one is used.
|
|
2
|
+
|
|
3
|
+
Importing ``pybreeze`` used to import the whole IDE up front -- PySide6, JEditor,
|
|
4
|
+
every menu builder -- so ``import pybreeze.utils.<anything>`` took about four
|
|
5
|
+
seconds, and so did every process that only needed a utility: a test run, or the
|
|
6
|
+
regex tester's worker process, which paid it on each run. The names are the same
|
|
7
|
+
and resolve to the same objects; they are just looked up on first use.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from je_editor import (
|
|
16
|
+
load_external_plugins,
|
|
17
|
+
register_natural_language,
|
|
18
|
+
register_programming_language,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from pybreeze.pybreeze_ui.editor_main.main_ui import (
|
|
22
|
+
EDITOR_EXTEND_TAB,
|
|
23
|
+
PyBreezeMainWindow,
|
|
24
|
+
start_editor,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Where each public name lives; JEditor's plugin API is re-exported for convenience
|
|
28
|
+
_HOMES = {
|
|
29
|
+
"EDITOR_EXTEND_TAB": "pybreeze.pybreeze_ui.editor_main.main_ui",
|
|
30
|
+
"PyBreezeMainWindow": "pybreeze.pybreeze_ui.editor_main.main_ui",
|
|
31
|
+
"start_editor": "pybreeze.pybreeze_ui.editor_main.main_ui",
|
|
32
|
+
"load_external_plugins": "je_editor",
|
|
33
|
+
"register_natural_language": "je_editor",
|
|
34
|
+
"register_programming_language": "je_editor",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"EDITOR_EXTEND_TAB",
|
|
39
|
+
"PyBreezeMainWindow",
|
|
40
|
+
"load_external_plugins",
|
|
41
|
+
"register_natural_language",
|
|
42
|
+
"register_programming_language",
|
|
43
|
+
"start_editor",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def __getattr__(name: str) -> Any:
|
|
48
|
+
"""Import a public name from its home the first time it is asked for."""
|
|
49
|
+
home = _HOMES.get(name)
|
|
50
|
+
if home is None:
|
|
51
|
+
raise AttributeError(f"module 'pybreeze' has no attribute {name!r}")
|
|
52
|
+
value = getattr(importlib.import_module(home), name)
|
|
53
|
+
globals()[name] = value
|
|
54
|
+
return value
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def __dir__() -> list[str]:
|
|
58
|
+
return sorted(set(globals()) | set(__all__))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import multiprocessing
|
|
4
|
+
|
|
5
|
+
from pybreeze import start_editor
|
|
6
|
+
|
|
7
|
+
# Guarded: in the packaged executable the regex tester runs its worker as a
|
|
8
|
+
# spawned process, which re-runs the main script in the child, and an unguarded
|
|
9
|
+
# start_editor() there would open a second IDE; freeze_support() lets the child
|
|
10
|
+
# start as a worker. (From source, the worker is a plain script and needs neither.)
|
|
11
|
+
if __name__ == "__main__":
|
|
12
|
+
multiprocessing.freeze_support()
|
|
13
|
+
start_editor()
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import threading
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
|
|
7
|
+
from pybreeze.utils.exception.exception_tags import send_html_exception_tag
|
|
8
|
+
from pybreeze.utils.exception.exceptions import ITESendHtmlReportException
|
|
9
|
+
from pybreeze.utils.logging.logger import pybreeze_logger
|
|
10
|
+
|
|
11
|
+
DEFAULT_REPORT_PATH = "default_name.html"
|
|
12
|
+
|
|
13
|
+
# How much older than the run a report may look and still be its own: file
|
|
14
|
+
# systems keep modification times to a second or two
|
|
15
|
+
_MTIME_SLACK_SECONDS = 2.0
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def send_after_test(
|
|
19
|
+
html_report_path: str | None = None,
|
|
20
|
+
*,
|
|
21
|
+
not_before: float | None = None,
|
|
22
|
+
on_done: Callable[[str | None], None] | None = None,
|
|
23
|
+
) -> None:
|
|
24
|
+
"""Mail a finished run's HTML report, on a thread of its own.
|
|
25
|
+
|
|
26
|
+
This is a run's done-hook, called on the UI thread as the run ends. The
|
|
27
|
+
SMTP connect (made when the client is built), the login and the send take
|
|
28
|
+
as long as the mail server does, and the IDE used to be frozen for all of
|
|
29
|
+
it. Whatever goes wrong is logged by that thread, never raised.
|
|
30
|
+
|
|
31
|
+
:param html_report_path: the report to send; ``default_name.html`` when None
|
|
32
|
+
:param not_before: see ``send_report``
|
|
33
|
+
:param on_done: called on the mail thread with ``send_report``'s answer
|
|
34
|
+
"""
|
|
35
|
+
def send() -> None:
|
|
36
|
+
try:
|
|
37
|
+
outcome = send_report(html_report_path, not_before=not_before)
|
|
38
|
+
# The last stop on this thread: anything je_mail_thunder raises past
|
|
39
|
+
# send_report must still reach on_done, or the run window never says
|
|
40
|
+
except Exception as error: # noqa: BLE001 — logged, and reported to the run window
|
|
41
|
+
pybreeze_logger.error("Sending the report failed: %r", error)
|
|
42
|
+
outcome = f"sending failed ({type(error).__name__})"
|
|
43
|
+
if on_done is not None:
|
|
44
|
+
on_done(outcome)
|
|
45
|
+
|
|
46
|
+
threading.Thread(target=send, name="pybreeze-report-mail", daemon=True).start()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def send_report(html_report_path: str | None = None, *, not_before: float | None = None) -> str | None:
|
|
50
|
+
"""Mail the HTML report to the configured mail user, and log what went wrong.
|
|
51
|
+
|
|
52
|
+
Blocks for as long as the mail server takes; ``send_after_test`` runs it
|
|
53
|
+
off the UI thread.
|
|
54
|
+
|
|
55
|
+
:param html_report_path: the report to send; ``default_name.html`` when None
|
|
56
|
+
:param not_before: when the run started (``time.time()``). A report last
|
|
57
|
+
written before then is an earlier run's, left behind by a run that
|
|
58
|
+
wrote none, and is not sent.
|
|
59
|
+
:return: None once the report is sent, else why it was not, in words for
|
|
60
|
+
the run window (no path, address or server reply: those are logged)
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
from je_mail_thunder import SMTPWrapper, get_mail_thunder_os_environ, read_output_content
|
|
64
|
+
from je_mail_thunder.utils.exception.exceptions import MailThunderException
|
|
65
|
+
except ImportError as error:
|
|
66
|
+
pybreeze_logger.error("Cannot send the report without je_mail_thunder: %r", error)
|
|
67
|
+
return "je_mail_thunder is not installed"
|
|
68
|
+
|
|
69
|
+
report_path = html_report_path if html_report_path is not None else DEFAULT_REPORT_PATH
|
|
70
|
+
problem = _report_problem(report_path, not_before)
|
|
71
|
+
if problem is not None:
|
|
72
|
+
pybreeze_logger.error("Report not sent (%s): %s", problem, report_path)
|
|
73
|
+
return problem
|
|
74
|
+
try:
|
|
75
|
+
user = _mail_user(read_output_content, get_mail_thunder_os_environ)
|
|
76
|
+
# je_mail_thunder reads mail_thunder_content.json in the locale's encoding
|
|
77
|
+
# and parses it unguarded: a broken file, or UTF-8 text on a cp950
|
|
78
|
+
# system, raised out of the mail thread
|
|
79
|
+
except (OSError, ValueError, MailThunderException) as error:
|
|
80
|
+
pybreeze_logger.error("The mail settings file could not be read: %r", error)
|
|
81
|
+
return "the mail settings file (mail_thunder_content.json) could not be read"
|
|
82
|
+
if user is None:
|
|
83
|
+
pybreeze_logger.error("Cannot determine mail user for sending report")
|
|
84
|
+
return "no mail user is set"
|
|
85
|
+
try:
|
|
86
|
+
with open(report_path, encoding="utf-8") as file:
|
|
87
|
+
html_string = file.read()
|
|
88
|
+
# The client connects when it is built, and quits when the block ends
|
|
89
|
+
# however it ends.
|
|
90
|
+
with SMTPWrapper() as mail_thunder_smtp:
|
|
91
|
+
mail_thunder_smtp.later_init()
|
|
92
|
+
if not mail_thunder_smtp.login_state:
|
|
93
|
+
raise ITESendHtmlReportException
|
|
94
|
+
message = mail_thunder_smtp.create_message_with_attach(
|
|
95
|
+
html_string,
|
|
96
|
+
{"Subject": "Test Report", "To": user, "From": user},
|
|
97
|
+
report_path, use_html=True)
|
|
98
|
+
mail_thunder_smtp.send_message(message)
|
|
99
|
+
except ITESendHtmlReportException as error:
|
|
100
|
+
pybreeze_logger.error("%r %s", error, send_html_exception_tag)
|
|
101
|
+
return "the mail server login failed"
|
|
102
|
+
# OSError covers the socket and every smtplib error; ValueError a report
|
|
103
|
+
# that is not UTF-8
|
|
104
|
+
except (OSError, ValueError, MailThunderException) as error:
|
|
105
|
+
pybreeze_logger.error("Failed to send report: %r", error)
|
|
106
|
+
return f"sending failed ({type(error).__name__})"
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _report_problem(report_path: str, not_before: float | None) -> str | None:
|
|
111
|
+
"""Why *report_path* is not this run's report to send, or None when it is."""
|
|
112
|
+
name = os.path.basename(report_path)
|
|
113
|
+
try:
|
|
114
|
+
written = os.stat(report_path)
|
|
115
|
+
except OSError:
|
|
116
|
+
return f"the run wrote no {name}"
|
|
117
|
+
if not os.path.isfile(report_path):
|
|
118
|
+
return f"{name} is not a file"
|
|
119
|
+
if not_before is not None and written.st_mtime < not_before - _MTIME_SLACK_SECONDS:
|
|
120
|
+
return f"the run wrote no new {name}; the one there is from an earlier run"
|
|
121
|
+
return None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _mail_user(read_output_content, get_mail_thunder_os_environ) -> str | None:
|
|
125
|
+
"""The address to send to: the saved content file's user, else the environment's."""
|
|
126
|
+
user_info = read_output_content()
|
|
127
|
+
if isinstance(user_info, dict) and user_info.get("user") is not None:
|
|
128
|
+
return user_info["user"]
|
|
129
|
+
return get_mail_thunder_os_environ().get("mail_thunder_user")
|