je-editor 0.0.202__py3-none-any.whl → 0.0.228__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. je_editor/__init__.py +2 -2
  2. je_editor/code_scan/__init__.py +0 -0
  3. je_editor/code_scan/ruff_thread.py +58 -0
  4. je_editor/code_scan/watchdog_implement.py +56 -0
  5. je_editor/code_scan/watchdog_thread.py +78 -0
  6. je_editor/git_client/__init__.py +0 -0
  7. je_editor/git_client/commit_graph.py +77 -0
  8. je_editor/git_client/git_action.py +175 -0
  9. je_editor/git_client/git_cli.py +66 -0
  10. je_editor/pyside_ui/browser/browser_download_window.py +40 -4
  11. je_editor/pyside_ui/browser/browser_serach_lineedit.py +24 -0
  12. je_editor/pyside_ui/browser/browser_view.py +55 -6
  13. je_editor/pyside_ui/browser/browser_widget.py +62 -19
  14. je_editor/pyside_ui/browser/main_browser_widget.py +85 -0
  15. je_editor/pyside_ui/code/auto_save/auto_save_manager.py +33 -1
  16. je_editor/pyside_ui/code/auto_save/auto_save_thread.py +18 -5
  17. je_editor/pyside_ui/code/code_format/pep8_format.py +52 -7
  18. je_editor/pyside_ui/code/code_process/code_exec.py +118 -64
  19. je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py +115 -53
  20. je_editor/pyside_ui/code/running_process_manager.py +18 -0
  21. je_editor/pyside_ui/code/shell_process/shell_exec.py +99 -60
  22. je_editor/pyside_ui/code/syntax/python_syntax.py +44 -9
  23. je_editor/pyside_ui/code/syntax/syntax_setting.py +39 -11
  24. je_editor/pyside_ui/code/textedit_code_result/code_record.py +33 -11
  25. je_editor/pyside_ui/code/variable_inspector/__init__.py +0 -0
  26. je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +172 -0
  27. je_editor/pyside_ui/dialog/ai_dialog/__init__.py +0 -0
  28. je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +71 -0
  29. je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +38 -4
  30. je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py +32 -4
  31. je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +25 -2
  32. je_editor/pyside_ui/dialog/search_ui/search_error_box.py +27 -2
  33. je_editor/pyside_ui/dialog/search_ui/search_text_box.py +28 -3
  34. je_editor/pyside_ui/git_ui/__init__.py +0 -0
  35. je_editor/pyside_ui/git_ui/code_diff_compare/__init__.py +0 -0
  36. je_editor/pyside_ui/git_ui/code_diff_compare/code_diff_viewer_widget.py +90 -0
  37. je_editor/pyside_ui/git_ui/code_diff_compare/line_number_code_viewer.py +141 -0
  38. je_editor/pyside_ui/git_ui/code_diff_compare/multi_file_diff_viewer.py +88 -0
  39. je_editor/pyside_ui/git_ui/code_diff_compare/side_by_side_diff_widget.py +284 -0
  40. je_editor/pyside_ui/git_ui/git_client/__init__.py +0 -0
  41. je_editor/pyside_ui/git_ui/git_client/commit_table.py +65 -0
  42. je_editor/pyside_ui/git_ui/git_client/git_branch_tree_widget.py +156 -0
  43. je_editor/pyside_ui/git_ui/git_client/git_client_gui.py +799 -0
  44. je_editor/pyside_ui/git_ui/git_client/graph_view.py +218 -0
  45. je_editor/pyside_ui/main_ui/ai_widget/__init__.py +0 -0
  46. je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +34 -0
  47. je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +36 -0
  48. je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +147 -0
  49. je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +84 -0
  50. je_editor/pyside_ui/main_ui/console_widget/__init__.py +0 -0
  51. je_editor/pyside_ui/main_ui/console_widget/console_gui.py +162 -0
  52. je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +84 -0
  53. je_editor/pyside_ui/main_ui/dock/destroy_dock.py +32 -1
  54. je_editor/pyside_ui/main_ui/editor/editor_widget.py +113 -23
  55. je_editor/pyside_ui/main_ui/editor/editor_widget_dock.py +33 -6
  56. je_editor/pyside_ui/main_ui/editor/process_input.py +42 -10
  57. je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py +45 -10
  58. je_editor/pyside_ui/main_ui/main_editor.py +189 -49
  59. je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +50 -27
  60. je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +141 -30
  61. je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py +67 -17
  62. je_editor/pyside_ui/main_ui/menu/help_menu/build_help_menu.py +33 -3
  63. je_editor/pyside_ui/main_ui/menu/language_menu/build_language_server.py +39 -0
  64. je_editor/pyside_ui/main_ui/menu/python_env_menu/build_venv_menu.py +102 -40
  65. je_editor/pyside_ui/main_ui/menu/run_menu/build_run_menu.py +53 -6
  66. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_debug_menu.py +47 -3
  67. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_program_menu.py +45 -5
  68. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_shell_menu.py +41 -3
  69. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py +21 -0
  70. je_editor/pyside_ui/main_ui/menu/set_menu_bar.py +37 -11
  71. je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py +42 -6
  72. je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +202 -27
  73. je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py +66 -0
  74. je_editor/pyside_ui/main_ui/save_settings/setting_utils.py +18 -1
  75. je_editor/pyside_ui/main_ui/save_settings/user_color_setting_file.py +32 -2
  76. je_editor/pyside_ui/main_ui/save_settings/user_setting_file.py +37 -10
  77. je_editor/pyside_ui/main_ui/system_tray/extend_system_tray.py +39 -0
  78. je_editor/start_editor.py +25 -0
  79. je_editor/utils/encodings/python_encodings.py +100 -97
  80. je_editor/utils/exception/exception_tags.py +11 -11
  81. je_editor/utils/file/open/open_file.py +35 -19
  82. je_editor/utils/file/save/save_file.py +34 -13
  83. je_editor/utils/json/json_file.py +29 -14
  84. je_editor/utils/json_format/json_process.py +32 -1
  85. je_editor/utils/logging/loggin_instance.py +37 -7
  86. je_editor/utils/multi_language/english.py +102 -6
  87. je_editor/utils/multi_language/multi_language_wrapper.py +28 -3
  88. je_editor/utils/multi_language/traditional_chinese.py +101 -10
  89. je_editor/utils/redirect_manager/redirect_manager_class.py +49 -11
  90. je_editor/utils/venv_check/check_venv.py +37 -14
  91. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/METADATA +12 -6
  92. je_editor-0.0.228.dist-info/RECORD +140 -0
  93. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/WHEEL +1 -1
  94. je_editor-0.0.202.dist-info/RECORD +0 -108
  95. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info/licenses}/LICENSE +0 -0
  96. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/top_level.txt +0 -0
@@ -1,27 +1,57 @@
1
1
  import logging
2
2
  from logging.handlers import RotatingFileHandler
3
3
 
4
+ # 設定 root logger 的最低層級為 DEBUG
5
+ # Set the root logger level to DEBUG
4
6
  logging.root.setLevel(logging.DEBUG)
7
+
8
+ # 建立一個名為 "JEditor" 的 logger
9
+ # Create a logger named "JEditor"
5
10
  jeditor_logger = logging.getLogger("JEditor")
11
+
12
+ # 設定 JEditor logger 的層級為 WARNING (只會輸出 WARNING 以上的訊息)
13
+ # Set the JEditor logger level to WARNING (only WARNING and above will be logged)
14
+ jeditor_logger.setLevel(logging.WARNING)
15
+
16
+ # 定義日誌格式:時間 | logger 名稱 | 等級 | 訊息
17
+ # Define log format: time | logger name | level | message
6
18
  formatter = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(message)s')
7
19
 
8
20
 
9
21
  class JEditorLoggingHandler(RotatingFileHandler):
22
+ """
23
+ 自訂的 Logging Handler,繼承自 RotatingFileHandler
24
+ Custom Logging Handler, inherits from RotatingFileHandler
10
25
 
11
- # redirect logging stderr output to queue
26
+ 功能:
27
+ - 將日誌輸出到檔案 (支援檔案大小輪替)
28
+ - 預設檔名為 JEditor.log
29
+ """
30
+
31
+ # redirect logging stderr output to queue (註解說明,但目前未實作)
32
+ # 註解提到要將 stderr 輸出導向 queue,但目前程式碼僅繼承 RotatingFileHandler
12
33
 
13
34
  def __init__(self, filename: str = "JEditor.log", mode="w",
14
- maxBytes:int=1073741824, backupCount:int=0):
35
+ maxBytes: int = 1073741824, backupCount: int = 0):
36
+ """
37
+ :param filename: 日誌檔案名稱 / log file name
38
+ :param mode: 檔案開啟模式 (預設 w 覆寫) / file open mode (default "w" overwrite)
39
+ :param maxBytes: 單一檔案最大大小 (預設 1GB) / max file size (default 1GB)
40
+ :param backupCount: 保留的備份檔案數量 / number of backup files to keep
41
+ """
15
42
  super().__init__(filename=filename, mode=mode, maxBytes=maxBytes, backupCount=backupCount)
16
- self.formatter = formatter
17
- self.setLevel(logging.DEBUG)
43
+ self.formatter = formatter # 設定日誌格式 / set log formatter
44
+ self.setLevel(logging.DEBUG) # 設定 handler 層級為 DEBUG / set handler level to DEBUG
18
45
 
19
46
  def emit(self, record: logging.LogRecord) -> None:
47
+ """
48
+ 實際輸出日誌的方法,這裡直接呼叫父類別的 emit
49
+ Method to emit log records, here just call parent emit
50
+ """
20
51
  super().emit(record)
21
52
 
22
53
 
23
- # File handler
54
+ # 建立檔案處理器並加入到 JEditor logger
55
+ # Create file handler and add it to JEditor logger
24
56
  file_handler = JEditorLoggingHandler()
25
57
  jeditor_logger.addHandler(file_handler)
26
-
27
-
@@ -14,10 +14,13 @@ english_word_dict = {
14
14
  "browser_reload_button": "Reload",
15
15
  "browser_search_button": "Search",
16
16
  # Dialog
17
- "dialog_create_file": "Create File",
18
- "dialog_input_file_name": "Please enter right file name",
19
- "dialog_search_next": "Search next",
20
- "dialog_search_back": "Search back",
17
+ "create_file_dialog_pushbutton": "Create File",
18
+ "input_file_name_dialog_pushbutton": "Please enter right file name",
19
+ "search_next_dialog_pushbutton": "Search next",
20
+ "search_back_dialog_pushbutton": "Search back",
21
+ "search_box_dialog_title": "Search Text",
22
+ "add_ai_model_title": "Please fill in AI model information",
23
+ "add_ai_model_pushbutton": "Add AI Model",
21
24
  # Editor
22
25
  "editor_code_result": "Code result",
23
26
  "editor_format_check": "Format checker",
@@ -79,11 +82,11 @@ english_word_dict = {
79
82
  "run_menu_run_help_tip": """
80
83
  If you are unable to run a Python program, please make sure you are have python interpreter,
81
84
  And if python conflict please choose another interpreter.
82
- """,
85
+ """,
83
86
  "run_menu_shell_run_tip": """
84
87
  When executing a shell command, if you encounter a decoding error,
85
88
  please make sure that the current encoding is consistent with the default encoding of the system shell.
86
- """,
89
+ """,
87
90
  # Debugger and menu
88
91
  "editor_debugger_input_title_label": "Debugger",
89
92
  "show_debugger_input": "Show debugger input",
@@ -106,6 +109,12 @@ please make sure that the current encoding is consistent with the default encodi
106
109
  "tab_menu_web_tab_name": "WEB Browser",
107
110
  "tab_menu_stackoverflow_tab_name": "Stackoverflow",
108
111
  "tab_menu_ipython_tab_name": "IPython(Jupyter)",
112
+ "tab_menu_chat_ui_tab_name": "ChatUI",
113
+ "tab_menu_git_client_tab_name": "Git Client",
114
+ "tab_menu_git_branch_tree_view_tab_name": "Git BranchTreeViewer",
115
+ "tab_menu_variable_inspector_tab_name": "Variable Inspector",
116
+ "tab_menu_console_widget_tab_name": "Console Widget",
117
+ "tab_code_diff_viewer_tab_name": "Code Diff Viewer",
109
118
  # Text Menu
110
119
  "text_menu_label": "Text",
111
120
  "text_menu_label_font": "Font",
@@ -122,4 +131,91 @@ please make sure that the current encoding is consistent with the default encodi
122
131
  "language_menu_bar_please_restart_messagebox": "Please restart",
123
132
  # Qtconsole
124
133
  "please_install_qtcontsole_label": "Please python -m pip install qtconsole first.",
134
+ # Chat UI
135
+ "font_size": "Font Size",
136
+ "set_ai_model_waring_title": "Can not set AI Model",
137
+ "set_ai_model_waring_text": "Please check [ai_base_url, ai_api_key, chat_model]",
138
+ "call_ai_model_error_title": "Can't connect to AI Model",
139
+ "call_ai_model_error_text": "Please check [ai_base_url, ai_api_key, chat_model]",
140
+ "chat_ui_dock_label": "Chat UI",
141
+ "chat_ui_set_ai_button": "Set AI setting",
142
+ "chat_ui_load_ai_button": "Load AI setting",
143
+ "chat_ui_call_ai_model_button": "Send prompt",
144
+ "base_url_label": "AI server URL",
145
+ "api_key_label": "AI server API Key",
146
+ "ai_model_label": "AI Model",
147
+ "load_ai_messagebox_title": "Load complete",
148
+ "load_ai_messagebox_text": "Load complete",
149
+ # gitGUI
150
+ "label_repo_initial": "Repo: -",
151
+ "btn_open_repo": "Open Repo",
152
+ "btn_switch_branch": "Switch",
153
+ "btn_pull": "Pull",
154
+ "btn_push": "Push",
155
+ "btn_clone_remote": "Clone Remote Repo",
156
+ "label_remote": "Remote:",
157
+ "label_branch": "Branch:",
158
+ "placeholder_commit_message": "Commit message...",
159
+ "btn_stage_all": "Stage All",
160
+ "btn_commit": "Commit",
161
+ "label_message": "Message:",
162
+ "dialog_choose_repo": "Choose Git Repo",
163
+ "err_open_repo": "Failed to open repository",
164
+ "default_remote": "origin",
165
+ "err_load_branches": "Failed to load branches",
166
+ "err_load_commits": "Failed to load commits",
167
+ "err_checkout": "Checkout Failure",
168
+ "info_checkout_title": "Checkout",
169
+ "info_checkout_msg": "Already check out to {branch}",
170
+ "err_read_diff": "Failed to read diff",
171
+ "err_stage": "Stage failed",
172
+ "info_stage_title": "Stage",
173
+ "info_stage_msg": "Executed git add -A",
174
+ "err_commit": "Commit failed",
175
+ "info_commit_title": "Commit",
176
+ "info_commit_msg": "Commit created",
177
+ "err_pull": "Pull failed",
178
+ "info_pull_title": "Pull",
179
+ "err_push": "Push failed",
180
+ "info_push_title": "Push",
181
+ "dialog_clone_title": "Clone Remote Repo",
182
+ "dialog_clone_prompt": "Enter Git repository URL:",
183
+ "dialog_select_folder": "Select Local Folder",
184
+ "info_clone_success_title": "Clone Successful",
185
+ "info_clone_success_msg": "Repository cloned to:\\n{repo_path}",
186
+ "err_clone_failed_title": "Clone Failed",
187
+ # Git graph
188
+ "git_graph_title": "Git Branch Viewer",
189
+ "git_graph_menu_file": "File",
190
+ "git_graph_menu_open_repo": "Open Repository...",
191
+ "git_graph_menu_refresh": "Refresh",
192
+ "git_graph_menu_exit": "Exit",
193
+ "git_graph_status_loading": "Loading repository...",
194
+ "git_graph_status_ready": "Ready",
195
+ "git_graph_status_repo_set": "Repository: {path}",
196
+ "git_graph_error_not_git": "Selected path is not a Git repository.",
197
+ "git_graph_error_exec_failed": "Git command failed.",
198
+ "git_graph_tooltip_commit": "Commit: {short}\nAuthor: {author}\nDate: {date}\nMessage: {msg}",
199
+ "git_graph_toolbar_open": "Open",
200
+ "git_graph_toolbar_refresh": "Refresh",
201
+ # Variable inspector
202
+ "variable_inspector_title": "Variable Inspector",
203
+ "variable_inspector_search": "Search Variables:",
204
+ "variable_inspector_var_name": "Variable Name",
205
+ "variable_inspector_var_type": "Type",
206
+ "variable_inspector_var_value": "Value",
207
+ # Dynamic Console
208
+ "dynamic_console_title": "Dynamic Console",
209
+ "dynamic_console_run": "Run",
210
+ "dynamic_console_stop": "Stop",
211
+ "dynamic_console_clear": "Clear",
212
+ "dynamic_console_cwd": "CWD",
213
+ "dynamic_console_shell": "Shell",
214
+ "dynamic_console_prompt": "❯ ",
215
+ "dynamic_console_running": "[running]",
216
+ "dynamic_console_ready": "[ready]",
217
+ "dynamic_console_process_running": "Process is running; stop it first",
218
+ "dynamic_console_done": "[done] exit={code}, status={status}",
219
+ "dynamic_console_system_prefix": "[system] ",
220
+ # Code diff viewer
125
221
  }
@@ -4,26 +4,51 @@ from je_editor.utils.multi_language.traditional_chinese import traditional_chine
4
4
 
5
5
 
6
6
  class LanguageWrapper(object):
7
+ """
8
+ 功能說明 (Function Description):
9
+ - 提供一個語言包裝器,用來管理目前使用的語言與對應的字典。
10
+ - A language wrapper to manage the current language and its corresponding dictionary.
11
+ """
7
12
 
8
- def __init__(
9
- self
10
- ):
13
+ def __init__(self):
14
+ # 初始化時記錄日誌
15
+ # Log initialization
11
16
  jeditor_logger.info("Init LanguageWrapper")
17
+
18
+ # 預設語言為 English
19
+ # Default language is English
12
20
  self.language: str = "English"
21
+
22
+ # 可選語言字典對照表
23
+ # Mapping of available languages to their word dictionaries
13
24
  self.choose_language_dict = {
14
25
  "English": english_word_dict,
15
26
  "Traditional_Chinese": traditional_chinese_word_dict
16
27
  }
28
+
29
+ # 根據目前語言選擇對應字典
30
+ # Select the dictionary based on current language
17
31
  self.language_word_dict: dict = self.choose_language_dict.get(self.language)
18
32
 
19
33
  def reset_language(self, language) -> None:
34
+ """
35
+ 重設語言 (Reset the language)
36
+ :param language: "English" 或 "Traditional_Chinese"
37
+ """
20
38
  jeditor_logger.info(f"LanguageWrapper reset_language language: {language}")
39
+
40
+ # 檢查輸入是否為支援的語言
41
+ # Check if the input language is supported
21
42
  if language in [
22
43
  "English",
23
44
  "Traditional_Chinese"
24
45
  ]:
46
+ # 更新語言與對應字典
47
+ # Update language and corresponding dictionary
25
48
  self.language = language
26
49
  self.language_word_dict = self.choose_language_dict.get(self.language)
27
50
 
28
51
 
52
+ # 建立一個全域的 LanguageWrapper 實例
53
+ # Create a global instance of LanguageWrapper
29
54
  language_wrapper = LanguageWrapper()
@@ -14,10 +14,13 @@ traditional_chinese_word_dict = {
14
14
  "browser_reload_button": "重新載入",
15
15
  "browser_search_button": "搜尋",
16
16
  # Dialog
17
- "dialog_create_file": "建立檔案",
18
- "dialog_input_file_name": "請輸入正確格式的檔案名稱",
19
- "dialog_search_next": "搜尋下一個",
20
- "dialog_search_back": "搜尋上一個",
17
+ "create_file_dialog_pushbutton": "建立檔案",
18
+ "input_file_name_dialog_pushbutton": "請輸入正確格式的檔案名稱",
19
+ "search_next_dialog_pushbutton": "搜尋下一個",
20
+ "search_back_dialog_pushbutton": "搜尋上一個",
21
+ "search_box_dialog_title": "搜尋文字",
22
+ "add_ai_model_title": "請填寫 AI 模型資訊",
23
+ "add_ai_model_pushbutton": "新增 AI 模型",
21
24
  # Editor
22
25
  "editor_code_result": "程式運行結果",
23
26
  "editor_format_check": "程式格式檢查",
@@ -76,12 +79,8 @@ traditional_chinese_word_dict = {
76
79
  "run_menu_shell_help_label": "終端運行幫助",
77
80
  "please_stop_current_running_shell": "請先關閉目前正在運行的終端",
78
81
  "please_stop_current_running_program": "請先關閉目前正在運行的程式",
79
- "run_menu_run_help_tip": """
80
- 如果不能運行程式, 請檢查是否有 Python 直譯器,如有 Python 衝突請選擇其他直譯器.
81
- """,
82
- "run_menu_shell_run_tip": """
83
- 如果有亂碼等問題請重新選擇編碼至與系統 Shell 編碼相同
84
- """,
82
+ "run_menu_run_help_tip": "如果不能運行程式, 請檢查是否有 Python 直譯器,如有 Python 衝突請選擇其他直譯器.",
83
+ "run_menu_shell_run_tip": "如果有亂碼等問題請重新選擇編碼至與系統 Shell 編碼相同",
85
84
  # Debugger
86
85
  "editor_debugger_input_title_label": "除錯器",
87
86
  "show_debugger_input": "開啟除錯輸入",
@@ -104,6 +103,12 @@ traditional_chinese_word_dict = {
104
103
  "tab_menu_web_tab_name": "瀏覽器",
105
104
  "tab_menu_stackoverflow_tab_name": "Stackoverflow",
106
105
  "tab_menu_ipython_tab_name": "IPython(Jupyter)",
106
+ "tab_menu_chat_ui_tab_name": "ChatUI",
107
+ "tab_menu_git_client_tab_name": "Git History",
108
+ "tab_menu_git_branch_tree_view_tab_name": "Git BranchTreeViewer",
109
+ "tab_menu_variable_inspector_tab_name": "Variable Inspector",
110
+ "tab_menu_console_widget_tab_name": "ConsoleWidget",
111
+ "tab_code_diff_viewer_tab_name": "Code Diff Viewer",
107
112
  # Text Menu
108
113
  "text_menu_label": "文字",
109
114
  "text_menu_label_font": "字體",
@@ -120,4 +125,90 @@ traditional_chinese_word_dict = {
120
125
  "language_menu_bar_please_restart_messagebox": "請重啟以應用更改",
121
126
  # Qtconsole
122
127
  "please_install_qtcontsole_label": "請先 python -m pip install qtconsole",
128
+ # Chat UI
129
+ "font_size": "字體大小",
130
+ "set_ai_model_waring_title": "無法設置 AI Model",
131
+ "set_ai_model_warring_text": "請檢查 [ai_base_url, ai_api_key, chat_model]",
132
+ "call_ai_model_error_title": "無法連線到 AI 模型",
133
+ "call_ai_model_error_text": "請檢查 [ai_base_url, ai_api_key, chat_model]",
134
+ "chat_ui_dock_label": "聊天 UI",
135
+ "chat_ui_set_ai_button": "設定 AI 設定",
136
+ "chat_ui_load_ai_button": "載入 AI 設定",
137
+ "chat_ui_call_ai_model_button": "傳送 prompt",
138
+ "base_url_label": "AI 伺服器 URL",
139
+ "api_key_label": "AI 伺服器 API Key",
140
+ "ai_model_label": "AI Model",
141
+ "load_ai_messagebox_title": "載入成功",
142
+ "load_ai_messagebox_text": "載入成功",
143
+ # gitGUI
144
+ "label_repo_initial": "儲存庫: -",
145
+ "btn_open_repo": "開啟儲存庫",
146
+ "btn_switch_branch": "切換",
147
+ "btn_pull": "拉取",
148
+ "btn_push": "推送",
149
+ "btn_clone_remote": "複製遠端儲存庫",
150
+ "label_remote": "遠端:",
151
+ "label_branch": "分支:",
152
+ "placeholder_commit_message": "提交訊息...",
153
+ "btn_stage_all": "暫存全部",
154
+ "btn_commit": "提交",
155
+ "label_message": "訊息:",
156
+ "dialog_choose_repo": "選擇 Git 儲存庫",
157
+ "err_open_repo": "開啟儲存庫失敗",
158
+ "default_remote": "origin",
159
+ "err_load_branches": "載入分支失敗",
160
+ "err_load_commits": "載入提交記錄失敗",
161
+ "err_checkout": "切換分支失敗",
162
+ "info_checkout_title": "切換分支",
163
+ "info_checkout_msg": "已切換至",
164
+ "err_read_diff": "讀取差異失敗",
165
+ "err_stage": "暫存失敗",
166
+ "info_stage_title": "暫存",
167
+ "info_stage_msg": "已執行 git add -A",
168
+ "err_commit": "提交失敗",
169
+ "info_commit_title": "提交",
170
+ "info_commit_msg": "已建立提交",
171
+ "err_pull": "拉取失敗",
172
+ "info_pull_title": "拉取",
173
+ "err_push": "推送失敗",
174
+ "info_push_title": "推送",
175
+ "dialog_clone_title": "複製遠端儲存庫",
176
+ "dialog_clone_prompt": "輸入 Git 儲存庫 URL:",
177
+ "dialog_select_folder": "選擇本機資料夾",
178
+ "info_clone_success_title": "複製成功",
179
+ "info_clone_success_msg": "儲存庫已複製至:\\n",
180
+ "err_clone_failed_title": "複製失敗",
181
+ # Git 圖形
182
+ "git_graph_title": "Git 分支檢視器",
183
+ "git_graph_menu_file": "檔案",
184
+ "git_graph_menu_open_repo": "開啟儲存庫...",
185
+ "git_graph_menu_refresh": "重新整理",
186
+ "git_graph_menu_exit": "退出",
187
+ "git_graph_status_loading": "正在載入儲存庫...",
188
+ "git_graph_status_ready": "就緒",
189
+ "git_graph_status_repo_set": "儲存庫:{path}",
190
+ "git_graph_error_not_git": "所選路徑不是 Git 儲存庫。",
191
+ "git_graph_error_exec_failed": "Git 指令執行失敗。",
192
+ "git_graph_tooltip_commit": "提交:{short}\n作者:{author}\n日期:{date}\n訊息:{msg}",
193
+ "git_graph_toolbar_open": "開啟",
194
+ "git_graph_toolbar_refresh": "重新整理",
195
+ # Variable inspector
196
+ "variable_inspector_title": "變數查看器",
197
+ "variable_inspector_search": "搜尋變數:",
198
+ "variable_inspector_var_name": "變數名稱",
199
+ "variable_inspector_var_type": "型別",
200
+ "variable_inspector_var_value": "值",
201
+ # Dynamic Console
202
+ "dynamic_console_title": "動態主控台",
203
+ "dynamic_console_run": "執行",
204
+ "dynamic_console_stop": "停止",
205
+ "dynamic_console_clear": "清除",
206
+ "dynamic_console_cwd": "工作目錄",
207
+ "dynamic_console_shell": "Shell",
208
+ "dynamic_console_prompt": "❯ ",
209
+ "dynamic_console_running": "[執行中]",
210
+ "dynamic_console_ready": "[就緒]",
211
+ "dynamic_console_process_running": "程序正在執行;請先停止",
212
+ "dynamic_console_done": "[完成] 退出碼={code}, 狀態={status}",
213
+ "dynamic_console_system_prefix": "[系統] ",
123
214
  }
@@ -6,54 +6,90 @@ from je_editor.utils.logging.loggin_instance import jeditor_logger
6
6
 
7
7
 
8
8
  class RedirectStdOut(logging.Handler):
9
-
10
- # redirect logging std output to queue
9
+ """
10
+ 功能說明 (Function Description):
11
+ - 將標準輸出 (stdout) 重導向到 queue
12
+ - Redirect standard output (stdout) to a queue
13
+ """
11
14
 
12
15
  def __init__(self):
13
16
  super().__init__()
14
17
 
15
18
  def write(self, content_to_write) -> None:
19
+ # 將輸出內容放入 RedirectManager 的 stdout queue
20
+ # Put output content into RedirectManager's stdout queue
16
21
  redirect_manager_instance.std_out_queue.put(content_to_write)
17
22
 
18
23
  def emit(self, record: logging.LogRecord) -> None:
24
+ # 將 logging 訊息格式化後放入 stdout queue
25
+ # Put formatted logging record into stdout queue
19
26
  redirect_manager_instance.std_out_queue.put(self.format(record))
20
27
 
21
28
 
22
29
  class RedirectStdErr(logging.Handler):
23
-
24
- # redirect logging stderr output to queue
30
+ """
31
+ 功能說明 (Function Description):
32
+ - 將標準錯誤輸出 (stderr) 重導向到 queue
33
+ - Redirect standard error (stderr) to a queue
34
+ """
25
35
 
26
36
  def __init__(self):
27
37
  super().__init__()
28
38
 
29
39
  def write(self, content_to_write) -> None:
40
+ # 將錯誤輸出內容放入 RedirectManager 的 stderr queue
41
+ # Put error output content into RedirectManager's stderr queue
30
42
  redirect_manager_instance.std_err_queue.put(content_to_write)
31
43
 
32
44
  def emit(self, record: logging.LogRecord) -> None:
45
+ # 將 logging 訊息格式化後放入 stderr queue
46
+ # Put formatted logging record into stderr queue
33
47
  redirect_manager_instance.std_err_queue.put(self.format(record))
34
48
 
35
49
 
36
50
  class RedirectManager(object):
37
- # Redirect all output to queue
51
+ """
52
+ 功能說明 (Function Description):
53
+ - 管理 stdout 與 stderr 的重導向
54
+ - 提供 set_redirect 與 restore_std 方法
55
+ - Manage redirection of stdout and stderr
56
+ - Provides set_redirect and restore_std methods
57
+ """
58
+
38
59
  def __init__(self):
39
60
  jeditor_logger.info("Init RedirectManager")
61
+ # 建立 stdout 與 stderr 的 queue
62
+ # Create queues for stdout and stderr
40
63
  self.std_err_queue = queue.Queue()
41
64
  self.std_out_queue = queue.Queue()
42
65
 
43
66
  @staticmethod
44
67
  def set_redirect() -> None:
45
68
  """
46
- :return: None
69
+ 啟用重導向
70
+ Redirect stdout and stderr to queues
47
71
  """
48
72
  jeditor_logger.info("RedirectManager set_redirect")
49
73
  redirect_out = RedirectStdOut()
50
74
  redirect_err = RedirectStdErr()
75
+
76
+ # 將 sys.stdout / sys.stderr 指向自訂 handler
77
+ # Redirect sys.stdout / sys.stderr to custom handlers
51
78
  sys.stdout = redirect_out
52
79
  sys.stderr = redirect_err
53
- default_logger = logging.getLogger("RedirectManager")
80
+
81
+ # 建立一個 logger 並綁定 stderr handler
82
+ # Create a logger and bind stderr handler
83
+ default_logger = logging.getLogger("JEditor_RedirectManager")
54
84
  default_logger.addHandler(redirect_err)
55
- skip_logger_list = ["JEditor", "FrontEngine",
56
- "AutomationIDE", "TestPioneer"]
85
+
86
+ # 過濾掉不需要重導向的 logger
87
+ # Skip specific loggers from being redirected
88
+ skip_logger_list = [
89
+ "JEditor", "FrontEngine",
90
+ "AutomationIDE", "TestPioneer",
91
+ "langchain", "langchain_core", "langchain_openai"
92
+ ]
57
93
  for name in logging.root.manager.loggerDict.keys():
58
94
  if name in skip_logger_list:
59
95
  continue
@@ -63,12 +99,14 @@ class RedirectManager(object):
63
99
  @staticmethod
64
100
  def restore_std() -> None:
65
101
  """
66
- reset redirect
67
- :return: None
102
+ 重設 stdout 與 stderr
103
+ Restore stdout and stderr to default
68
104
  """
69
105
  jeditor_logger.info("RedirectManager restore_std")
70
106
  sys.stdout = sys.__stdout__
71
107
  sys.stderr = sys.__stderr__
72
108
 
73
109
 
110
+ # 建立全域 RedirectManager 實例
111
+ # Create a global instance of RedirectManager
74
112
  redirect_manager_instance = RedirectManager()
@@ -1,28 +1,51 @@
1
+ # 匯入自訂錯誤訊息與例外類別
2
+ # Import custom error messages and exception class
3
+
1
4
  import shutil
2
5
  from pathlib import Path
3
6
 
7
+ # 匯入自訂錯誤訊息與例外類別
8
+ # Import custom error messages and exception class
4
9
  from je_editor.utils.exception.exception_tags import compiler_not_found_error
5
10
  from je_editor.utils.exception.exceptions import JEditorExecException
6
11
  from je_editor.utils.logging.loggin_instance import jeditor_logger
7
12
 
8
13
 
9
14
  def check_and_choose_venv(venv_path: Path) -> str:
15
+ """
16
+ 功能說明 (Function Description):
17
+ 檢查虛擬環境 (venv) 路徑,並嘗試尋找可用的 Python 編譯器。
18
+ Check the virtual environment (venv) path and try to find a usable Python interpreter.
19
+
20
+ :param venv_path: 虛擬環境的路徑 / path to the virtual environment
21
+ :return: Python 編譯器的完整路徑 / full path to the Python interpreter
22
+ :raise JEditorExecException: 若找不到 Python 編譯器 / if no Python interpreter is found
23
+ """
24
+
10
25
  jeditor_logger.info(f"check_venv.py check_and_choose_venv venv_path: {venv_path}")
11
- compiler_path = None
26
+
27
+ # 如果 venv_path 是資料夾且存在
28
+ # If venv_path is a directory and exists
12
29
  if venv_path.is_dir() and venv_path.exists():
13
- compiler_path = shutil.which(
14
- cmd="python3",
15
- path=str(venv_path)
16
- )
17
- if compiler_path is None:
18
- compiler_path = shutil.which(
19
- cmd="python",
20
- path=str(venv_path)
21
- )
22
- else:
23
- compiler_path = shutil.which(cmd="python")
24
- if compiler_path is None:
25
- compiler_path = shutil.which(cmd="python")
30
+ # 先嘗試在該路徑下尋找 python3
31
+ # Try to find python3 in the given path
32
+ compiler_path = shutil.which("python3", path=str(venv_path))
33
+ if compiler_path:
34
+ return compiler_path
35
+
36
+ # 如果找不到 python3,再找 python
37
+ # If python3 not found, try python
38
+ compiler_path = shutil.which("python", path=str(venv_path))
39
+ if compiler_path:
40
+ return compiler_path
41
+
42
+ # 如果 venv_path 無效或都找不到,最後再嘗試系統預設的 python3 或 python
43
+ # If venv_path is invalid or no interpreter found, try system default python3 or python
44
+ compiler_path = shutil.which("python3") or shutil.which("python")
45
+
46
+ # 如果還是找不到,拋出例外
47
+ # If still not found, raise exception
26
48
  if compiler_path is None:
27
49
  raise JEditorExecException(compiler_not_found_error)
50
+
28
51
  return compiler_path
@@ -1,29 +1,35 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: je_editor
3
- Version: 0.0.202
3
+ Version: 0.0.228
4
4
  Summary: JEditor is basic but powerful editor include GPT
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
- License: MIT
7
6
  Project-URL: Homepage, https://github.com/JE-Chen/je_editor
8
7
  Project-URL: Documentation, https://je-editor.readthedocs.io/en/latest/
9
8
  Project-URL: Code, https://github.com/JE-Chen/je_editor
10
- Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
11
10
  Classifier: Development Status :: 2 - Pre-Alpha
12
11
  Classifier: Environment :: Win32 (MS Windows)
13
12
  Classifier: Environment :: MacOS X
14
13
  Classifier: Environment :: X11 Applications
15
14
  Classifier: License :: OSI Approved :: MIT License
16
15
  Classifier: Operating System :: OS Independent
17
- Requires-Python: >=3.9
16
+ Requires-Python: >=3.10
18
17
  Description-Content-Type: text/markdown
19
18
  License-File: LICENSE
20
- Requires-Dist: PySide6==6.8.2.1
19
+ Requires-Dist: PySide6==6.10.0
21
20
  Requires-Dist: qt-material
22
21
  Requires-Dist: yapf
23
22
  Requires-Dist: frontengine
24
23
  Requires-Dist: pycodestyle
25
24
  Requires-Dist: jedi
26
25
  Requires-Dist: qtconsole
26
+ Requires-Dist: langchain_openai==1.0.2
27
+ Requires-Dist: langchain==1.0.3
28
+ Requires-Dist: pydantic
29
+ Requires-Dist: watchdog
30
+ Requires-Dist: ruff
31
+ Requires-Dist: gitpython
32
+ Dynamic: license-file
27
33
 
28
34
  # je_editor
29
35