je-editor 0.0.222__py3-none-any.whl → 0.0.224__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of je-editor might be problematic. Click here for more details.

Files changed (75) hide show
  1. je_editor/__init__.py +2 -2
  2. je_editor/git_client/commit_graph.py +7 -7
  3. je_editor/git_client/git_action.py +0 -7
  4. je_editor/pyside_ui/browser/browser_view.py +16 -4
  5. je_editor/pyside_ui/browser/browser_widget.py +43 -29
  6. je_editor/pyside_ui/browser/main_browser_widget.py +85 -0
  7. je_editor/pyside_ui/code/auto_save/auto_save_manager.py +34 -2
  8. je_editor/pyside_ui/code/auto_save/auto_save_thread.py +19 -6
  9. je_editor/pyside_ui/code/code_format/pep8_format.py +53 -9
  10. je_editor/pyside_ui/code/code_process/code_exec.py +88 -52
  11. je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py +116 -55
  12. je_editor/pyside_ui/code/running_process_manager.py +19 -1
  13. je_editor/pyside_ui/code/shell_process/shell_exec.py +71 -48
  14. je_editor/pyside_ui/code/syntax/python_syntax.py +45 -10
  15. je_editor/pyside_ui/code/syntax/syntax_setting.py +40 -12
  16. je_editor/pyside_ui/code/textedit_code_result/code_record.py +34 -12
  17. je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +53 -6
  18. je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +30 -3
  19. je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +35 -2
  20. je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py +33 -5
  21. je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +25 -3
  22. je_editor/pyside_ui/dialog/search_ui/search_error_box.py +26 -1
  23. je_editor/pyside_ui/dialog/search_ui/search_text_box.py +26 -1
  24. je_editor/pyside_ui/git_ui/code_diff_compare/code_diff_viewer_widget.py +11 -11
  25. je_editor/pyside_ui/git_ui/git_client/commit_table.py +46 -8
  26. je_editor/pyside_ui/git_ui/git_client/git_branch_tree_widget.py +49 -15
  27. je_editor/pyside_ui/git_ui/git_client/git_client_gui.py +81 -16
  28. je_editor/pyside_ui/git_ui/git_client/graph_view.py +64 -20
  29. je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +20 -5
  30. je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +20 -1
  31. je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +56 -41
  32. je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +45 -6
  33. je_editor/pyside_ui/main_ui/console_widget/console_gui.py +44 -12
  34. je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +34 -13
  35. je_editor/pyside_ui/main_ui/dock/destroy_dock.py +33 -2
  36. je_editor/pyside_ui/main_ui/editor/editor_widget.py +104 -20
  37. je_editor/pyside_ui/main_ui/editor/editor_widget_dock.py +34 -7
  38. je_editor/pyside_ui/main_ui/editor/process_input.py +38 -11
  39. je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py +46 -11
  40. je_editor/pyside_ui/main_ui/main_editor.py +180 -42
  41. je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +51 -28
  42. je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +83 -36
  43. je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py +70 -17
  44. je_editor/pyside_ui/main_ui/menu/help_menu/build_help_menu.py +35 -4
  45. je_editor/pyside_ui/main_ui/menu/language_menu/build_language_server.py +41 -1
  46. je_editor/pyside_ui/main_ui/menu/python_env_menu/build_venv_menu.py +100 -42
  47. je_editor/pyside_ui/main_ui/menu/run_menu/build_run_menu.py +57 -7
  48. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_debug_menu.py +50 -4
  49. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_program_menu.py +52 -6
  50. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_shell_menu.py +44 -4
  51. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py +23 -1
  52. je_editor/pyside_ui/main_ui/menu/set_menu_bar.py +37 -12
  53. je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py +44 -7
  54. je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +127 -44
  55. je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py +65 -1
  56. je_editor/pyside_ui/main_ui/save_settings/setting_utils.py +18 -1
  57. je_editor/pyside_ui/main_ui/save_settings/user_color_setting_file.py +33 -3
  58. je_editor/pyside_ui/main_ui/save_settings/user_setting_file.py +38 -11
  59. je_editor/pyside_ui/main_ui/system_tray/extend_system_tray.py +39 -2
  60. je_editor/start_editor.py +26 -1
  61. je_editor/utils/encodings/python_encodings.py +101 -98
  62. je_editor/utils/file/open/open_file.py +36 -19
  63. je_editor/utils/file/save/save_file.py +35 -14
  64. je_editor/utils/json/json_file.py +29 -14
  65. je_editor/utils/json_format/json_process.py +33 -2
  66. je_editor/utils/logging/loggin_instance.py +38 -8
  67. je_editor/utils/multi_language/multi_language_wrapper.py +29 -4
  68. je_editor/utils/redirect_manager/redirect_manager_class.py +49 -11
  69. je_editor/utils/venv_check/check_venv.py +45 -15
  70. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/METADATA +1 -1
  71. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/RECORD +74 -74
  72. je_editor/git_client/github.py +0 -81
  73. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/WHEEL +0 -0
  74. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/licenses/LICENSE +0 -0
  75. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/top_level.txt +0 -0
@@ -2,34 +2,51 @@ import typing
2
2
  from pathlib import Path
3
3
  from threading import Lock
4
4
 
5
+ # 匯入自訂例外與日誌工具
6
+ # Import custom exception and logging utility
5
7
  from je_editor.utils.exception.exceptions import JEditorOpenFileException
6
8
  from je_editor.utils.logging.loggin_instance import jeditor_logger
7
9
 
8
10
 
9
- def read_file(file_path: str) -> typing.List[typing.Union[str, str]]:
11
+ def read_file(file_path: str) -> list[Path | str] | None:
10
12
  """
11
- use to check file is exist and open
12
- :param file_path: the file we want to read its whole file path
13
- :return: read's file and file content
14
- try
15
- lock thread
16
- find file is exist ? and is file ?
17
- if both is true
18
- try to open it and read
19
- return file and content
20
- finally
21
- release lock
13
+ 功能說明 (Function Description):
14
+ 用來檢查檔案是否存在並嘗試開啟,讀取其內容。
15
+ Used to check if a file exists and open it to read its content.
16
+
17
+ :param file_path: 檔案完整路徑 / the full path of the file to read
18
+ :return: [檔案路徑, 檔案內容] / [file path, file content]
19
+
20
+ 流程 (Logic):
21
+ 1. 嘗試鎖定執行緒 (避免多執行緒同時存取)
22
+ Try to lock the thread (prevent concurrent access).
23
+ 2. 檢查檔案路徑是否為空,並確認檔案存在且為檔案。
24
+ Check if file path is not empty, exists, and is a file.
25
+ 3. 若條件成立,嘗試以 UTF-8 編碼開啟檔案並讀取內容。
26
+ If true, open the file with UTF-8 encoding and read content.
27
+ 4. 最後釋放鎖。
28
+ Finally, release the lock.
22
29
  """
30
+
31
+ # 記錄日誌,方便除錯與追蹤
32
+ # Log the file path for debugging and tracking
23
33
  jeditor_logger.info(f"open_file.py read_file file_path: {file_path}")
24
- lock = Lock()
34
+
35
+ lock = Lock() # 建立一個執行緒鎖 / Create a thread lock
25
36
  try:
26
- lock.acquire()
27
- if file_path != "" and file_path is not None:
28
- file_path = Path(file_path)
29
- if file_path.exists() and file_path.is_file():
37
+ lock.acquire() # 嘗試鎖定資源 / Acquire the lock
38
+ if file_path != "" and file_path is not None: # 確認路徑不為空 / Ensure path is not empty
39
+ file_path = Path(file_path) # 轉換為 Path 物件 / Convert to Path object
40
+ if file_path.exists() and file_path.is_file(): # 檢查檔案存在且為檔案 / Check file existence
41
+ # 以讀寫模式開啟檔案 (UTF-8 編碼)
42
+ # Open file in read+write mode with UTF-8 encoding
30
43
  with open(file_path, "r+", encoding="utf-8") as open_read_file:
31
- return [file_path, open_read_file.read()]
44
+ return [file_path, open_read_file.read()] # 回傳檔案路徑與內容 / Return file path and content
32
45
  except JEditorOpenFileException:
46
+ # 捕捉自訂例外並重新拋出
47
+ # Catch custom exception and re-raise
33
48
  raise JEditorOpenFileException
34
49
  finally:
35
- lock.release()
50
+ # 確保鎖一定會被釋放
51
+ # Ensure the lock is always released
52
+ lock.release()
@@ -1,31 +1,52 @@
1
1
  from threading import Lock
2
2
 
3
+ # 匯入自訂例外與日誌工具
4
+ # Import custom exception and logging utility
3
5
  from je_editor.utils.exception.exceptions import JEditorSaveFileException
4
6
  from je_editor.utils.logging.loggin_instance import jeditor_logger
5
7
 
6
8
 
7
9
  def write_file(file_path: str, content: str) -> None:
8
10
  """
9
- :param file_path: file we want to write
10
- :param content: content write in file
11
- try
12
- lock thread
13
- if file not empty string
14
- write content to file
15
- finally
16
- release lock
11
+ 功能說明 (Function Description):
12
+ 將指定內容寫入檔案,並確保在多執行緒環境下安全操作。
13
+ Write the given content into a file, ensuring thread safety.
14
+
15
+ :param file_path: 要寫入的檔案路徑 / the file path to write
16
+ :param content: 要寫入的內容 / the content to write
17
+
18
+ 流程 (Logic):
19
+ 1. 嘗試鎖定執行緒 (避免多執行緒同時存取檔案)
20
+ Try to lock the thread (prevent concurrent file access).
21
+ 2. 檢查檔案路徑是否為空字串或 None。
22
+ Check if file path is not empty or None.
23
+ 3. 若條件成立,開啟檔案並以 UTF-8 編碼寫入內容。
24
+ If valid, open the file and write content with UTF-8 encoding.
25
+ 4. 最後釋放鎖。
26
+ Finally, release the lock.
17
27
  """
28
+
29
+ # 記錄日誌,方便除錯與追蹤
30
+ # Log the file path and content for debugging and tracking
18
31
  jeditor_logger.info("save_file.py write_file "
19
32
  f"file_path: {file_path} "
20
33
  f"content: {content}")
21
- lock = Lock()
22
- content = str(content)
34
+
35
+ lock = Lock() # 建立一個執行緒鎖 / Create a thread lock
36
+ content = str(content) # 確保內容為字串 / Ensure content is a string
37
+
23
38
  try:
24
- lock.acquire()
25
- if file_path != "" and file_path is not None:
39
+ lock.acquire() # 嘗試鎖定資源 / Acquire the lock
40
+ if file_path != "" and file_path is not None: # 確認路徑有效 / Ensure path is valid
41
+ # 以寫入模式開啟檔案 (UTF-8 編碼)
42
+ # Open file in write+read mode with UTF-8 encoding
26
43
  with open(file_path, "w+", encoding="utf-8") as file_to_write:
27
- file_to_write.write(content)
44
+ file_to_write.write(content) # 寫入內容 / Write content
28
45
  except JEditorSaveFileException:
46
+ # 捕捉自訂例外並重新拋出
47
+ # Catch custom exception and re-raise
29
48
  raise JEditorSaveFileException
30
49
  finally:
31
- lock.release()
50
+ # 確保鎖一定會被釋放
51
+ # Ensure the lock is always released
52
+ lock.release()
@@ -1,48 +1,63 @@
1
1
  import json
2
2
  from pathlib import Path
3
3
  from threading import Lock
4
- from typing import Union
4
+ from typing import Union, Any
5
5
 
6
+ # 匯入自訂錯誤訊息與例外類別
7
+ # Import custom error messages and exception class
6
8
  from je_editor.utils.exception.exception_tags import cant_find_json_error
7
9
  from je_editor.utils.exception.exception_tags import cant_save_json_error
8
10
  from je_editor.utils.exception.exceptions import JEditorJsonException
9
11
  from je_editor.utils.logging.loggin_instance import jeditor_logger
10
12
 
13
+ # 全域鎖,確保多執行緒存取 JSON 檔案時的安全性
14
+ # Global lock to ensure thread safety when accessing JSON files
11
15
  _lock = Lock()
12
16
 
13
17
 
14
- def read_json(json_file_path: str) -> Union[list, dict]:
18
+ def read_json(json_file_path: str) -> Any | None:
15
19
  """
16
- use to read action file
17
- :param json_file_path json file's path to read
20
+ 功能說明 (Function Description):
21
+ 讀取 JSON 檔案並回傳其內容。
22
+ Read a JSON file and return its content.
23
+
24
+ :param json_file_path: JSON 檔案路徑 / path to the JSON file
25
+ :return: list 或 dict,取決於 JSON 結構 / list or dict depending on JSON structure
18
26
  """
19
27
  jeditor_logger.info(f"json_file.py read_json json_file_path: {json_file_path}")
20
- _lock.acquire()
28
+ _lock.acquire() # 嘗試鎖定資源 / Acquire the lock
21
29
  try:
22
30
  file_path = Path(json_file_path)
23
- if file_path.exists() and file_path.is_file():
24
- with open(json_file_path) as read_file:
25
- return json.loads(read_file.read())
31
+ if file_path.exists() and file_path.is_file(): # 確認檔案存在且為檔案 / Ensure file exists
32
+ with open(json_file_path) as read_file: # 開啟檔案 (預設 UTF-8)
33
+ return json.loads(read_file.read()) # 載入 JSON 並回傳 / Load JSON and return
26
34
  except JEditorJsonException:
35
+ # 捕捉自訂例外並重新拋出
36
+ # Catch custom exception and re-raise
27
37
  raise JEditorJsonException(cant_find_json_error)
28
38
  finally:
29
- _lock.release()
39
+ _lock.release() # 確保鎖一定會被釋放 / Ensure the lock is always released
30
40
 
31
41
 
32
42
  def write_json(json_save_path: str, data_to_output: Union[list, dict]) -> None:
33
43
  """
34
- use to save action file
35
- :param json_save_path json save path
36
- :param data_to_output data to output
44
+ 功能說明 (Function Description):
45
+ 將資料寫入 JSON 檔案。
46
+ Write data into a JSON file.
47
+
48
+ :param json_save_path: JSON 檔案儲存路徑 / path to save the JSON file
49
+ :param data_to_output: 要輸出的資料 (list 或 dict) / data to output (list or dict)
37
50
  """
38
51
  jeditor_logger.info("json_file.py write_json "
39
52
  f"json_save_path: {json_save_path} "
40
53
  f"data_to_output: {data_to_output}")
41
- _lock.acquire()
54
+ _lock.acquire() # 嘗試鎖定資源 / Acquire the lock
42
55
  try:
56
+ # 以寫入模式開啟檔案,並將資料轉換為 JSON 格式 (縮排 4 格)
57
+ # Open file in write mode and dump data as JSON (indent=4)
43
58
  with open(json_save_path, "w+") as file_to_write:
44
59
  file_to_write.write(json.dumps(data_to_output, indent=4))
45
60
  except JEditorJsonException:
46
61
  raise JEditorJsonException(cant_save_json_error)
47
62
  finally:
48
- _lock.release()
63
+ _lock.release() # 確保鎖一定會被釋放 / Ensure the lock is always released
@@ -3,6 +3,8 @@ import sys
3
3
  from json import dumps
4
4
  from json import loads
5
5
 
6
+ # 匯入自訂錯誤訊息與例外類別
7
+ # Import custom error messages and exception class
6
8
  from je_editor.utils.exception.exception_tags import cant_reformat_json_error
7
9
  from je_editor.utils.exception.exception_tags import wrong_json_data_error
8
10
  from je_editor.utils.exception.exceptions import JEditorJsonException
@@ -10,24 +12,53 @@ from je_editor.utils.logging.loggin_instance import jeditor_logger
10
12
 
11
13
 
12
14
  def __process_json(json_string: str, **kwargs) -> str:
15
+ """
16
+ 功能說明 (Function Description):
17
+ 嘗試將輸入的 JSON 字串重新格式化 (pretty print)。
18
+ Try to reformat the input JSON string (pretty print).
19
+
20
+ :param json_string: JSON 格式字串 / JSON formatted string
21
+ :param kwargs: 額外參數傳給 json.dumps / extra arguments for json.dumps
22
+ :return: 格式化後的 JSON 字串 / formatted JSON string
23
+ """
13
24
  try:
25
+ # 嘗試先將字串解析為 JSON,再重新輸出為縮排格式
26
+ # Try to parse string into JSON, then dump with indentation
14
27
  return dumps(loads(json_string), indent=4, sort_keys=True, **kwargs)
15
28
  except json.JSONDecodeError as error:
29
+ # 如果 JSON 格式錯誤,輸出錯誤訊息到 stderr 並拋出例外
30
+ # If JSON format is invalid, print error to stderr and raise exception
16
31
  print(wrong_json_data_error, file=sys.stderr)
17
32
  raise error
18
33
  except TypeError:
34
+ # 如果輸入不是合法 JSON 字串,嘗試直接將物件轉為 JSON
35
+ # If input is not a valid JSON string, try dumping the object directly
19
36
  try:
20
37
  return dumps(json_string, indent=4, sort_keys=True, **kwargs)
21
38
  except TypeError:
39
+ # 若仍失敗,拋出自訂例外
40
+ # If still fails, raise custom exception
22
41
  raise JEditorJsonException(wrong_json_data_error)
23
42
 
24
43
 
25
44
  def reformat_json(json_string: str, **kwargs) -> str:
26
- # Make json pretty
45
+ """
46
+ 功能說明 (Function Description):
47
+ 對外提供的 JSON 格式化函式,會呼叫內部的 __process_json。
48
+ Public function to reformat JSON string, calls __process_json internally.
49
+
50
+ :param json_string: JSON 格式字串 / JSON formatted string
51
+ :param kwargs: 額外參數傳給 json.dumps / extra arguments for json.dumps
52
+ :return: 格式化後的 JSON 字串 / formatted JSON string
53
+ """
54
+ # 記錄日誌,方便除錯與追蹤
55
+ # Log the input string and kwargs for debugging and tracking
27
56
  jeditor_logger.info(f"json_process.py reformat_json "
28
57
  f"json_string: {json_string} "
29
58
  f"kwargs: {kwargs}")
30
59
  try:
31
60
  return __process_json(json_string, **kwargs)
32
61
  except JEditorJsonException:
33
- raise JEditorJsonException(cant_reformat_json_error)
62
+ # 捕捉自訂例外並重新拋出
63
+ # Catch custom exception and re-raise
64
+ raise JEditorJsonException(cant_reformat_json_error)
@@ -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)
6
14
  jeditor_logger.setLevel(logging.WARNING)
15
+
16
+ # 定義日誌格式:時間 | logger 名稱 | 等級 | 訊息
17
+ # Define log format: time | logger name | level | message
7
18
  formatter = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(message)s')
8
19
 
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
- jeditor_logger.addHandler(file_handler)
26
-
27
-
57
+ jeditor_logger.addHandler(file_handler)
@@ -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
 
29
- language_wrapper = LanguageWrapper()
52
+ # 建立一個全域的 LanguageWrapper 實例
53
+ # Create a global instance of LanguageWrapper
54
+ language_wrapper = LanguageWrapper()
@@ -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
80
+
81
+ # 建立一個 logger 並綁定 stderr handler
82
+ # Create a logger and bind stderr handler
53
83
  default_logger = logging.getLogger("JEditor_RedirectManager")
54
84
  default_logger.addHandler(redirect_err)
55
- skip_logger_list = ["JEditor", "FrontEngine",
56
- "AutomationIDE", "TestPioneer", "langchain", "langchain_core", "langchain_openai"]
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
 
74
- redirect_manager_instance = RedirectManager()
110
+ # 建立全域 RedirectManager 實例
111
+ # Create a global instance of RedirectManager
112
+ redirect_manager_instance = RedirectManager()
@@ -1,28 +1,58 @@
1
1
  import shutil
2
2
  from pathlib import Path
3
3
 
4
+ # 匯入自訂錯誤訊息與例外類別
5
+ # Import custom error messages and exception class
6
+ from je_editor.utils.exception.exception_tags import compiler_not_found_error
7
+ from je_editor.utils.exception.exceptions import JEditorExecException
8
+ from je_editor.utils.logging.loggin_instance import jeditor_logger
9
+
10
+
11
+ import shutil
12
+ from pathlib import Path
13
+
14
+ # 匯入自訂錯誤訊息與例外類別
15
+ # Import custom error messages and exception class
4
16
  from je_editor.utils.exception.exception_tags import compiler_not_found_error
5
17
  from je_editor.utils.exception.exceptions import JEditorExecException
6
18
  from je_editor.utils.logging.loggin_instance import jeditor_logger
7
19
 
8
20
 
9
21
  def check_and_choose_venv(venv_path: Path) -> str:
22
+ """
23
+ 功能說明 (Function Description):
24
+ 檢查虛擬環境 (venv) 路徑,並嘗試尋找可用的 Python 編譯器。
25
+ Check the virtual environment (venv) path and try to find a usable Python interpreter.
26
+
27
+ :param venv_path: 虛擬環境的路徑 / path to the virtual environment
28
+ :return: Python 編譯器的完整路徑 / full path to the Python interpreter
29
+ :raise JEditorExecException: 若找不到 Python 編譯器 / if no Python interpreter is found
30
+ """
31
+
10
32
  jeditor_logger.info(f"check_venv.py check_and_choose_venv venv_path: {venv_path}")
11
- compiler_path = None
33
+
34
+ # 如果 venv_path 是資料夾且存在
35
+ # If venv_path is a directory and exists
12
36
  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")
37
+ # 先嘗試在該路徑下尋找 python3
38
+ # Try to find python3 in the given path
39
+ compiler_path = shutil.which("python3", path=str(venv_path))
40
+ if compiler_path:
41
+ return compiler_path
42
+
43
+ # 如果找不到 python3,再找 python
44
+ # If python3 not found, try python
45
+ compiler_path = shutil.which("python", path=str(venv_path))
46
+ if compiler_path:
47
+ return compiler_path
48
+
49
+ # 如果 venv_path 無效或都找不到,最後再嘗試系統預設的 python3 或 python
50
+ # If venv_path is invalid or no interpreter found, try system default python3 or python
51
+ compiler_path = shutil.which("python3") or shutil.which("python")
52
+
53
+ # 如果還是找不到,拋出例外
54
+ # If still not found, raise exception
26
55
  if compiler_path is None:
27
56
  raise JEditorExecException(compiler_not_found_error)
28
- return compiler_path
57
+
58
+ return compiler_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: je_editor
3
- Version: 0.0.222
3
+ Version: 0.0.224
4
4
  Summary: JEditor is basic but powerful editor include GPT
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/JE-Chen/je_editor