pygpt-net 2.6.21__py3-none-any.whl → 2.6.22__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.
- pygpt_net/CHANGELOG.txt +4 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +3 -1
- pygpt_net/controller/__init__.py +4 -8
- pygpt_net/controller/access/voice.py +2 -2
- pygpt_net/controller/assistant/batch.py +2 -3
- pygpt_net/controller/assistant/editor.py +2 -2
- pygpt_net/controller/assistant/files.py +2 -3
- pygpt_net/controller/assistant/store.py +2 -2
- pygpt_net/controller/audio/audio.py +2 -2
- pygpt_net/controller/ctx/ctx.py +2 -1
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +2 -2
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -4
- pygpt_net/controller/settings/profile.py +105 -124
- pygpt_net/controller/theme/menu.py +154 -57
- pygpt_net/controller/theme/nodes.py +51 -44
- pygpt_net/controller/theme/theme.py +33 -9
- pygpt_net/controller/tools/tools.py +2 -2
- pygpt_net/controller/ui/tabs.py +2 -3
- pygpt_net/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/filesystem/actions.py +1 -2
- pygpt_net/core/render/plain/helpers.py +2 -5
- pygpt_net/core/render/plain/renderer.py +26 -30
- pygpt_net/core/render/web/body.py +1 -1
- pygpt_net/core/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +4 -1
- pygpt_net/data/locale/locale.es.ini +4 -1
- pygpt_net/data/locale/locale.fr.ini +4 -1
- pygpt_net/data/locale/locale.it.ini +4 -1
- pygpt_net/data/locale/locale.pl.ini +5 -4
- pygpt_net/data/locale/locale.uk.ini +4 -1
- pygpt_net/data/locale/locale.zh.ini +4 -1
- pygpt_net/plugin/twitter/plugin.py +2 -2
- pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
- pygpt_net/tools/code_interpreter/body.py +1 -2
- pygpt_net/tools/code_interpreter/tool.py +7 -4
- pygpt_net/tools/code_interpreter/ui/html.py +1 -3
- pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
- pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
- pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
- pygpt_net/tools/indexer/ui/widgets.py +2 -4
- pygpt_net/tools/media_player/tool.py +2 -5
- pygpt_net/tools/media_player/ui/widgets.py +60 -36
- pygpt_net/tools/text_editor/ui/widgets.py +18 -19
- pygpt_net/tools/translator/ui/widgets.py +39 -35
- pygpt_net/ui/base/context_menu.py +9 -4
- pygpt_net/ui/dialog/db.py +1 -3
- pygpt_net/ui/dialog/models.py +1 -3
- pygpt_net/ui/dialog/models_importer.py +2 -4
- pygpt_net/ui/dialogs.py +34 -30
- pygpt_net/ui/layout/chat/attachments.py +72 -84
- pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
- pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
- pygpt_net/ui/layout/chat/calendar.py +100 -70
- pygpt_net/ui/layout/chat/chat.py +23 -17
- pygpt_net/ui/layout/chat/input.py +95 -118
- pygpt_net/ui/layout/chat/output.py +100 -162
- pygpt_net/ui/layout/chat/painter.py +89 -61
- pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
- pygpt_net/ui/layout/status.py +23 -14
- pygpt_net/ui/layout/toolbox/agent.py +27 -38
- pygpt_net/ui/layout/toolbox/agent_llama.py +42 -45
- pygpt_net/ui/layout/toolbox/assistants.py +42 -38
- pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
- pygpt_net/ui/layout/toolbox/footer.py +13 -16
- pygpt_net/ui/layout/toolbox/image.py +18 -21
- pygpt_net/ui/layout/toolbox/indexes.py +46 -89
- pygpt_net/ui/layout/toolbox/mode.py +20 -7
- pygpt_net/ui/layout/toolbox/model.py +12 -10
- pygpt_net/ui/layout/toolbox/presets.py +68 -52
- pygpt_net/ui/layout/toolbox/prompt.py +31 -58
- pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
- pygpt_net/ui/layout/toolbox/vision.py +20 -22
- pygpt_net/ui/main.py +2 -4
- pygpt_net/ui/menu/about.py +64 -84
- pygpt_net/ui/menu/audio.py +87 -63
- pygpt_net/ui/menu/config.py +121 -127
- pygpt_net/ui/menu/debug.py +69 -76
- pygpt_net/ui/menu/file.py +32 -35
- pygpt_net/ui/menu/menu.py +2 -3
- pygpt_net/ui/menu/plugins.py +69 -33
- pygpt_net/ui/menu/theme.py +45 -46
- pygpt_net/ui/menu/tools.py +56 -60
- pygpt_net/ui/menu/video.py +20 -25
- pygpt_net/ui/tray.py +1 -2
- pygpt_net/ui/widget/audio/bar.py +1 -3
- pygpt_net/ui/widget/audio/input_button.py +3 -4
- pygpt_net/ui/widget/calendar/select.py +1 -2
- pygpt_net/ui/widget/dialog/base.py +12 -9
- pygpt_net/ui/widget/dialog/editor_file.py +20 -23
- pygpt_net/ui/widget/dialog/find.py +25 -24
- pygpt_net/ui/widget/dialog/profile.py +57 -53
- pygpt_net/ui/widget/draw/painter.py +62 -93
- pygpt_net/ui/widget/element/button.py +42 -30
- pygpt_net/ui/widget/element/checkbox.py +23 -15
- pygpt_net/ui/widget/element/group.py +6 -5
- pygpt_net/ui/widget/element/labels.py +1 -2
- pygpt_net/ui/widget/filesystem/explorer.py +93 -102
- pygpt_net/ui/widget/image/display.py +1 -2
- pygpt_net/ui/widget/lists/assistant.py +1 -2
- pygpt_net/ui/widget/lists/attachment.py +1 -2
- pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
- pygpt_net/ui/widget/lists/context.py +2 -4
- pygpt_net/ui/widget/lists/index.py +1 -2
- pygpt_net/ui/widget/lists/model.py +1 -2
- pygpt_net/ui/widget/lists/model_editor.py +1 -2
- pygpt_net/ui/widget/lists/model_importer.py +1 -2
- pygpt_net/ui/widget/lists/preset.py +1 -2
- pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
- pygpt_net/ui/widget/lists/profile.py +1 -2
- pygpt_net/ui/widget/lists/uploaded.py +1 -2
- pygpt_net/ui/widget/option/checkbox.py +2 -4
- pygpt_net/ui/widget/option/checkbox_list.py +1 -4
- pygpt_net/ui/widget/option/cmd.py +1 -4
- pygpt_net/ui/widget/option/dictionary.py +25 -28
- pygpt_net/ui/widget/option/input.py +1 -3
- pygpt_net/ui/widget/tabs/Input.py +16 -12
- pygpt_net/ui/widget/tabs/body.py +5 -3
- pygpt_net/ui/widget/tabs/layout.py +36 -25
- pygpt_net/ui/widget/tabs/output.py +96 -74
- pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
- pygpt_net/ui/widget/textarea/editor.py +41 -73
- pygpt_net/ui/widget/textarea/find.py +11 -10
- pygpt_net/ui/widget/textarea/html.py +3 -6
- pygpt_net/ui/widget/textarea/input.py +63 -64
- pygpt_net/ui/widget/textarea/notepad.py +54 -38
- pygpt_net/ui/widget/textarea/output.py +65 -54
- pygpt_net/ui/widget/textarea/search_input.py +5 -4
- pygpt_net/ui/widget/textarea/web.py +2 -4
- pygpt_net/ui/widget/vision/camera.py +2 -31
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +15 -151
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +144 -144
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/entry_points.txt +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
@@ -15,7 +15,10 @@ import os
|
|
|
15
15
|
import shutil
|
|
16
16
|
from typing import Optional, Dict, Any, List
|
|
17
17
|
|
|
18
|
+
from PySide6.QtWidgets import QApplication
|
|
19
|
+
|
|
18
20
|
from pygpt_net.core.events import RenderEvent
|
|
21
|
+
from pygpt_net.utils import trans
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
class Settings:
|
|
@@ -116,7 +119,7 @@ class Settings:
|
|
|
116
119
|
"""Load defaults from file"""
|
|
117
120
|
file = self.window.ui.dialog['config.editor'].file
|
|
118
121
|
self.load_editor(file)
|
|
119
|
-
self.window.update_status("Restored from user file: {}"
|
|
122
|
+
self.window.update_status(f"Restored from user file: {file}")
|
|
120
123
|
|
|
121
124
|
def load_default_editor_app(self):
|
|
122
125
|
"""Load defaults from file (app)"""
|
|
@@ -125,11 +128,11 @@ class Settings:
|
|
|
125
128
|
if basename.endswith(".css"):
|
|
126
129
|
path = str(os.path.join(self.window.core.config.get_app_path(), "data", "css", basename))
|
|
127
130
|
self.load_editor(file, path)
|
|
128
|
-
self.window.update_status("Restored from app defaults: {}"
|
|
131
|
+
self.window.update_status(f"Restored from app defaults: {basename}")
|
|
129
132
|
elif basename.endswith(".json"):
|
|
130
133
|
path = str(os.path.join(self.window.core.config.get_app_path(), "data", "config", basename))
|
|
131
134
|
self.load_editor(file, path)
|
|
132
|
-
self.window.update_status("Restored from app defaults: {}"
|
|
135
|
+
self.window.update_status(f"Restored from app defaults: {basename}")
|
|
133
136
|
|
|
134
137
|
def load_editor(
|
|
135
138
|
self,
|
|
@@ -151,13 +154,14 @@ class Settings:
|
|
|
151
154
|
self.window.ui.paths['config'].setText(path)
|
|
152
155
|
|
|
153
156
|
self.window.ui.dialog['config.editor'].file = file
|
|
157
|
+
|
|
154
158
|
try:
|
|
155
159
|
with open(path, 'r', encoding="utf-8") as f:
|
|
156
160
|
txt = f.read()
|
|
157
161
|
self.window.ui.editor['config'].setPlainText(txt)
|
|
158
162
|
except Exception as e:
|
|
159
163
|
self.window.core.debug.log(e)
|
|
160
|
-
self.window.update_status("Error loading file: {}"
|
|
164
|
+
self.window.update_status(f"Error loading file: {e}")
|
|
161
165
|
|
|
162
166
|
def save_editor(self):
|
|
163
167
|
"""Save file to disk"""
|
|
@@ -170,8 +174,8 @@ class Settings:
|
|
|
170
174
|
try:
|
|
171
175
|
json.loads(data)
|
|
172
176
|
except Exception as e:
|
|
173
|
-
self.window.update_status("This is not a valid JSON: {}"
|
|
174
|
-
self.window.ui.dialogs.alert("This is not a valid JSON: {}"
|
|
177
|
+
self.window.update_status(f"This is not a valid JSON: {e}")
|
|
178
|
+
self.window.ui.dialogs.alert(f"This is not a valid JSON: {e}")
|
|
175
179
|
return
|
|
176
180
|
path = os.path.join(self.window.core.config.get_user_path(), file)
|
|
177
181
|
elif file.endswith('.css'):
|
|
@@ -189,22 +193,48 @@ class Settings:
|
|
|
189
193
|
backup_path = os.path.join(self.window.core.config.get_user_path(), backup_file)
|
|
190
194
|
if os.path.isfile(path):
|
|
191
195
|
shutil.copyfile(path, backup_path)
|
|
192
|
-
self.window.update_status("Created backup file: {}"
|
|
196
|
+
self.window.update_status(f"Created backup file: {backup_file}")
|
|
197
|
+
|
|
198
|
+
prev_content = None
|
|
199
|
+
if os.path.isfile(path):
|
|
200
|
+
try:
|
|
201
|
+
with open(path, 'r', encoding="utf-8") as f:
|
|
202
|
+
prev_content = f.read()
|
|
203
|
+
except Exception as e:
|
|
204
|
+
pass
|
|
193
205
|
|
|
194
206
|
# save changes to current file
|
|
195
207
|
try:
|
|
196
208
|
with open(path, 'w', encoding="utf-8") as f:
|
|
197
209
|
f.write(data)
|
|
198
|
-
self.window.update_status("Saved file: {}"
|
|
199
|
-
|
|
210
|
+
self.window.update_status(f"Saved file: {path}")
|
|
211
|
+
except Exception as e:
|
|
212
|
+
self.window.core.debug.log(e)
|
|
213
|
+
self.window.update_status(f"Error saving file: {path}")
|
|
214
|
+
return # abort if error
|
|
215
|
+
|
|
216
|
+
if prev_content == data:
|
|
217
|
+
self.window.update_status(f"Saved file: {path}")
|
|
218
|
+
self.window.ui.dialogs.alert(f"Saved file: {path}")
|
|
219
|
+
return # no changes made, no need to reload
|
|
220
|
+
|
|
221
|
+
if file in ("config.json", "models.json") or file.endswith('.css'):
|
|
222
|
+
self.window.update_status(trans("status.reloading"))
|
|
223
|
+
|
|
224
|
+
QApplication.processEvents() # process events to update UI
|
|
225
|
+
|
|
226
|
+
try:
|
|
200
227
|
if file == "config.json":
|
|
201
228
|
self.window.core.config.load_config() # reload config
|
|
202
229
|
elif file == "models.json":
|
|
203
230
|
self.window.core.models.load() # reload models
|
|
204
231
|
elif file.endswith('.css'):
|
|
205
|
-
|
|
206
|
-
self.window.dispatch(event)
|
|
232
|
+
self.window.dispatch(RenderEvent(RenderEvent.ON_THEME_CHANGE))
|
|
207
233
|
self.window.controller.theme.reload(force=True) # reload theme
|
|
234
|
+
self.window.update_status(f"Saved file: {path}")
|
|
235
|
+
self.window.ui.dialogs.alert(f"Saved file: {path}")
|
|
208
236
|
except Exception as e:
|
|
209
237
|
self.window.core.debug.log(e)
|
|
210
|
-
self.window.update_status("Error
|
|
238
|
+
self.window.update_status(f"Error reloading saved file: {path}")
|
|
239
|
+
|
|
240
|
+
|
pygpt_net/core/tabs/tabs.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import uuid
|
|
@@ -559,6 +559,19 @@ class Tabs:
|
|
|
559
559
|
tab.tooltip = tabs.tabToolTip(tab.idx)
|
|
560
560
|
tab.updated_at = datetime.now()
|
|
561
561
|
|
|
562
|
+
def insert_tab(self, tabs, tab: Tab) -> int:
|
|
563
|
+
"""
|
|
564
|
+
Insert tab into the specified tab widget
|
|
565
|
+
|
|
566
|
+
:param tabs: Tabs instance
|
|
567
|
+
:param tab: Tab instance
|
|
568
|
+
:return: new index of the tab
|
|
569
|
+
"""
|
|
570
|
+
if tab.new_idx is not None:
|
|
571
|
+
return tabs.insertTab(tab.new_idx, tab.child, tab.title)
|
|
572
|
+
else:
|
|
573
|
+
return tabs.addTab(tab.child, tab.title)
|
|
574
|
+
|
|
562
575
|
def add_chat(self, tab: Tab):
|
|
563
576
|
"""
|
|
564
577
|
Add chat tab
|
|
@@ -569,10 +582,7 @@ class Tabs:
|
|
|
569
582
|
tabs = column.get_tabs()
|
|
570
583
|
tab.parent = column
|
|
571
584
|
tab.child = self.window.core.ctx.container.get(tab) # tab is already appended here
|
|
572
|
-
|
|
573
|
-
tab.idx = tabs.insertTab(tab.new_idx, tab.child, tab.title)
|
|
574
|
-
else:
|
|
575
|
-
tab.idx = tabs.addTab(tab.child, tab.title)
|
|
585
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
576
586
|
tab.child.setOwner(tab)
|
|
577
587
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
578
588
|
if tab.tooltip is not None:
|
|
@@ -593,10 +603,7 @@ class Tabs:
|
|
|
593
603
|
idx = tab.data_id # restore prev idx
|
|
594
604
|
tab.child, idx, data_id = self.window.controller.notepad.create(idx, tab)
|
|
595
605
|
tab.data_id = data_id # notepad idx in db, enumerated from 1
|
|
596
|
-
|
|
597
|
-
tab.idx = tabs.insertTab(tab.new_idx, tab.child, tab.title)
|
|
598
|
-
else:
|
|
599
|
-
tab.idx = tabs.addTab(tab.child, tab.title)
|
|
606
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
600
607
|
tab.child.setOwner(tab)
|
|
601
608
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
602
609
|
if tab.tooltip is not None:
|
|
@@ -612,7 +619,7 @@ class Tabs:
|
|
|
612
619
|
tabs = column.get_tabs()
|
|
613
620
|
tab.parent = column
|
|
614
621
|
tab.child = self.window.ui.chat.output.explorer.setup()
|
|
615
|
-
tab.idx =
|
|
622
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
616
623
|
tab.child.setOwner(tab)
|
|
617
624
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
618
625
|
if tab.tooltip is not None:
|
|
@@ -629,7 +636,7 @@ class Tabs:
|
|
|
629
636
|
tab.parent = column
|
|
630
637
|
tab.child = self.window.ui.chat.output.painter.setup()
|
|
631
638
|
tab.child.append(self.window.ui.painter)
|
|
632
|
-
tab.idx =
|
|
639
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
633
640
|
tab.child.setOwner(tab)
|
|
634
641
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
635
642
|
if tab.tooltip is not None:
|
|
@@ -645,7 +652,7 @@ class Tabs:
|
|
|
645
652
|
tabs = column.get_tabs()
|
|
646
653
|
tab.parent = column
|
|
647
654
|
tab.child = self.window.ui.chat.output.calendar.setup()
|
|
648
|
-
tab.idx =
|
|
655
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
649
656
|
tab.child.setOwner(tab)
|
|
650
657
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
651
658
|
if tab.tooltip is not None:
|
|
@@ -669,7 +676,7 @@ class Tabs:
|
|
|
669
676
|
tab.title = trans(tool.tab_title)
|
|
670
677
|
tab.parent = column
|
|
671
678
|
tab.child = self.from_widget(widget)
|
|
672
|
-
tab.idx =
|
|
679
|
+
tab.idx = self.insert_tab(tabs, tab)
|
|
673
680
|
tab.child.setOwner(tab)
|
|
674
681
|
tabs.setTabIcon(tab.idx, QIcon(tab.icon))
|
|
675
682
|
if tab.tooltip is not None:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"__meta__": {
|
|
3
|
-
"version": "2.6.
|
|
4
|
-
"app.version": "2.6.
|
|
5
|
-
"updated_at": "2025-08-
|
|
3
|
+
"version": "2.6.22",
|
|
4
|
+
"app.version": "2.6.22",
|
|
5
|
+
"updated_at": "2025-08-25T00:00:00"
|
|
6
6
|
},
|
|
7
7
|
"access.audio.event.speech": false,
|
|
8
8
|
"access.audio.event.speech.disabled": [],
|
|
@@ -422,7 +422,7 @@
|
|
|
422
422
|
}
|
|
423
423
|
},
|
|
424
424
|
"temperature": 1.0,
|
|
425
|
-
"theme": "
|
|
425
|
+
"theme": "dark_darker",
|
|
426
426
|
"theme.markdown": true,
|
|
427
427
|
"theme.style": "chatgpt",
|
|
428
428
|
"top_p": 1.0,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"__meta__": {
|
|
3
|
-
"version": "2.6.
|
|
4
|
-
"app.version": "2.6.
|
|
5
|
-
"updated_at": "2025-08-
|
|
3
|
+
"version": "2.6.22",
|
|
4
|
+
"app.version": "2.6.22",
|
|
5
|
+
"updated_at": "2025-08-25T23:07:35"
|
|
6
6
|
},
|
|
7
7
|
"items": {
|
|
8
8
|
"SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
|
|
@@ -1347,6 +1347,9 @@ status.preset.deleted = Voreinstellung gelöscht
|
|
|
1347
1347
|
status.preset.duplicated = Voreinstellung dupliziert
|
|
1348
1348
|
status.preset.empty_id = WARNUNG: Voreinstellungs-ID (Dateiname) ist leer! Abbruch...
|
|
1349
1349
|
status.preset.saved = Voreinstellung gespeichert
|
|
1350
|
+
status.reloading = Aktualisieren... Bitte warten
|
|
1351
|
+
status.reloading.profile.begin = Aktualisieren der Komponenten... bitte warten...
|
|
1352
|
+
status.reloading.profile.end = [OK] Komponenten erfolgreich aktualisiert.
|
|
1350
1353
|
status.saved = Gespeichert
|
|
1351
1354
|
status.sending = Bitte warten...
|
|
1352
1355
|
status.started = Bereit
|
|
@@ -1356,7 +1359,7 @@ status.tokens = Token
|
|
|
1356
1359
|
status.uploaded = Dateien hochgeladen
|
|
1357
1360
|
status.uploading = Dateien hochladen...
|
|
1358
1361
|
tab.close_all.confirm = Bist du sicher, dass du alle Tabs schließen möchtest?
|
|
1359
|
-
text.context_menu.audio.read =
|
|
1362
|
+
text.context_menu.audio.read = Lesen (Sprachsynthese)
|
|
1360
1363
|
text.context_menu.copy_to = Kopieren zu...
|
|
1361
1364
|
text.context_menu.copy_to.calendar = Kalender
|
|
1362
1365
|
text.context_menu.copy_to.input = Eingabe
|
|
@@ -1359,6 +1359,9 @@ status.preset.deleted = Preset has been deleted.
|
|
|
1359
1359
|
status.preset.duplicated = Preset has been duplicated.
|
|
1360
1360
|
status.preset.empty_id = WARNING: Preset ID (filename) is empty! Aborting...
|
|
1361
1361
|
status.preset.saved = Preset has been saved.
|
|
1362
|
+
status.reloading = Reloading... Please wait
|
|
1363
|
+
status.reloading.profile.begin = Reloading components... please wait...
|
|
1364
|
+
status.reloading.profile.end = [OK] Components reloaded successfully.
|
|
1362
1365
|
status.saved = Saved
|
|
1363
1366
|
status.sending = Please wait...
|
|
1364
1367
|
status.started = Ready
|
|
@@ -1368,7 +1371,7 @@ status.tokens = Tokens
|
|
|
1368
1371
|
status.uploaded = Files have been uploaded
|
|
1369
1372
|
status.uploading = Uploading files...
|
|
1370
1373
|
tab.close_all.confirm = Are you sure you want to close all tabs?
|
|
1371
|
-
text.context_menu.audio.read = Read
|
|
1374
|
+
text.context_menu.audio.read = Read (speech synthesis)
|
|
1372
1375
|
text.context_menu.copy_to = Copy to...
|
|
1373
1376
|
text.context_menu.copy_to.calendar = Calendar
|
|
1374
1377
|
text.context_menu.copy_to.input = Input
|
|
@@ -1348,6 +1348,9 @@ status.preset.deleted = Ajuste preestablecido eliminado
|
|
|
1348
1348
|
status.preset.duplicated = Ajuste preestablecido duplicado
|
|
1349
1349
|
status.preset.empty_id = ADVERTENCIA: ¡El ID del ajuste preestablecido (nombre de archivo) está vacío! Abortando...
|
|
1350
1350
|
status.preset.saved = Ajuste preestablecido guardado
|
|
1351
|
+
status.reloading = Actualizando... Por favor, espere
|
|
1352
|
+
status.reloading.profile.begin = Actualizando componentes... por favor, espere...
|
|
1353
|
+
status.reloading.profile.end = [OK] Componentes actualizados con éxito.
|
|
1351
1354
|
status.saved = Guardado
|
|
1352
1355
|
status.sending = Por favor, espere...
|
|
1353
1356
|
status.started = Listo
|
|
@@ -1357,7 +1360,7 @@ status.tokens = Tokens
|
|
|
1357
1360
|
status.uploaded = Archivos subidos
|
|
1358
1361
|
status.uploading = Subiendo archivos...
|
|
1359
1362
|
tab.close_all.confirm = ¿Estás seguro de cerrar todas las pestañas?
|
|
1360
|
-
text.context_menu.audio.read = Leer
|
|
1363
|
+
text.context_menu.audio.read = Leer (síntesis de voz)
|
|
1361
1364
|
text.context_menu.copy_to = Copiar a...
|
|
1362
1365
|
text.context_menu.copy_to.calendar = Calendario
|
|
1363
1366
|
text.context_menu.copy_to.input = Entrada
|
|
@@ -1347,6 +1347,9 @@ status.preset.deleted = Préréglage supprimé
|
|
|
1347
1347
|
status.preset.duplicated = Préréglage dupliqué
|
|
1348
1348
|
status.preset.empty_id = ATTENTION : L'ID du préréglage (nom de fichier) est vide ! Annulation...
|
|
1349
1349
|
status.preset.saved = Préréglage sauvegardé
|
|
1350
|
+
status.reloading = Actualisation... Veuillez patienter
|
|
1351
|
+
status.reloading.profile.begin = Actualisation des composants... veuillez patienter...
|
|
1352
|
+
status.reloading.profile.end = [OK] Composants actualisés avec succès.
|
|
1350
1353
|
status.saved = Sauvegardé
|
|
1351
1354
|
status.sending = Veuillez patienter...
|
|
1352
1355
|
status.started = Prêt
|
|
@@ -1356,7 +1359,7 @@ status.tokens = Jetons
|
|
|
1356
1359
|
status.uploaded = Les fichiers sont téléversés
|
|
1357
1360
|
status.uploading = Téléversement des fichiers...
|
|
1358
1361
|
tab.close_all.confirm = Êtes-vous sûr de vouloir fermer tous les onglets ?
|
|
1359
|
-
text.context_menu.audio.read = Lire
|
|
1362
|
+
text.context_menu.audio.read = Lire (synthèse vocale)
|
|
1360
1363
|
text.context_menu.copy_to = Copier vers...
|
|
1361
1364
|
text.context_menu.copy_to.calendar = Calendrier
|
|
1362
1365
|
text.context_menu.copy_to.input = Entrée
|
|
@@ -1347,6 +1347,9 @@ status.preset.deleted = Preset cancellato.
|
|
|
1347
1347
|
status.preset.duplicated = Preset duplicato.
|
|
1348
1348
|
status.preset.empty_id = ATTENZIONE: ID del preset (nome del file) vuoto! Annullamento...
|
|
1349
1349
|
status.preset.saved = Preset salvato.
|
|
1350
|
+
status.reloading = Aggiornamento in corso... Attendere
|
|
1351
|
+
status.reloading.profile.begin = Aggiornamento dei componenti... attendere...
|
|
1352
|
+
status.reloading.profile.end = [OK] Componenti aggiornati con successo.
|
|
1350
1353
|
status.saved = Salvato.
|
|
1351
1354
|
status.sending = Attendere...
|
|
1352
1355
|
status.started = Pronto.
|
|
@@ -1356,7 +1359,7 @@ status.tokens = Token.
|
|
|
1356
1359
|
status.uploaded = I file sono stati caricati.
|
|
1357
1360
|
status.uploading = Caricamento dei file...
|
|
1358
1361
|
tab.close_all.confirm = Sei sicuro di voler chiudere tutte le schede?
|
|
1359
|
-
text.context_menu.audio.read = Leggi
|
|
1362
|
+
text.context_menu.audio.read = Leggi (sintesi vocale)
|
|
1360
1363
|
text.context_menu.copy_to = Copia a...
|
|
1361
1364
|
text.context_menu.copy_to.calendar = Calendario
|
|
1362
1365
|
text.context_menu.copy_to.input = Input
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
[LOCALE]
|
|
2
|
-
|
|
3
|
-
|
|
4
2
|
about.btn.github = GitHub
|
|
5
3
|
about.btn.support = Wsparcie
|
|
6
4
|
about.btn.website = WWW
|
|
@@ -1344,12 +1342,15 @@ status.evaluating = Proszę czekać... ocena w toku...
|
|
|
1344
1342
|
status.finished = Zakończono.
|
|
1345
1343
|
status.img.generated = Obraz został wygenerowany.
|
|
1346
1344
|
status.img.saved = Obraz został zapisany
|
|
1347
|
-
status.loading = Ładowanie... Proszę czekać
|
|
1345
|
+
status.loading = Ładowanie... Proszę czekać
|
|
1348
1346
|
status.preset.cleared = Preset wyczyszczony
|
|
1349
1347
|
status.preset.deleted = Preset usunięty
|
|
1350
1348
|
status.preset.duplicated = Preset skopiowany
|
|
1351
1349
|
status.preset.empty_id = Uwaga: nie podano ID dla presetu!
|
|
1352
1350
|
status.preset.saved = Preset zapisany
|
|
1351
|
+
status.reloading = Odświeżanie... Proszę czekać
|
|
1352
|
+
status.reloading.profile.begin = Odświeżanie komponentów... proszę czekać...
|
|
1353
|
+
status.reloading.profile.end = [OK] Komponenty zostały pomyślnie odświeżone.
|
|
1353
1354
|
status.saved = Zapisano
|
|
1354
1355
|
status.sending = Czekaj...
|
|
1355
1356
|
status.started = Gotowy
|
|
@@ -1359,7 +1360,7 @@ status.tokens = Tokenów
|
|
|
1359
1360
|
status.uploaded = Pliki wgrane na serwer
|
|
1360
1361
|
status.uploading = Upload plików...
|
|
1361
1362
|
tab.close_all.confirm = Czy na pewno chcesz zamknąć wszystkie karty?
|
|
1362
|
-
text.context_menu.audio.read =
|
|
1363
|
+
text.context_menu.audio.read = Czytaj (synteza mowy)
|
|
1363
1364
|
text.context_menu.copy_to = Kopiuj do...
|
|
1364
1365
|
text.context_menu.copy_to.calendar = Kalendarz
|
|
1365
1366
|
text.context_menu.copy_to.input = Wejście (input)
|
|
@@ -1347,6 +1347,9 @@ status.preset.deleted = Пресет видалено
|
|
|
1347
1347
|
status.preset.duplicated = Пресет дубльовано
|
|
1348
1348
|
status.preset.empty_id = УВАГА: ID пресету (ім'я файлу) порожній! Скасовано...
|
|
1349
1349
|
status.preset.saved = Пресет збережено
|
|
1350
|
+
status.reloading = Оновлення... Будь ласка, зачекайте
|
|
1351
|
+
status.reloading.profile.begin = Оновлення компонентів... будь ласка, зачекайте...
|
|
1352
|
+
status.reloading.profile.end = [OK] Компоненти успішно оновлено.
|
|
1350
1353
|
status.saved = Збережено
|
|
1351
1354
|
status.sending = Будь ласка, зачекайте...
|
|
1352
1355
|
status.started = Готово
|
|
@@ -1356,7 +1359,7 @@ status.tokens = Токени
|
|
|
1356
1359
|
status.uploaded = Файли завантажено
|
|
1357
1360
|
status.uploading = Вивантаження файлів...
|
|
1358
1361
|
tab.close_all.confirm = Ви впевнені, що хочете закрити всі вкладки?
|
|
1359
|
-
text.context_menu.audio.read = Читати
|
|
1362
|
+
text.context_menu.audio.read = Читати (синтез мови)
|
|
1360
1363
|
text.context_menu.copy_to = Копіювати до...
|
|
1361
1364
|
text.context_menu.copy_to.calendar = Календар
|
|
1362
1365
|
text.context_menu.copy_to.input = Введення
|
|
@@ -1347,6 +1347,9 @@ status.preset.deleted = 预设已删除。
|
|
|
1347
1347
|
status.preset.duplicated = 预设已复制。
|
|
1348
1348
|
status.preset.empty_id = 警告:预设 ID(文件名)为空!正在中止...
|
|
1349
1349
|
status.preset.saved = 预设已保存。
|
|
1350
|
+
status.reloading = 正在刷新... 请稍候
|
|
1351
|
+
status.reloading.profile.begin = 正在刷新组件... 请稍候...
|
|
1352
|
+
status.reloading.profile.end = [OK] 组件刷新成功。
|
|
1350
1353
|
status.saved = 已保存
|
|
1351
1354
|
status.sending = 请稍候...
|
|
1352
1355
|
status.started = 准备好
|
|
@@ -1356,7 +1359,7 @@ status.tokens = 令牌
|
|
|
1356
1359
|
status.uploaded = 文件已上傳
|
|
1357
1360
|
status.uploading = 正在上傳文件...
|
|
1358
1361
|
tab.close_all.confirm = 确定要关闭所有标签页吗?
|
|
1359
|
-
text.context_menu.audio.read =
|
|
1362
|
+
text.context_menu.audio.read = 阅读(语音合成)
|
|
1360
1363
|
text.context_menu.copy_to = 複製到...
|
|
1361
1364
|
text.context_menu.copy_to.calendar = 日曆
|
|
1362
1365
|
text.context_menu.copy_to.input = 輸入
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.plugin.base.plugin import BasePlugin
|
|
@@ -20,7 +20,7 @@ class Plugin(BasePlugin):
|
|
|
20
20
|
def __init__(self, *args, **kwargs):
|
|
21
21
|
super(Plugin, self).__init__(*args, **kwargs)
|
|
22
22
|
self.id = "twitter"
|
|
23
|
-
self.name = "Twitter
|
|
23
|
+
self.name = "X/Twitter"
|
|
24
24
|
self.description = "Interact with tweets and users, manage bookmarks and media, perform likes, retweets, and more."
|
|
25
25
|
self.prefix = "API"
|
|
26
26
|
self.order = 100
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
@@ -20,6 +20,7 @@ from pygpt_net.utils import trans
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class AudioTranscribe:
|
|
23
|
+
|
|
23
24
|
def __init__(self, window=None):
|
|
24
25
|
"""
|
|
25
26
|
Audio Transcribe dialog
|
|
@@ -31,30 +32,21 @@ class AudioTranscribe:
|
|
|
31
32
|
self.file_menu = None
|
|
32
33
|
self.actions = {}
|
|
33
34
|
|
|
34
|
-
def setup_menu(self) -> QMenuBar:
|
|
35
|
+
def setup_menu(self, parent=None) -> QMenuBar:
|
|
35
36
|
"""Setup audio transcriber dialog menu"""
|
|
36
|
-
self.menu_bar = QMenuBar()
|
|
37
|
+
self.menu_bar = QMenuBar(parent)
|
|
37
38
|
self.file_menu = self.menu_bar.addMenu(trans("menu.file"))
|
|
39
|
+
t = self.window.tools.get("transcriber")
|
|
40
|
+
|
|
41
|
+
self.actions["open"] = QAction(QIcon(":/icons/folder.svg"), trans("action.open"), self.menu_bar)
|
|
42
|
+
self.actions["open"].triggered.connect(lambda checked=False, t=t: t.open_file())
|
|
43
|
+
|
|
44
|
+
self.actions["save_as"] = QAction(QIcon(":/icons/save.svg"), trans("action.save_as"), self.menu_bar)
|
|
45
|
+
self.actions["save_as"].triggered.connect(lambda checked=False, t=t: t.save_as_file())
|
|
46
|
+
|
|
47
|
+
self.actions["exit"] = QAction(QIcon(":/icons/logout.svg"), trans("menu.file.exit"), self.menu_bar)
|
|
48
|
+
self.actions["exit"].triggered.connect(lambda checked=False, t=t: t.close())
|
|
38
49
|
|
|
39
|
-
# open
|
|
40
|
-
self.actions["open"] = QAction(QIcon(":/icons/folder.svg"), trans("action.open"))
|
|
41
|
-
self.actions["open"].triggered.connect(
|
|
42
|
-
lambda: self.window.tools.get("transcriber").open_file()
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
# save as
|
|
46
|
-
self.actions["save_as"] = QAction(QIcon(":/icons/save.svg"), trans("action.save_as"))
|
|
47
|
-
self.actions["save_as"].triggered.connect(
|
|
48
|
-
lambda: self.window.tools.get("transcriber").save_as_file()
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# exit
|
|
52
|
-
self.actions["exit"] = QAction(QIcon(":/icons/logout.svg"), trans("menu.file.exit"))
|
|
53
|
-
self.actions["exit"].triggered.connect(
|
|
54
|
-
lambda: self.window.tools.get("transcriber").close()
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
# add actions
|
|
58
50
|
self.file_menu.addAction(self.actions["open"])
|
|
59
51
|
self.file_menu.addAction(self.actions["save_as"])
|
|
60
52
|
self.file_menu.addAction(self.actions["exit"])
|
|
@@ -63,53 +55,51 @@ class AudioTranscribe:
|
|
|
63
55
|
def setup(self):
|
|
64
56
|
"""Setup transcriber dialog"""
|
|
65
57
|
id = 'audio.transcribe'
|
|
58
|
+
u = self.window.ui
|
|
59
|
+
t = self.window.tools.get("transcriber")
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
self.window.ui.editor[id].setProperty('class', 'code-editor')
|
|
61
|
+
u.dialog['audio.transcribe'] = AudioTranscribeDialog(self.window)
|
|
62
|
+
dlg = u.dialog['audio.transcribe']
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
lambda: self.window.tools.get("transcriber").toggle_auto_convert()
|
|
75
|
-
)
|
|
64
|
+
u.editor[id] = CodeEditor(self.window)
|
|
65
|
+
u.editor[id].setReadOnly(False)
|
|
66
|
+
u.editor[id].setProperty('class', 'code-editor')
|
|
76
67
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
)
|
|
68
|
+
u.nodes['audio.transcribe.convert_video'] = QCheckBox(trans("audio.transcribe.auto_convert"))
|
|
69
|
+
u.nodes['audio.transcribe.convert_video'].setChecked(True)
|
|
70
|
+
u.nodes['audio.transcribe.convert_video'].clicked.connect(lambda checked=False, t=t: t.toggle_auto_convert())
|
|
81
71
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
)
|
|
72
|
+
u.nodes['audio.transcribe.clear'] = QPushButton(trans("dialog.logger.btn.clear"))
|
|
73
|
+
u.nodes['audio.transcribe.clear'].clicked.connect(self.clear)
|
|
74
|
+
|
|
75
|
+
u.nodes['audio.transcribe.open'] = QPushButton(trans("audio.transcribe.open"))
|
|
76
|
+
u.nodes['audio.transcribe.open'].clicked.connect(lambda checked=False, t=t: t.open_file())
|
|
86
77
|
|
|
87
78
|
bottom_layout = QHBoxLayout()
|
|
88
|
-
bottom_layout.addWidget(
|
|
89
|
-
bottom_layout.addWidget(
|
|
79
|
+
bottom_layout.addWidget(u.nodes['audio.transcribe.clear'])
|
|
80
|
+
bottom_layout.addWidget(u.nodes['audio.transcribe.open'])
|
|
90
81
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
u.nodes['audio.transcribe.title'] = HelpLabel(trans("audio.transcribe.tip"))
|
|
83
|
+
u.nodes['audio.transcribe.status'] = QLabel("...")
|
|
84
|
+
u.nodes['audio.transcribe.status'].setAlignment(Qt.AlignCenter)
|
|
85
|
+
u.nodes['audio.transcribe.status'].setWordWrap(True)
|
|
95
86
|
|
|
96
87
|
layout = QVBoxLayout()
|
|
97
|
-
layout.setMenuBar(self.setup_menu())
|
|
98
|
-
layout.addWidget(
|
|
99
|
-
layout.addWidget(
|
|
88
|
+
layout.setMenuBar(self.setup_menu(dlg))
|
|
89
|
+
layout.addWidget(u.editor[id])
|
|
90
|
+
layout.addWidget(u.nodes['audio.transcribe.title'])
|
|
100
91
|
layout.addLayout(bottom_layout)
|
|
101
|
-
layout.addWidget(
|
|
102
|
-
layout.addWidget(
|
|
103
|
-
|
|
104
|
-
self.window.ui.dialog['audio.transcribe'] = AudioTranscribeDialog(self.window)
|
|
105
|
-
self.window.ui.dialog['audio.transcribe'].setLayout(layout)
|
|
106
|
-
self.window.ui.dialog['audio.transcribe'].setWindowTitle(trans("audio.transcribe.title"))
|
|
92
|
+
layout.addWidget(u.nodes['audio.transcribe.convert_video'])
|
|
93
|
+
layout.addWidget(u.nodes['audio.transcribe.status'])
|
|
107
94
|
|
|
95
|
+
dlg.setLayout(layout)
|
|
96
|
+
dlg.setWindowTitle(trans("audio.transcribe.title"))
|
|
108
97
|
|
|
109
98
|
def clear(self):
|
|
110
99
|
"""Clear transcribe dialog"""
|
|
111
100
|
self.window.tools.get("transcriber").clear()
|
|
112
101
|
|
|
102
|
+
|
|
113
103
|
class AudioTranscribeDialog(BaseDialog):
|
|
114
104
|
def __init__(self, window=None, id=None):
|
|
115
105
|
"""
|
|
@@ -139,7 +129,7 @@ class AudioTranscribeDialog(BaseDialog):
|
|
|
139
129
|
"""
|
|
140
130
|
if event.key() == Qt.Key_Escape:
|
|
141
131
|
self.cleanup()
|
|
142
|
-
self.close()
|
|
132
|
+
self.close()
|
|
143
133
|
else:
|
|
144
134
|
super(AudioTranscribeDialog, self).keyPressEvent(event)
|
|
145
135
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -140,7 +140,6 @@ class Body:
|
|
|
140
140
|
</style>
|
|
141
141
|
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
|
142
142
|
<script type="text/javascript" src="qrc:///js/highlight.min.js"></script>
|
|
143
|
-
<script type="text/javascript" src="qrc:///js/auto-render.min.js"></script>
|
|
144
143
|
<script>
|
|
145
144
|
|
|
146
145
|
let scrollTimeout = null;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import json
|
|
@@ -26,7 +26,7 @@ from pygpt_net.item.ctx import CtxItem
|
|
|
26
26
|
from pygpt_net.utils import trans
|
|
27
27
|
from .ui.html import HtmlOutput, CodeBlock
|
|
28
28
|
|
|
29
|
-
from .ui.widgets import PythonInput,
|
|
29
|
+
from .ui.widgets import PythonInput, ToolWidget, ToolSignals
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class CodeInterpreter(BaseTool):
|
|
@@ -48,6 +48,7 @@ class CodeInterpreter(BaseTool):
|
|
|
48
48
|
self.ipython = True
|
|
49
49
|
self.auto_opened = False
|
|
50
50
|
self.signals = ToolSignals()
|
|
51
|
+
self.max_history_size = 1000 # max history lines
|
|
51
52
|
|
|
52
53
|
# interpreter data files in /data directory
|
|
53
54
|
self.file_current = ".interpreter.current.py"
|
|
@@ -366,11 +367,13 @@ class CodeInterpreter(BaseTool):
|
|
|
366
367
|
|
|
367
368
|
def save_history(self, input: str):
|
|
368
369
|
"""
|
|
369
|
-
Save input data
|
|
370
|
+
Save input data (history)
|
|
370
371
|
|
|
371
372
|
:param input: Input data
|
|
372
373
|
"""
|
|
373
374
|
path = self.get_path_input()
|
|
375
|
+
if self.max_history_size > 0 and isinstance(input, str):
|
|
376
|
+
input = ''.join(input.splitlines(True)[-self.max_history_size:])
|
|
374
377
|
with open(path , "w", encoding="utf-8") as f:
|
|
375
378
|
f.write(input)
|
|
376
379
|
|
|
@@ -431,7 +434,7 @@ class CodeInterpreter(BaseTool):
|
|
|
431
434
|
self.window.controller.command.dispatch_only(event)
|
|
432
435
|
self.signals.focus_input.emit()
|
|
433
436
|
event = KernelEvent(KernelEvent.STATUS, {
|
|
434
|
-
'status': "[OK] Kernel restarted at
|
|
437
|
+
'status': f"[OK] Kernel restarted at {strftime('%H:%M:%S')}.",
|
|
435
438
|
})
|
|
436
439
|
self.window.dispatch(event)
|
|
437
440
|
|