je-editor 0.0.204__py3-none-any.whl → 0.0.205__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.
- je_editor/pyside_ui/code/code_process/code_exec.py +1 -1
- je_editor/pyside_ui/code/shell_process/shell_exec.py +3 -3
- je_editor/pyside_ui/dialog/ai_dialog/__init__.py +0 -0
- je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +44 -0
- je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +4 -3
- je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +1 -0
- je_editor/pyside_ui/dialog/search_ui/search_error_box.py +2 -2
- je_editor/pyside_ui/dialog/search_ui/search_text_box.py +3 -3
- je_editor/pyside_ui/main_ui/ai_widget/__init__.py +0 -0
- je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +19 -0
- je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +17 -0
- je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +130 -0
- je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +45 -0
- je_editor/pyside_ui/main_ui/main_editor.py +1 -1
- je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +11 -1
- je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +17 -0
- je_editor/utils/multi_language/english.py +23 -4
- je_editor/utils/multi_language/traditional_chinese.py +23 -4
- je_editor/utils/redirect_manager/redirect_manager_class.py +1 -1
- {je_editor-0.0.204.dist-info → je_editor-0.0.205.dist-info}/METADATA +4 -1
- {je_editor-0.0.204.dist-info → je_editor-0.0.205.dist-info}/RECORD +24 -17
- {je_editor-0.0.204.dist-info → je_editor-0.0.205.dist-info}/WHEEL +1 -1
- {je_editor-0.0.204.dist-info → je_editor-0.0.205.dist-info}/licenses/LICENSE +0 -0
- {je_editor-0.0.204.dist-info → je_editor-0.0.205.dist-info}/top_level.txt +0 -0
@@ -44,8 +44,8 @@ class ShellManager(object):
|
|
44
44
|
self.read_program_output_from_thread = None
|
45
45
|
self.main_window: EditorWidget = main_window
|
46
46
|
self.compiler_path = None
|
47
|
-
self.code_result: [QTextEdit, None] = None
|
48
|
-
self.timer: [QTimer, None] = None
|
47
|
+
self.code_result: Union[QTextEdit, None] = None
|
48
|
+
self.timer: Union[QTimer, None] = None
|
49
49
|
self.still_run_shell: bool = True
|
50
50
|
self.process = None
|
51
51
|
self.run_output_queue: queue = queue.Queue()
|
@@ -157,7 +157,7 @@ class ShellManager(object):
|
|
157
157
|
if self.after_done_function is not None:
|
158
158
|
self.after_done_function()
|
159
159
|
|
160
|
-
# exit program change
|
160
|
+
# exit program change runs flag to false and clean read thread and queue and process
|
161
161
|
def exit_program(self) -> None:
|
162
162
|
jeditor_logger.info("ShellManager exit_program")
|
163
163
|
self.still_run_shell = False
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from PySide6.QtWidgets import QWidget, QLineEdit, QPushButton, QMessageBox, QGridLayout, QLabel
|
2
|
+
|
3
|
+
from je_editor.pyside_ui.main_ui.ai_widget.ai_config import ai_config
|
4
|
+
from je_editor.utils.logging.loggin_instance import jeditor_logger
|
5
|
+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
6
|
+
|
7
|
+
|
8
|
+
class SetAIDialog(QWidget):
|
9
|
+
|
10
|
+
def __init__(self):
|
11
|
+
jeditor_logger.info("Init SetAIDialog")
|
12
|
+
super().__init__()
|
13
|
+
self.base_url_label = QLabel(language_wrapper.language_word_dict.get("base_url_label"))
|
14
|
+
self.base_url_input = QLineEdit()
|
15
|
+
self.api_key_label = QLabel(language_wrapper.language_word_dict.get("api_key_label"))
|
16
|
+
self.api_key_input = QLineEdit()
|
17
|
+
self.chat_model_label = QLabel(language_wrapper.language_word_dict.get("ai_model_label"))
|
18
|
+
self.chat_model_input = QLineEdit()
|
19
|
+
self.add_ai_info_button = QPushButton()
|
20
|
+
self.add_ai_info_button.setText(language_wrapper.language_word_dict.get("add_ai_model_pushbutton"))
|
21
|
+
self.add_ai_info_button.clicked.connect(self.update_ai_config)
|
22
|
+
self.grid_layout = QGridLayout()
|
23
|
+
self.grid_layout.addWidget(self.base_url_label, 0, 0)
|
24
|
+
self.grid_layout.addWidget(self.base_url_input, 0, 1)
|
25
|
+
self.grid_layout.addWidget(self.api_key_label, 1, 0)
|
26
|
+
self.grid_layout.addWidget(self.api_key_input, 1, 1)
|
27
|
+
self.grid_layout.addWidget(self.chat_model_label, 2, 0)
|
28
|
+
self.grid_layout.addWidget(self.chat_model_input, 2, 1)
|
29
|
+
self.grid_layout.addWidget(self.add_ai_info_button, 3, 1)
|
30
|
+
self.setWindowTitle(language_wrapper.language_word_dict.get("add_ai_model_title"))
|
31
|
+
self.setLayout(self.grid_layout)
|
32
|
+
|
33
|
+
def update_ai_config(self):
|
34
|
+
base_url = self.base_url_input.text().strip()
|
35
|
+
api_key = self.api_key_input.text().strip()
|
36
|
+
chat_model = self.chat_model_input.text().strip()
|
37
|
+
if base_url and chat_model:
|
38
|
+
ai_config.choosable_ai.update(
|
39
|
+
{"AI_model": {"base_url": base_url, "api_key": api_key, "chat_model": chat_model}}
|
40
|
+
)
|
41
|
+
else:
|
42
|
+
QMessageBox.warning(self,
|
43
|
+
language_wrapper.language_word_dict.get("set_ai_model_warring_title"),
|
44
|
+
language_wrapper.language_word_dict.get("set_ai_model_warring_text"))
|
@@ -12,13 +12,13 @@ class CreateFileDialog(QWidget):
|
|
12
12
|
self.box_layout = QBoxLayout(QBoxLayout.Direction.TopToBottom)
|
13
13
|
self.file_name_input = QLineEdit()
|
14
14
|
self.create_file_button = QPushButton()
|
15
|
-
self.create_file_button.setText(language_wrapper.language_word_dict.get("
|
15
|
+
self.create_file_button.setText(language_wrapper.language_word_dict.get("create_file_dialog_pushbutton"))
|
16
16
|
self.create_file_button.clicked.connect(self.create_file)
|
17
17
|
self.box_h_layout = QHBoxLayout()
|
18
18
|
self.box_h_layout.addWidget(self.create_file_button)
|
19
19
|
self.box_layout.addWidget(self.file_name_input)
|
20
20
|
self.box_layout.addLayout(self.box_h_layout)
|
21
|
-
self.setWindowTitle(language_wrapper.language_word_dict.get("
|
21
|
+
self.setWindowTitle(language_wrapper.language_word_dict.get("create_file_dialog_pushbutton"))
|
22
22
|
self.setLayout(self.box_layout)
|
23
23
|
|
24
24
|
def create_file(self):
|
@@ -26,7 +26,8 @@ class CreateFileDialog(QWidget):
|
|
26
26
|
file_name = self.file_name_input.text().strip()
|
27
27
|
if file_name == "":
|
28
28
|
create_file_message_box = QMessageBox(self)
|
29
|
-
create_file_message_box.setText(
|
29
|
+
create_file_message_box.setText(
|
30
|
+
language_wrapper.language_word_dict.get("input_file_name_dialog_pushbutton"))
|
30
31
|
create_file_message_box.show()
|
31
32
|
else:
|
32
33
|
with open(file_name, "w+") as file:
|
@@ -12,9 +12,9 @@ class SearchResultBox(QWidget):
|
|
12
12
|
self.box_layout = QBoxLayout(QBoxLayout.Direction.TopToBottom)
|
13
13
|
self.search_input = QLineEdit()
|
14
14
|
self.search_next_button = QPushButton()
|
15
|
-
self.search_next_button.setText(language_wrapper.language_word_dict.get("
|
15
|
+
self.search_next_button.setText(language_wrapper.language_word_dict.get("search_next_dialog_pushbutton"))
|
16
16
|
self.search_back_button = QPushButton()
|
17
|
-
self.search_back_button.setText(language_wrapper.language_word_dict.get("
|
17
|
+
self.search_back_button.setText(language_wrapper.language_word_dict.get("search_back_dialog_pushbutton"))
|
18
18
|
self.box_h_layout = QHBoxLayout()
|
19
19
|
self.box_h_layout.addWidget(self.search_back_button)
|
20
20
|
self.box_h_layout.addWidget(self.search_next_button)
|
@@ -12,13 +12,13 @@ class SearchBox(QWidget):
|
|
12
12
|
self.box_layout = QBoxLayout(QBoxLayout.Direction.TopToBottom)
|
13
13
|
self.search_input = QLineEdit()
|
14
14
|
self.search_next_button = QPushButton()
|
15
|
-
self.search_next_button.setText(language_wrapper.language_word_dict.get("
|
15
|
+
self.search_next_button.setText(language_wrapper.language_word_dict.get("search_next_dialog_pushbutton"))
|
16
16
|
self.search_back_button = QPushButton()
|
17
|
-
self.search_back_button.setText(language_wrapper.language_word_dict.get("
|
17
|
+
self.search_back_button.setText(language_wrapper.language_word_dict.get("search_back_dialog_pushbutton"))
|
18
18
|
self.box_h_layout = QHBoxLayout()
|
19
19
|
self.box_h_layout.addWidget(self.search_back_button)
|
20
20
|
self.box_h_layout.addWidget(self.search_next_button)
|
21
21
|
self.box_layout.addWidget(self.search_input)
|
22
22
|
self.box_layout.addLayout(self.box_h_layout)
|
23
|
-
self.setWindowTitle("
|
23
|
+
self.setWindowTitle(language_wrapper.language_word_dict.get("search_box_dialog_title"))
|
24
24
|
self.setLayout(self.box_layout)
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from queue import Queue
|
2
|
+
|
3
|
+
|
4
|
+
class AIConfig(object):
|
5
|
+
|
6
|
+
def __init__(self):
|
7
|
+
self.current_ai_model_system_prompt: str = ""
|
8
|
+
self.choosable_ai: dict[str, dict[str, str]] = {
|
9
|
+
"AI_model": {
|
10
|
+
"ai_base_url": "",
|
11
|
+
"ai_api_key": "",
|
12
|
+
"chat_model": "",
|
13
|
+
"prompt_template": "",
|
14
|
+
}
|
15
|
+
}
|
16
|
+
self.message_queue = Queue()
|
17
|
+
|
18
|
+
|
19
|
+
ai_config = AIConfig()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from threading import Thread
|
2
|
+
|
3
|
+
from je_editor.pyside_ui.main_ui.ai_widget.ai_config import ai_config
|
4
|
+
from je_editor.pyside_ui.main_ui.ai_widget.langchain_interface import LangChainInterface
|
5
|
+
|
6
|
+
|
7
|
+
class AskThread(Thread):
|
8
|
+
|
9
|
+
def __init__(self, lang_chain_interface: LangChainInterface, prompt):
|
10
|
+
super().__init__()
|
11
|
+
self.lang_chain_interface = lang_chain_interface
|
12
|
+
self.prompt = prompt
|
13
|
+
|
14
|
+
|
15
|
+
def run(self):
|
16
|
+
ai_response = self.lang_chain_interface.call_ai_model(prompt=self.prompt)
|
17
|
+
ai_config.message_queue.put(ai_response)
|
@@ -0,0 +1,130 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import TYPE_CHECKING, Union
|
5
|
+
|
6
|
+
from PySide6.QtCore import Qt, QTimer
|
7
|
+
from PySide6.QtGui import QFontDatabase
|
8
|
+
from PySide6.QtWidgets import QWidget, QPlainTextEdit, QScrollArea, QLabel, QComboBox, QGridLayout, QPushButton, \
|
9
|
+
QMessageBox, QSizePolicy, QLineEdit
|
10
|
+
|
11
|
+
from je_editor.pyside_ui.dialog.ai_dialog.set_ai_dialog import SetAIDialog
|
12
|
+
from je_editor.pyside_ui.main_ui.ai_widget.ai_config import AIConfig, ai_config
|
13
|
+
from je_editor.pyside_ui.main_ui.ai_widget.ask_thread import AskThread
|
14
|
+
from je_editor.pyside_ui.main_ui.ai_widget.langchain_interface import LangChainInterface
|
15
|
+
from je_editor.utils.json.json_file import read_json
|
16
|
+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
17
|
+
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from je_editor.pyside_ui.main_ui.main_editor import EditorMain
|
20
|
+
|
21
|
+
|
22
|
+
class ChatUI(QWidget):
|
23
|
+
|
24
|
+
def __init__(self, main_window: EditorMain):
|
25
|
+
super().__init__()
|
26
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
27
|
+
self.main_window = main_window
|
28
|
+
# Chat panel
|
29
|
+
self.chat_panel = QPlainTextEdit()
|
30
|
+
self.chat_panel.setLineWrapMode(self.chat_panel.LineWrapMode.NoWrap)
|
31
|
+
self.chat_panel.setReadOnly(True)
|
32
|
+
self.chat_panel_scroll_area = QScrollArea()
|
33
|
+
self.chat_panel_scroll_area.setWidgetResizable(True)
|
34
|
+
self.chat_panel_scroll_area.setViewportMargins(0, 0, 0, 0)
|
35
|
+
self.chat_panel_scroll_area.setWidget(self.chat_panel)
|
36
|
+
self.chat_panel.setFont(QFontDatabase.font(self.font().family(), "", 16))
|
37
|
+
# Prompt input
|
38
|
+
self.prompt_input = QLineEdit()
|
39
|
+
self.prompt_input.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
40
|
+
self.prompt_input.returnPressed.connect(self.call_ai_model)
|
41
|
+
# Font size combobox
|
42
|
+
self.font_size_label = QLabel(language_wrapper.language_word_dict.get("font_size"))
|
43
|
+
self.font_size_combobox = QComboBox()
|
44
|
+
for font_size in range(2, 101, 2):
|
45
|
+
self.font_size_combobox.addItem(str(font_size))
|
46
|
+
self.font_size_combobox.setCurrentText("16")
|
47
|
+
self.font_size_combobox.currentTextChanged.connect(self.update_panel_text_size)
|
48
|
+
# Buttons
|
49
|
+
self.set_ai_config_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_set_ai_button"))
|
50
|
+
self.set_ai_config_button.clicked.connect(self.set_ai_config)
|
51
|
+
self.load_ai_config_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_load_ai_button"))
|
52
|
+
self.load_ai_config_button.clicked.connect(lambda: self.load_ai_config(show_load_complete=True))
|
53
|
+
self.call_ai_model_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_call_ai_model_button"))
|
54
|
+
self.call_ai_model_button.clicked.connect(self.call_ai_model)
|
55
|
+
# Add to layout
|
56
|
+
self.grid_layout = QGridLayout()
|
57
|
+
self.grid_layout.addWidget(self.chat_panel_scroll_area, 0, 0, 1, 4)
|
58
|
+
self.grid_layout.addWidget(self.call_ai_model_button, 1, 0)
|
59
|
+
self.grid_layout.addWidget(self.font_size_combobox, 1, 1)
|
60
|
+
self.grid_layout.addWidget(self.set_ai_config_button, 1, 2)
|
61
|
+
self.grid_layout.addWidget(self.load_ai_config_button, 1, 3)
|
62
|
+
self.grid_layout.addWidget(self.prompt_input, 2, 0, 1, 4)
|
63
|
+
|
64
|
+
# Variable
|
65
|
+
self.ai_config: AIConfig = ai_config
|
66
|
+
self.lang_chain_interface: Union[LangChainInterface, None] = None
|
67
|
+
self.set_ai_config_dialog = None
|
68
|
+
# Timer to pop queue
|
69
|
+
self.pull_message_timer = QTimer(self)
|
70
|
+
self.pull_message_timer.setInterval(1000)
|
71
|
+
self.pull_message_timer.timeout.connect(self.pull_message)
|
72
|
+
self.pull_message_timer.start()
|
73
|
+
|
74
|
+
# Set layout
|
75
|
+
self.setLayout(self.grid_layout)
|
76
|
+
|
77
|
+
self.load_ai_config()
|
78
|
+
|
79
|
+
def update_panel_text_size(self):
|
80
|
+
self.chat_panel.setFont(
|
81
|
+
QFontDatabase.font(self.font().family(), "", int(self.font_size_combobox.currentText())))
|
82
|
+
|
83
|
+
def load_ai_config(self, show_load_complete: bool = False):
|
84
|
+
ai_config_file = Path(str(Path.cwd()) + "/" + ".jeditor/ai_config.json")
|
85
|
+
if ai_config_file.exists():
|
86
|
+
with open(ai_config_file, "r", encoding="utf-8"):
|
87
|
+
json_data: dict = read_json(str(ai_config_file))
|
88
|
+
if json_data:
|
89
|
+
if json_data.get("AI_model") and len(json_data.get("AI_model")) == 4:
|
90
|
+
ai_info: dict = json_data.get("AI_model")
|
91
|
+
if ai_info.get("ai_base_url") and ai_info.get("chat_model"):
|
92
|
+
ai_config.choosable_ai.update(json_data)
|
93
|
+
self.lang_chain_interface = LangChainInterface(
|
94
|
+
main_window=self,
|
95
|
+
api_key=ai_info.get("ai_api_key"),
|
96
|
+
base_url=ai_info.get("ai_base_url"),
|
97
|
+
chat_model=ai_info.get("chat_model"),
|
98
|
+
prompt_template=ai_info.get("prompt_template"),
|
99
|
+
)
|
100
|
+
if show_load_complete:
|
101
|
+
load_complete = QMessageBox(self)
|
102
|
+
load_complete.setWindowTitle(language_wrapper.language_word_dict.get("load_ai_messagebox_title"))
|
103
|
+
load_complete.setText(language_wrapper.language_word_dict.get("load_ai_messagebox_text"))
|
104
|
+
load_complete.exec()
|
105
|
+
|
106
|
+
|
107
|
+
def call_ai_model(self):
|
108
|
+
if isinstance(self.lang_chain_interface, LangChainInterface):
|
109
|
+
thread = AskThread(lang_chain_interface=self.lang_chain_interface, prompt=self.prompt_input.text())
|
110
|
+
thread.start()
|
111
|
+
else:
|
112
|
+
ai_info = ai_config.choosable_ai.get('AI_model')
|
113
|
+
QMessageBox.warning(self,
|
114
|
+
language_wrapper.language_word_dict.get("call_ai_model_error_title"),
|
115
|
+
language_wrapper.language_word_dict.get(
|
116
|
+
f"ai_api_key: {ai_info.get('ai_api_key')}, \n"
|
117
|
+
f"ai_base_url: {ai_info.get('ai_base_url')}, \n"
|
118
|
+
f"chat_model: {ai_info.get('chat_model')}, \n"
|
119
|
+
f"prompt_template: {ai_info.get('prompt_template')}"))
|
120
|
+
|
121
|
+
def pull_message(self):
|
122
|
+
if not ai_config.message_queue.empty():
|
123
|
+
ai_response = ai_config.message_queue.get_nowait()
|
124
|
+
self.chat_panel.appendPlainText(ai_response)
|
125
|
+
self.chat_panel.appendPlainText("\n")
|
126
|
+
|
127
|
+
def set_ai_config(self):
|
128
|
+
# Set and output AI a config file
|
129
|
+
self.set_ai_config_dialog = SetAIDialog()
|
130
|
+
self.set_ai_config_dialog.show()
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import os
|
4
|
+
import re
|
5
|
+
from typing import Union, TYPE_CHECKING
|
6
|
+
|
7
|
+
from PySide6.QtWidgets import QMessageBox
|
8
|
+
from langchain.prompts.chat import SystemMessagePromptTemplate
|
9
|
+
from langchain_openai import ChatOpenAI
|
10
|
+
from pydantic import SecretStr
|
11
|
+
|
12
|
+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
16
|
+
|
17
|
+
class LangChainInterface(object):
|
18
|
+
|
19
|
+
def __init__(self, main_window: ChatUI, prompt_template: str, base_url: str, api_key: Union[SecretStr, str],
|
20
|
+
chat_model: str):
|
21
|
+
self.system_message_prompt = SystemMessagePromptTemplate.from_template(prompt_template)
|
22
|
+
self.base_url = base_url
|
23
|
+
self.api_key = api_key
|
24
|
+
self.chat_model = chat_model
|
25
|
+
self.main_window = main_window
|
26
|
+
os.environ["OPENAI_BASE_URL"] = self.base_url
|
27
|
+
os.environ["OPENAI_API_KEY"] = self.api_key
|
28
|
+
os.environ["CHAT_MODEL"] = self.chat_model
|
29
|
+
self.chat_ai = ChatOpenAI(base_url=self.base_url, api_key=self.api_key, model=self.chat_model)
|
30
|
+
|
31
|
+
def call_ai_model(self, prompt: str) -> str | None:
|
32
|
+
message = None
|
33
|
+
try:
|
34
|
+
message = self.chat_ai.invoke(prompt).text()
|
35
|
+
match = re.search(r"</think>\s*(.*)", message, re.DOTALL)
|
36
|
+
if match:
|
37
|
+
message = match.group(1).strip()
|
38
|
+
else:
|
39
|
+
message = message
|
40
|
+
|
41
|
+
except Exception as error:
|
42
|
+
QMessageBox.warning(self.main_window,
|
43
|
+
language_wrapper.language_word_dict.get("call_ai_model_error_title"),
|
44
|
+
str(error))
|
45
|
+
return message
|
@@ -7,7 +7,7 @@ from typing import Dict, Type
|
|
7
7
|
import jedi.settings
|
8
8
|
from PySide6.QtCore import QTimer, QEvent
|
9
9
|
from PySide6.QtGui import QFontDatabase, QIcon, Qt
|
10
|
-
from PySide6.QtWidgets import QMainWindow, QWidget, QTabWidget
|
10
|
+
from PySide6.QtWidgets import QMainWindow, QWidget, QTabWidget, QMessageBox
|
11
11
|
from frontengine import FrontEngineMainUI
|
12
12
|
from qt_material import QtStyleTools
|
13
13
|
|
@@ -9,6 +9,7 @@ from PySide6.QtWidgets import QFileDialog
|
|
9
9
|
from frontengine import FrontEngineMainUI
|
10
10
|
|
11
11
|
from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
|
12
|
+
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
12
13
|
from je_editor.pyside_ui.main_ui.dock.destroy_dock import DestroyDock
|
13
14
|
from je_editor.pyside_ui.main_ui.editor.editor_widget_dock import FullEditorWidget
|
14
15
|
from je_editor.pyside_ui.main_ui.ipython_widget.rich_jupyter import IpythonWidget
|
@@ -59,7 +60,13 @@ def set_dock_menu(ui_we_want_to_set: EditorMain) -> None:
|
|
59
60
|
lambda: add_dock_widget(ui_we_want_to_set, "ipython")
|
60
61
|
)
|
61
62
|
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_ipython)
|
62
|
-
|
63
|
+
# ChatUI
|
64
|
+
ui_we_want_to_set.dock_menu.new_chat_ui = QAction(
|
65
|
+
language_wrapper.language_word_dict.get("chat_ui_dock_label"))
|
66
|
+
ui_we_want_to_set.dock_menu.new_chat_ui.triggered.connect(
|
67
|
+
lambda: add_dock_widget(ui_we_want_to_set, "chat_ui")
|
68
|
+
)
|
69
|
+
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_chat_ui)
|
63
70
|
|
64
71
|
def add_dock_widget(ui_we_want_to_set: EditorMain, widget_type: str = None):
|
65
72
|
jeditor_logger.info("build_dock_menu.py add_dock_widget "
|
@@ -90,6 +97,9 @@ def add_dock_widget(ui_we_want_to_set: EditorMain, widget_type: str = None):
|
|
90
97
|
elif widget_type == "ipython":
|
91
98
|
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_ipython_title"))
|
92
99
|
dock_widget.setWidget(IpythonWidget(ui_we_want_to_set))
|
100
|
+
elif widget_type == "chat_ui":
|
101
|
+
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("chat_ui_dock_label"))
|
102
|
+
dock_widget.setWidget(ChatUI(ui_we_want_to_set))
|
93
103
|
else:
|
94
104
|
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_browser_title"))
|
95
105
|
dock_widget.setWidget(BrowserWidget())
|
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
|
|
5
5
|
from frontengine import FrontEngineMainUI
|
6
6
|
|
7
7
|
from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
|
8
|
+
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
8
9
|
from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
|
9
10
|
from je_editor.pyside_ui.main_ui.ipython_widget.rich_jupyter import IpythonWidget
|
10
11
|
from je_editor.utils.logging.loggin_instance import jeditor_logger
|
@@ -55,6 +56,13 @@ def set_tab_menu(ui_we_want_to_set: EditorMain) -> None:
|
|
55
56
|
lambda: add_ipython_tab(ui_we_want_to_set)
|
56
57
|
)
|
57
58
|
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_ipython_action)
|
59
|
+
# ChatUI
|
60
|
+
ui_we_want_to_set.tab_menu.add_chat_ui_action = QAction(
|
61
|
+
language_wrapper.language_word_dict.get("tab_menu_chat_ui_tab_name"))
|
62
|
+
ui_we_want_to_set.tab_menu.add_chat_ui_action.triggered.connect(
|
63
|
+
lambda: add_chat_ui_tab(ui_we_want_to_set)
|
64
|
+
)
|
65
|
+
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_chat_ui_action)
|
58
66
|
|
59
67
|
|
60
68
|
def add_editor_tab(ui_we_want_to_set: EditorMain):
|
@@ -98,3 +106,12 @@ def add_ipython_tab(ui_we_want_to_set: EditorMain):
|
|
98
106
|
f"{language_wrapper.language_word_dict.get('tab_menu_ipython_tab_name')} "
|
99
107
|
f"{ui_we_want_to_set.tab_widget.count()}")
|
100
108
|
|
109
|
+
|
110
|
+
def add_chat_ui_tab(ui_we_want_to_set: EditorMain):
|
111
|
+
jeditor_logger.info(f"build_tab_menu.py add_ipython_tab ui_we_want_to_set: {ui_we_want_to_set}")
|
112
|
+
ui_we_want_to_set.tab_widget.addTab(
|
113
|
+
ChatUI(ui_we_want_to_set),
|
114
|
+
f"{language_wrapper.language_word_dict.get('tab_menu_chat_ui_tab_name')} "
|
115
|
+
f"{ui_we_want_to_set.tab_widget.count()}")
|
116
|
+
|
117
|
+
|
@@ -14,10 +14,13 @@ english_word_dict = {
|
|
14
14
|
"browser_reload_button": "Reload",
|
15
15
|
"browser_search_button": "Search",
|
16
16
|
# Dialog
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
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",
|
@@ -106,6 +109,7 @@ 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",
|
109
113
|
# Text Menu
|
110
114
|
"text_menu_label": "Text",
|
111
115
|
"text_menu_label_font": "Font",
|
@@ -122,4 +126,19 @@ please make sure that the current encoding is consistent with the default encodi
|
|
122
126
|
"language_menu_bar_please_restart_messagebox": "Please restart",
|
123
127
|
# Qtconsole
|
124
128
|
"please_install_qtcontsole_label": "Please python -m pip install qtconsole first.",
|
129
|
+
# Chat UI
|
130
|
+
"font_size": "Font Size",
|
131
|
+
"set_ai_model_waring_title": "Can not set AI Model",
|
132
|
+
"set_ai_model_waring_text": "Please check [ai_base_url, ai_api_key, chat_model]",
|
133
|
+
"call_ai_model_error_title": "Can't connect to AI Model",
|
134
|
+
"call_ai_model_error_text": "Please check [ai_base_url, ai_api_key, chat_model]",
|
135
|
+
"chat_ui_dock_label": "Chat UI",
|
136
|
+
"chat_ui_set_ai_button": "Set AI setting",
|
137
|
+
"chat_ui_load_ai_button": "Load AI setting",
|
138
|
+
"chat_ui_call_ai_model_button": "Send prompt",
|
139
|
+
"base_url_label": "AI server URL",
|
140
|
+
"api_key_label": "AI server API Key",
|
141
|
+
"ai_model_label": "AI Model",
|
142
|
+
"load_ai_messagebox_title": "Load complete",
|
143
|
+
"load_ai_messagebox_text": "Load complete",
|
125
144
|
}
|
@@ -14,10 +14,13 @@ traditional_chinese_word_dict = {
|
|
14
14
|
"browser_reload_button": "重新載入",
|
15
15
|
"browser_search_button": "搜尋",
|
16
16
|
# Dialog
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
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": "程式格式檢查",
|
@@ -104,6 +107,7 @@ traditional_chinese_word_dict = {
|
|
104
107
|
"tab_menu_web_tab_name": "瀏覽器",
|
105
108
|
"tab_menu_stackoverflow_tab_name": "Stackoverflow",
|
106
109
|
"tab_menu_ipython_tab_name": "IPython(Jupyter)",
|
110
|
+
"tab_menu_chat_ui_tab_name": "ChatUI",
|
107
111
|
# Text Menu
|
108
112
|
"text_menu_label": "文字",
|
109
113
|
"text_menu_label_font": "字體",
|
@@ -120,4 +124,19 @@ traditional_chinese_word_dict = {
|
|
120
124
|
"language_menu_bar_please_restart_messagebox": "請重啟以應用更改",
|
121
125
|
# Qtconsole
|
122
126
|
"please_install_qtcontsole_label": "請先 python -m pip install qtconsole",
|
127
|
+
# Chat UI
|
128
|
+
"font_size": "字體大小",
|
129
|
+
"set_ai_model_waring_title": "無法設置 AI Model",
|
130
|
+
"set_ai_model_warring_text": "請檢查 [ai_base_url, ai_api_key, chat_model]",
|
131
|
+
"call_ai_model_error_title": "無法連線到 AI 模型",
|
132
|
+
"call_ai_model_error_text": "請檢查 [ai_base_url, ai_api_key, chat_model]",
|
133
|
+
"chat_ui_dock_label": "聊天 UI",
|
134
|
+
"chat_ui_set_ai_button": "設定 AI 設定",
|
135
|
+
"chat_ui_load_ai_button": "載入 AI 設定",
|
136
|
+
"chat_ui_call_ai_model_button": "傳送 prompt",
|
137
|
+
"base_url_label":"AI 伺服器 URL",
|
138
|
+
"api_key_label": "AI 伺服器 API Key",
|
139
|
+
"ai_model_label": "AI Model",
|
140
|
+
"load_ai_messagebox_title": "載入成功",
|
141
|
+
"load_ai_messagebox_text": "載入成功",
|
123
142
|
}
|
@@ -53,7 +53,7 @@ class RedirectManager(object):
|
|
53
53
|
default_logger = logging.getLogger("RedirectManager")
|
54
54
|
default_logger.addHandler(redirect_err)
|
55
55
|
skip_logger_list = ["JEditor", "FrontEngine",
|
56
|
-
"AutomationIDE", "TestPioneer"]
|
56
|
+
"AutomationIDE", "TestPioneer", "langchain", "langchain_core", "langchain_openai"]
|
57
57
|
for name in logging.root.manager.loggerDict.keys():
|
58
58
|
if name in skip_logger_list:
|
59
59
|
continue
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: je_editor
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.205
|
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
|
@@ -23,6 +23,9 @@ Requires-Dist: frontengine
|
|
23
23
|
Requires-Dist: pycodestyle
|
24
24
|
Requires-Dist: jedi
|
25
25
|
Requires-Dist: qtconsole
|
26
|
+
Requires-Dist: langchain_openai
|
27
|
+
Requires-Dist: langchain
|
28
|
+
Requires-Dist: pydantic
|
26
29
|
Dynamic: license-file
|
27
30
|
|
28
31
|
# je_editor
|
@@ -15,26 +15,33 @@ je_editor/pyside_ui/code/auto_save/auto_save_thread.py,sha256=V_A8_4JZdHdF9e2E_r
|
|
15
15
|
je_editor/pyside_ui/code/code_format/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
je_editor/pyside_ui/code/code_format/pep8_format.py,sha256=zrCkUdz2SG4bnMSkXfccvpHAmUOxXLedSBxL_nkdaoE,3574
|
17
17
|
je_editor/pyside_ui/code/code_process/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
-
je_editor/pyside_ui/code/code_process/code_exec.py,sha256=
|
18
|
+
je_editor/pyside_ui/code/code_process/code_exec.py,sha256=yrkWz7lqWmbpfuNUHavFfyisKuVfhHSHS6D95Oq52Dk,9841
|
19
19
|
je_editor/pyside_ui/code/plaintext_code_edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py,sha256=lcwmBemFenH-uDGe6fo70MS47emzPFgy9XL7cipwryY,14249
|
21
21
|
je_editor/pyside_ui/code/shell_process/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
je_editor/pyside_ui/code/shell_process/shell_exec.py,sha256=
|
22
|
+
je_editor/pyside_ui/code/shell_process/shell_exec.py,sha256=y1SxB2NnblB3U7qOwQxuJv7aMgBiBSMTY9gP5X8-j4E,8741
|
23
23
|
je_editor/pyside_ui/code/syntax/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
je_editor/pyside_ui/code/syntax/python_syntax.py,sha256=9rK7_DYAANgf28PUdVl9xs42b76Re_SWwIpijEGBuzQ,3054
|
25
25
|
je_editor/pyside_ui/code/syntax/syntax_setting.py,sha256=oaLRF_83Oa6bcAorf7AlZG0Mrt4FmsK7b4aA-LS_bRo,2284
|
26
26
|
je_editor/pyside_ui/code/textedit_code_result/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
je_editor/pyside_ui/code/textedit_code_result/code_record.py,sha256=pT-CmcADEaXLZ0ih6D6rpe1XywgszrEpcJxtJYgopJE,2162
|
28
28
|
je_editor/pyside_ui/dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
|
+
je_editor/pyside_ui/dialog/ai_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
+
je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py,sha256=w_cku2dQthtk0TDSxEeDB-tvzdHV4vmUhFVDlb2ynO8,2392
|
29
31
|
je_editor/pyside_ui/dialog/file_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
-
je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py,sha256=
|
32
|
+
je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py,sha256=3NvGVld_If2TsM_Xt0pgWDTcj51szS8MxG1raU-tP2A,1650
|
31
33
|
je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py,sha256=wTI4TwMfJ-960c_C0cLy2EhWbZosewSmpyWOrcf9yLE,3806
|
32
|
-
je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py,sha256=
|
34
|
+
je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py,sha256=pyPfwgrDiDpMKk8T_4oBukgJLxdWnzIKSziwFt4YuUU,1781
|
33
35
|
je_editor/pyside_ui/dialog/search_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
|
-
je_editor/pyside_ui/dialog/search_ui/search_error_box.py,sha256=
|
35
|
-
je_editor/pyside_ui/dialog/search_ui/search_text_box.py,sha256=
|
36
|
+
je_editor/pyside_ui/dialog/search_ui/search_error_box.py,sha256=jSa423cQW_xQ2WAj46CCWPsCP0Gy7g-UDe5o8LQyKQk,1190
|
37
|
+
je_editor/pyside_ui/dialog/search_ui/search_text_box.py,sha256=ul-98FVByq_TNkkLZcBSF4VSwIQNBBj-4e6jYlh6YEA,1229
|
36
38
|
je_editor/pyside_ui/main_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
|
-
je_editor/pyside_ui/main_ui/main_editor.py,sha256=
|
39
|
+
je_editor/pyside_ui/main_ui/main_editor.py,sha256=NCyNb20qLg-PRgjuyHB3UxOcIWfSDgvO0mn7SF2Jdgk,11075
|
40
|
+
je_editor/pyside_ui/main_ui/ai_widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
+
je_editor/pyside_ui/main_ui/ai_widget/ai_config.py,sha256=Uc9UkrIeALqjmZCF5ukXtSgU1EB4xa5223gk3CfYXX4,459
|
42
|
+
je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py,sha256=ma5Cnwlr0RbU-sytmodcYabWueyGE8DKKISZ_0zf3Eo,571
|
43
|
+
je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py,sha256=yBoWXvGvgUCWjmPoBcOhj0mtOm0R42mYEs7FokYQmnE,6763
|
44
|
+
je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py,sha256=OgBaUcUMR0Z2VQUO9QfCX2wJc_qBFw3IvoMCiEGBTug,1768
|
38
45
|
je_editor/pyside_ui/main_ui/dock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
46
|
je_editor/pyside_ui/main_ui/dock/destroy_dock.py,sha256=MTN45BykNm6FA4gMW7gI4Kr9orTdcxVTm7mch3DUhaw,604
|
40
47
|
je_editor/pyside_ui/main_ui/editor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -48,7 +55,7 @@ je_editor/pyside_ui/main_ui/menu/set_menu_bar.py,sha256=I12DXLyRO4cKe17fQY-QDazK
|
|
48
55
|
je_editor/pyside_ui/main_ui/menu/check_style_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
49
56
|
je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py,sha256=1wD6FI21Dw3IcQONuTkHP9rUPGwY70OvCtSc-ZcTKMk,3793
|
50
57
|
je_editor/pyside_ui/main_ui/menu/dock_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
|
-
je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py,sha256=
|
58
|
+
je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py,sha256=74djXCmevdbGs61EBiIuvWUnHrN41DCZJw6aPEkLiK8,5600
|
52
59
|
je_editor/pyside_ui/main_ui/menu/file_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
60
|
je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py,sha256=YT6kvXShRbfM4Qo51VveO_IK8uDqlNrGwHZUiM6_Tes,6881
|
54
61
|
je_editor/pyside_ui/main_ui/menu/help_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -67,7 +74,7 @@ je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py,sha256=zk5adQ7
|
|
67
74
|
je_editor/pyside_ui/main_ui/menu/style_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
75
|
je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py,sha256=OjfcjQ7fA1Z1rMwIS9oGkIkC-jy-e0jdGoYo1btTqUQ,1852
|
69
76
|
je_editor/pyside_ui/main_ui/menu/tab_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
70
|
-
je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py,sha256
|
77
|
+
je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py,sha256=ZP_HHXmQYguSVQpzK-WI0Jb-PgLvKRMW5GlfGXBPQcA,5691
|
71
78
|
je_editor/pyside_ui/main_ui/menu/text_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
79
|
je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py,sha256=k3pOpK4i8ccs3D8VIrNx8g3kUDp1fZdqv9H5uEvNl5c,3558
|
73
80
|
je_editor/pyside_ui/main_ui/save_settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -94,15 +101,15 @@ je_editor/utils/json_format/json_process.py,sha256=tszo48OnVivVkuuPrl-FtGaaq-1YO
|
|
94
101
|
je_editor/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
95
102
|
je_editor/utils/logging/loggin_instance.py,sha256=OFdWgra201B4f1vDM35M9L-47DK-8j-5HQEAq_ySSKM,841
|
96
103
|
je_editor/utils/multi_language/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
97
|
-
je_editor/utils/multi_language/english.py,sha256=
|
104
|
+
je_editor/utils/multi_language/english.py,sha256=A9I54gmcCNPEcFwNH_EMUkGYasSusiNUPLbFUTJewsE,6637
|
98
105
|
je_editor/utils/multi_language/multi_language_wrapper.py,sha256=_MtYrE51poQ1p_iWvT2eg_604uj6IsiBgGpifWpYLGc,1050
|
99
|
-
je_editor/utils/multi_language/traditional_chinese.py,sha256=
|
106
|
+
je_editor/utils/multi_language/traditional_chinese.py,sha256=MPCBCwd7KnSHgq86z77jS1EECnlFnpmRMKeqRO_fUM4,6667
|
100
107
|
je_editor/utils/redirect_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
101
|
-
je_editor/utils/redirect_manager/redirect_manager_class.py,sha256=
|
108
|
+
je_editor/utils/redirect_manager/redirect_manager_class.py,sha256=CHASOUD0Uob5jZrxK_lK9SE1TE1WCZEUfDPRGeJNSEs,2269
|
102
109
|
je_editor/utils/venv_check/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
103
110
|
je_editor/utils/venv_check/check_venv.py,sha256=oCrMdue4NYUUGrVifh_iHFwIgxVx9azYN4jz3Xiulgg,999
|
104
|
-
je_editor-0.0.
|
105
|
-
je_editor-0.0.
|
106
|
-
je_editor-0.0.
|
107
|
-
je_editor-0.0.
|
108
|
-
je_editor-0.0.
|
111
|
+
je_editor-0.0.205.dist-info/licenses/LICENSE,sha256=KMhUHh6pnIUvmXDW-49L_Sz63bqkOlPDqsecaqKiitU,1091
|
112
|
+
je_editor-0.0.205.dist-info/METADATA,sha256=7oCIeF9Yky6gvTDFWrgkxwTSWHNjkWC_9iEJY1tg6dk,3398
|
113
|
+
je_editor-0.0.205.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
114
|
+
je_editor-0.0.205.dist-info/top_level.txt,sha256=_9YA7BgxpkmdLs-5V_UQILxClcMRgPyG1a3qaE-Bkcs,10
|
115
|
+
je_editor-0.0.205.dist-info/RECORD,,
|
File without changes
|
File without changes
|