pygpt-net 2.6.1__py3-none-any.whl → 2.6.6__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 +23 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +20 -1
- pygpt_net/config.py +55 -65
- pygpt_net/controller/__init__.py +5 -2
- pygpt_net/controller/calendar/note.py +101 -126
- pygpt_net/controller/chat/chat.py +38 -35
- pygpt_net/controller/chat/render.py +154 -214
- pygpt_net/controller/chat/response.py +5 -3
- pygpt_net/controller/chat/stream.py +92 -27
- pygpt_net/controller/config/config.py +39 -42
- pygpt_net/controller/config/field/checkbox.py +16 -12
- pygpt_net/controller/config/field/checkbox_list.py +36 -31
- pygpt_net/controller/config/field/cmd.py +51 -57
- pygpt_net/controller/config/field/combo.py +33 -16
- pygpt_net/controller/config/field/dictionary.py +48 -55
- pygpt_net/controller/config/field/input.py +50 -32
- pygpt_net/controller/config/field/slider.py +40 -45
- pygpt_net/controller/config/field/textarea.py +20 -6
- pygpt_net/controller/config/placeholder.py +110 -231
- pygpt_net/controller/ctx/common.py +48 -48
- pygpt_net/controller/ctx/ctx.py +91 -132
- pygpt_net/controller/lang/mapping.py +57 -95
- pygpt_net/controller/lang/plugins.py +64 -55
- pygpt_net/controller/lang/settings.py +39 -38
- pygpt_net/controller/layout/layout.py +176 -109
- pygpt_net/controller/mode/mode.py +88 -85
- pygpt_net/controller/model/model.py +73 -73
- pygpt_net/controller/plugins/plugins.py +209 -223
- pygpt_net/controller/plugins/presets.py +54 -55
- pygpt_net/controller/plugins/settings.py +54 -69
- pygpt_net/controller/presets/editor.py +33 -88
- pygpt_net/controller/presets/experts.py +20 -1
- pygpt_net/controller/presets/presets.py +293 -298
- pygpt_net/controller/settings/profile.py +16 -4
- pygpt_net/controller/theme/theme.py +72 -81
- pygpt_net/controller/ui/mode.py +118 -186
- pygpt_net/controller/ui/tabs.py +69 -90
- pygpt_net/controller/ui/ui.py +47 -56
- pygpt_net/controller/ui/vision.py +24 -23
- pygpt_net/core/agents/runner.py +15 -7
- pygpt_net/core/bridge/bridge.py +5 -5
- pygpt_net/core/command/command.py +149 -219
- pygpt_net/core/ctx/ctx.py +94 -146
- pygpt_net/core/debug/debug.py +48 -58
- pygpt_net/core/experts/experts.py +3 -3
- pygpt_net/core/models/models.py +74 -112
- pygpt_net/core/modes/modes.py +13 -21
- pygpt_net/core/plugins/plugins.py +154 -177
- pygpt_net/core/presets/presets.py +103 -176
- pygpt_net/core/render/web/body.py +217 -215
- pygpt_net/core/render/web/renderer.py +330 -474
- pygpt_net/core/text/utils.py +28 -44
- pygpt_net/core/tokens/tokens.py +104 -203
- pygpt_net/data/config/config.json +3 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +2 -0
- pygpt_net/data/locale/locale.en.ini +2 -0
- pygpt_net/data/locale/locale.es.ini +2 -0
- pygpt_net/data/locale/locale.fr.ini +2 -0
- pygpt_net/data/locale/locale.it.ini +2 -0
- pygpt_net/data/locale/locale.pl.ini +3 -1
- pygpt_net/data/locale/locale.uk.ini +2 -0
- pygpt_net/data/locale/locale.zh.ini +2 -0
- pygpt_net/item/ctx.py +141 -139
- pygpt_net/plugin/agent/plugin.py +2 -1
- pygpt_net/plugin/audio_output/plugin.py +5 -2
- pygpt_net/plugin/base/plugin.py +101 -85
- pygpt_net/plugin/bitbucket/__init__.py +12 -0
- pygpt_net/plugin/bitbucket/config.py +267 -0
- pygpt_net/plugin/bitbucket/plugin.py +126 -0
- pygpt_net/plugin/bitbucket/worker.py +569 -0
- pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
- pygpt_net/plugin/cmd_custom/plugin.py +3 -2
- pygpt_net/plugin/cmd_files/plugin.py +3 -2
- pygpt_net/plugin/cmd_history/plugin.py +3 -2
- pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
- pygpt_net/plugin/cmd_serial/plugin.py +3 -2
- pygpt_net/plugin/cmd_system/plugin.py +3 -6
- pygpt_net/plugin/cmd_web/plugin.py +3 -2
- pygpt_net/plugin/experts/plugin.py +2 -2
- pygpt_net/plugin/facebook/__init__.py +12 -0
- pygpt_net/plugin/facebook/config.py +359 -0
- pygpt_net/plugin/facebook/plugin.py +113 -0
- pygpt_net/plugin/facebook/worker.py +698 -0
- pygpt_net/plugin/github/__init__.py +12 -0
- pygpt_net/plugin/github/config.py +441 -0
- pygpt_net/plugin/github/plugin.py +126 -0
- pygpt_net/plugin/github/worker.py +674 -0
- pygpt_net/plugin/google/__init__.py +12 -0
- pygpt_net/plugin/google/config.py +367 -0
- pygpt_net/plugin/google/plugin.py +126 -0
- pygpt_net/plugin/google/worker.py +826 -0
- pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
- pygpt_net/plugin/mailer/plugin.py +3 -5
- pygpt_net/plugin/openai_vision/plugin.py +3 -2
- pygpt_net/plugin/real_time/plugin.py +52 -60
- pygpt_net/plugin/slack/__init__.py +12 -0
- pygpt_net/plugin/slack/config.py +349 -0
- pygpt_net/plugin/slack/plugin.py +115 -0
- pygpt_net/plugin/slack/worker.py +639 -0
- pygpt_net/plugin/telegram/__init__.py +12 -0
- pygpt_net/plugin/telegram/config.py +308 -0
- pygpt_net/plugin/telegram/plugin.py +117 -0
- pygpt_net/plugin/telegram/worker.py +563 -0
- pygpt_net/plugin/twitter/__init__.py +12 -0
- pygpt_net/plugin/twitter/config.py +491 -0
- pygpt_net/plugin/twitter/plugin.py +125 -0
- pygpt_net/plugin/twitter/worker.py +837 -0
- pygpt_net/provider/agents/llama_index/legacy/openai_assistant.py +35 -3
- pygpt_net/tools/code_interpreter/tool.py +0 -1
- pygpt_net/tools/translator/tool.py +1 -1
- pygpt_net/ui/base/config_dialog.py +86 -100
- pygpt_net/ui/base/context_menu.py +48 -46
- pygpt_net/ui/dialog/preset.py +34 -77
- pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
- pygpt_net/ui/layout/toolbox/presets.py +41 -41
- pygpt_net/ui/main.py +49 -31
- pygpt_net/ui/tray.py +61 -60
- pygpt_net/ui/widget/calendar/select.py +86 -70
- pygpt_net/ui/widget/lists/attachment.py +86 -44
- pygpt_net/ui/widget/lists/base_list_combo.py +85 -33
- pygpt_net/ui/widget/lists/context.py +135 -188
- pygpt_net/ui/widget/lists/preset.py +59 -61
- pygpt_net/ui/widget/textarea/web.py +161 -48
- pygpt_net/utils.py +8 -1
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/METADATA +164 -2
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/RECORD +131 -103
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.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: 2025.
|
|
9
|
+
# Updated Date: 2025.08.15 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import List, Dict, Any
|
|
@@ -34,6 +34,17 @@ class Plugins:
|
|
|
34
34
|
self.settings = Settings(window)
|
|
35
35
|
self.presets = Presets(window)
|
|
36
36
|
self.enabled = {}
|
|
37
|
+
self._suspend_updates = 0
|
|
38
|
+
|
|
39
|
+
def _begin_batch(self):
|
|
40
|
+
self._suspend_updates += 1
|
|
41
|
+
|
|
42
|
+
def _end_batch(self):
|
|
43
|
+
if self._suspend_updates > 0:
|
|
44
|
+
self._suspend_updates -= 1
|
|
45
|
+
if self._suspend_updates == 0:
|
|
46
|
+
self.update_info()
|
|
47
|
+
self.update()
|
|
37
48
|
|
|
38
49
|
def setup(self):
|
|
39
50
|
"""Set up plugins"""
|
|
@@ -41,12 +52,12 @@ class Plugins:
|
|
|
41
52
|
self.setup_ui()
|
|
42
53
|
|
|
43
54
|
try:
|
|
44
|
-
self.window.core.plugins.clean_presets()
|
|
55
|
+
self.window.core.plugins.clean_presets()
|
|
45
56
|
except Exception as e:
|
|
46
57
|
self.window.core.debug.error(e)
|
|
47
58
|
|
|
48
|
-
self.presets.preset_to_current()
|
|
49
|
-
self.reconfigure(silent=True)
|
|
59
|
+
self.presets.preset_to_current()
|
|
60
|
+
self.reconfigure(silent=True)
|
|
50
61
|
|
|
51
62
|
def reconfigure(self, silent: bool = False):
|
|
52
63
|
"""
|
|
@@ -60,31 +71,30 @@ class Plugins:
|
|
|
60
71
|
|
|
61
72
|
def setup_ui(self):
|
|
62
73
|
"""Set up plugins UI"""
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# show/hide UI elements
|
|
71
|
-
self.handle_types()
|
|
74
|
+
pm = self.window.core.plugins
|
|
75
|
+
for pid in pm.get_ids():
|
|
76
|
+
plugin = pm.get(pid)
|
|
77
|
+
fn = getattr(plugin, "setup_ui", None)
|
|
78
|
+
if callable(fn):
|
|
79
|
+
fn()
|
|
72
80
|
|
|
73
|
-
|
|
74
|
-
# self.window.core.plugins.dump_locales()
|
|
81
|
+
self.handle_types()
|
|
75
82
|
|
|
76
83
|
def setup_menu(self):
|
|
77
84
|
"""Set up plugins menu"""
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
pm = self.window.core.plugins
|
|
86
|
+
ui_menu = self.window.ui.menu
|
|
87
|
+
menu_plugins = ui_menu['plugins']
|
|
88
|
+
for pid in pm.get_ids():
|
|
89
|
+
if pid in menu_plugins:
|
|
80
90
|
continue
|
|
81
|
-
name =
|
|
82
|
-
tooltip =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
name = pm.get_name(pid)
|
|
92
|
+
tooltip = pm.get_desc(pid)
|
|
93
|
+
act = QAction(name, self.window, checkable=True)
|
|
94
|
+
act.triggered.connect(lambda checked=None, id=pid: self.toggle(id))
|
|
95
|
+
act.setToolTip(tooltip)
|
|
96
|
+
menu_plugins[pid] = act
|
|
97
|
+
ui_menu['menu.plugins'].addAction(act)
|
|
88
98
|
|
|
89
99
|
def setup_config(self, silent: bool = False):
|
|
90
100
|
"""
|
|
@@ -92,27 +102,31 @@ class Plugins:
|
|
|
92
102
|
|
|
93
103
|
:param silent: silent mode
|
|
94
104
|
"""
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
pm = self.window.core.plugins
|
|
106
|
+
cfg = self.window.core.config
|
|
107
|
+
cfg_enabled = cfg.get('plugins_enabled')
|
|
108
|
+
self._begin_batch()
|
|
109
|
+
try:
|
|
110
|
+
for pid in pm.get_ids():
|
|
111
|
+
if pid in cfg_enabled:
|
|
112
|
+
if cfg.data['plugins_enabled'][pid]:
|
|
113
|
+
self.enable(pid)
|
|
114
|
+
else:
|
|
115
|
+
self.disable(pid, silent=silent)
|
|
99
116
|
else:
|
|
100
|
-
self.disable(
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
self.disable(pid, silent=silent)
|
|
118
|
+
finally:
|
|
119
|
+
self._end_batch()
|
|
103
120
|
|
|
104
121
|
def update(self):
|
|
105
122
|
"""Update plugins menu"""
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
for id in self.enabled:
|
|
110
|
-
if self.enabled[id]:
|
|
111
|
-
self.window.ui.menu['plugins'][id].setChecked(True)
|
|
123
|
+
menu_plugins = self.window.ui.menu['plugins']
|
|
124
|
+
for pid, action in menu_plugins.items():
|
|
125
|
+
action.setChecked(self.enabled.get(pid, False))
|
|
112
126
|
|
|
113
127
|
self.handle_types()
|
|
114
|
-
self.window.controller.ui.mode.update()
|
|
115
|
-
self.window.controller.ui.vision.update()
|
|
128
|
+
self.window.controller.ui.mode.update()
|
|
129
|
+
self.window.controller.ui.vision.update()
|
|
116
130
|
|
|
117
131
|
def enable(self, id: str):
|
|
118
132
|
"""
|
|
@@ -120,22 +134,24 @@ class Plugins:
|
|
|
120
134
|
|
|
121
135
|
:param id: plugin id
|
|
122
136
|
"""
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
pm = self.window.core.plugins
|
|
138
|
+
if not pm.is_registered(id):
|
|
139
|
+
return
|
|
140
|
+
if self.enabled.get(id, False):
|
|
141
|
+
return
|
|
126
142
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
'value': id,
|
|
130
|
-
})
|
|
131
|
-
self.window.dispatch(event)
|
|
143
|
+
self.enabled[id] = True
|
|
144
|
+
pm.enable(id)
|
|
132
145
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
self.window.controller.audio.update()
|
|
146
|
+
event = Event(Event.ENABLE, {'value': id})
|
|
147
|
+
self.window.dispatch(event)
|
|
136
148
|
|
|
137
|
-
self.
|
|
138
|
-
|
|
149
|
+
if self.has_type(id, 'audio.input') or self.has_type(id, 'audio.output'):
|
|
150
|
+
self.window.controller.audio.update()
|
|
151
|
+
|
|
152
|
+
if self._suspend_updates == 0:
|
|
153
|
+
self.update_info()
|
|
154
|
+
self.update()
|
|
139
155
|
|
|
140
156
|
def disable(self, id: str, silent: bool = False):
|
|
141
157
|
"""
|
|
@@ -144,25 +160,26 @@ class Plugins:
|
|
|
144
160
|
:param id: plugin id
|
|
145
161
|
:param silent: silent mode
|
|
146
162
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
163
|
+
pm = self.window.core.plugins
|
|
164
|
+
if not pm.is_registered(id):
|
|
165
|
+
return
|
|
166
|
+
if not self.enabled.get(id, False):
|
|
167
|
+
return
|
|
150
168
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
event = Event(Event.DISABLE, {
|
|
154
|
-
'value': id,
|
|
155
|
-
})
|
|
156
|
-
self.window.dispatch(event, all=True) # dispatch to all plugins, including disabled now
|
|
169
|
+
self.enabled[id] = False
|
|
170
|
+
pm.disable(id)
|
|
157
171
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
172
|
+
if not silent:
|
|
173
|
+
event = Event(Event.DISABLE, {'value': id})
|
|
174
|
+
self.window.dispatch(event, all=True)
|
|
175
|
+
if self.has_type(id, 'audio.input') or self.has_type(id, 'audio.output'):
|
|
176
|
+
self.window.controller.audio.update()
|
|
161
177
|
|
|
162
|
-
self.
|
|
163
|
-
|
|
178
|
+
if self._suspend_updates == 0:
|
|
179
|
+
self.update_info()
|
|
180
|
+
self.update()
|
|
164
181
|
|
|
165
|
-
def is_enabled(self, id: str):
|
|
182
|
+
def is_enabled(self, id: str) -> bool:
|
|
166
183
|
"""
|
|
167
184
|
Check if plugin is enabled
|
|
168
185
|
|
|
@@ -170,10 +187,7 @@ class Plugins:
|
|
|
170
187
|
:return: True if enabled
|
|
171
188
|
:rtype: bool
|
|
172
189
|
"""
|
|
173
|
-
|
|
174
|
-
if id in self.enabled:
|
|
175
|
-
return self.enabled[id]
|
|
176
|
-
return False
|
|
190
|
+
return self.window.core.plugins.is_registered(id) and self.enabled.get(id, False)
|
|
177
191
|
|
|
178
192
|
def toggle(self, id: str):
|
|
179
193
|
"""
|
|
@@ -187,12 +201,9 @@ class Plugins:
|
|
|
187
201
|
else:
|
|
188
202
|
self.enable(id)
|
|
189
203
|
|
|
190
|
-
self.
|
|
191
|
-
self.window.controller.
|
|
192
|
-
self.
|
|
193
|
-
self.window.controller.ui.vision.update() # vision camera
|
|
194
|
-
self.window.controller.attachment.update() # attachments update
|
|
195
|
-
self.presets.save_current() # save settings in current preset
|
|
204
|
+
self.window.controller.ui.update_tokens()
|
|
205
|
+
self.window.controller.attachment.update()
|
|
206
|
+
self.presets.save_current()
|
|
196
207
|
|
|
197
208
|
def set_by_tab(self, idx: int):
|
|
198
209
|
"""
|
|
@@ -200,13 +211,14 @@ class Plugins:
|
|
|
200
211
|
|
|
201
212
|
:param idx: tab index
|
|
202
213
|
"""
|
|
214
|
+
pm = self.window.core.plugins
|
|
203
215
|
plugin_idx = 0
|
|
204
|
-
for
|
|
205
|
-
if
|
|
216
|
+
for pid in pm.get_ids():
|
|
217
|
+
if pm.has_options(pid):
|
|
206
218
|
if plugin_idx == idx:
|
|
207
|
-
self.settings.current_plugin =
|
|
219
|
+
self.settings.current_plugin = pid
|
|
208
220
|
break
|
|
209
|
-
|
|
221
|
+
plugin_idx += 1
|
|
210
222
|
current = self.window.ui.models['plugin.list'].index(idx, 0)
|
|
211
223
|
self.window.ui.nodes['plugin.list'].setCurrentIndex(current)
|
|
212
224
|
|
|
@@ -217,14 +229,11 @@ class Plugins:
|
|
|
217
229
|
:param plugin_id: plugin id
|
|
218
230
|
:return: tab index
|
|
219
231
|
"""
|
|
220
|
-
|
|
221
|
-
i
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
break
|
|
226
|
-
i += 1
|
|
227
|
-
return plugin_idx
|
|
232
|
+
pm = self.window.core.plugins
|
|
233
|
+
for i, pid in enumerate(pm.get_ids()):
|
|
234
|
+
if pid == plugin_id:
|
|
235
|
+
return i
|
|
236
|
+
return None
|
|
228
237
|
|
|
229
238
|
def unregister(self, id: str):
|
|
230
239
|
"""
|
|
@@ -233,22 +242,22 @@ class Plugins:
|
|
|
233
242
|
:param id: plugin id
|
|
234
243
|
"""
|
|
235
244
|
self.window.core.plugins.unregister(id)
|
|
236
|
-
|
|
237
|
-
self.enabled.pop(id)
|
|
245
|
+
self.enabled.pop(id, None)
|
|
238
246
|
|
|
239
247
|
def destroy(self):
|
|
240
248
|
"""Destroy plugins workers"""
|
|
241
|
-
|
|
242
|
-
# send force stop event
|
|
243
249
|
event = Event(Event.FORCE_STOP, {})
|
|
244
250
|
self.window.dispatch(event)
|
|
245
251
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
pm = self.window.core.plugins
|
|
253
|
+
for pid in pm.get_ids():
|
|
254
|
+
plugin = pm.get(pid)
|
|
255
|
+
fn = getattr(pm, "destroy", None)
|
|
256
|
+
if callable(fn):
|
|
257
|
+
try:
|
|
258
|
+
pm.destroy(pid)
|
|
259
|
+
except AttributeError:
|
|
260
|
+
pass
|
|
252
261
|
|
|
253
262
|
def has_type(self, id: str, type: str):
|
|
254
263
|
"""
|
|
@@ -257,10 +266,10 @@ class Plugins:
|
|
|
257
266
|
:param type: type to check
|
|
258
267
|
:return: True if has type
|
|
259
268
|
"""
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return
|
|
269
|
+
pm = self.window.core.plugins
|
|
270
|
+
if not pm.is_registered(id):
|
|
271
|
+
return False
|
|
272
|
+
return type in pm.get(id).type
|
|
264
273
|
|
|
265
274
|
def is_type_enabled(self, type: str) -> bool:
|
|
266
275
|
"""
|
|
@@ -269,39 +278,25 @@ class Plugins:
|
|
|
269
278
|
:param type: plugin type
|
|
270
279
|
:return: True if enabled
|
|
271
280
|
"""
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if type in self.window.core.plugins.get(id).type and self.is_enabled(id):
|
|
275
|
-
enabled = True
|
|
276
|
-
break
|
|
277
|
-
return enabled
|
|
281
|
+
pm = self.window.core.plugins
|
|
282
|
+
return any((type in pm.get(pid).type) and self.is_enabled(pid) for pid in pm.get_ids())
|
|
278
283
|
|
|
279
284
|
def handle_types(self):
|
|
280
285
|
"""Handle plugin type"""
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
enabled = self.is_type_enabled(
|
|
284
|
-
|
|
285
|
-
if type == 'audio.input':
|
|
286
|
+
pm = self.window.core.plugins
|
|
287
|
+
for t in pm.allowed_types:
|
|
288
|
+
enabled = self.is_type_enabled(t)
|
|
289
|
+
if t == 'audio.input':
|
|
286
290
|
self.window.controller.audio.handle_audio_input(enabled)
|
|
287
|
-
|
|
288
|
-
elif type == 'audio.output':
|
|
291
|
+
elif t == 'audio.output':
|
|
289
292
|
self.window.controller.audio.handle_audio_output(enabled)
|
|
290
|
-
|
|
291
|
-
elif type == 'schedule':
|
|
293
|
+
elif t == 'schedule':
|
|
292
294
|
if enabled:
|
|
293
295
|
self.window.ui.plugin_addon['schedule'].setVisible(True)
|
|
294
|
-
|
|
295
|
-
num = 0
|
|
296
|
-
data = {
|
|
297
|
-
'name': 'scheduled_tasks_count',
|
|
298
|
-
'value': num,
|
|
299
|
-
}
|
|
296
|
+
data = {'name': 'scheduled_tasks_count', 'value': 0}
|
|
300
297
|
event = Event(Event.PLUGIN_OPTION_GET, data)
|
|
301
298
|
self.window.dispatch(event)
|
|
302
|
-
|
|
303
|
-
num = event.data['value']
|
|
304
|
-
# update tray menu
|
|
299
|
+
num = event.data.get('value', 0)
|
|
305
300
|
self.window.ui.tray.update_schedule_tasks(num)
|
|
306
301
|
else:
|
|
307
302
|
self.window.ui.plugin_addon['schedule'].setVisible(False)
|
|
@@ -309,58 +304,70 @@ class Plugins:
|
|
|
309
304
|
|
|
310
305
|
def on_update(self):
|
|
311
306
|
"""Called on update"""
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
307
|
+
pm = self.window.core.plugins
|
|
308
|
+
for pid in pm.get_ids():
|
|
309
|
+
if self.is_enabled(pid):
|
|
310
|
+
fn = getattr(pm.get(pid), "on_update", None)
|
|
311
|
+
if callable(fn):
|
|
312
|
+
fn()
|
|
318
313
|
|
|
319
314
|
def on_post_update(self):
|
|
320
315
|
"""Called on post update"""
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
316
|
+
pm = self.window.core.plugins
|
|
317
|
+
for pid in pm.get_ids():
|
|
318
|
+
if self.is_enabled(pid):
|
|
319
|
+
fn = getattr(pm.get(pid), "on_post_update", None)
|
|
320
|
+
if callable(fn):
|
|
321
|
+
fn()
|
|
327
322
|
|
|
328
323
|
def update_info(self):
|
|
329
324
|
"""Update plugins info"""
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if self.is_enabled(id):
|
|
333
|
-
enabled_list.append(self.window.core.plugins.get(id).name)
|
|
334
|
-
tooltip = " + ".join(enabled_list)
|
|
335
|
-
|
|
336
|
-
count_str = ""
|
|
325
|
+
pm = self.window.core.plugins
|
|
326
|
+
enabled_names = []
|
|
337
327
|
c = 0
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
328
|
+
for pid in pm.get_ids():
|
|
329
|
+
if self.is_enabled(pid):
|
|
330
|
+
c += 1
|
|
331
|
+
enabled_names.append(pm.get(pid).name)
|
|
342
332
|
|
|
343
|
-
|
|
344
|
-
|
|
333
|
+
tooltip = " + ".join(enabled_names)
|
|
334
|
+
count_str = f"+ {c} {trans('chatbox.plugins')}" if c > 0 else ""
|
|
345
335
|
self.window.ui.nodes['chat.plugins'].setText(count_str)
|
|
346
336
|
self.window.ui.nodes['chat.plugins'].setToolTip(tooltip)
|
|
347
337
|
|
|
348
|
-
def
|
|
338
|
+
def _apply_cmds_common(
|
|
349
339
|
self,
|
|
340
|
+
event_type: str,
|
|
350
341
|
ctx: CtxItem,
|
|
351
|
-
cmds: List[Dict[str, Any]]
|
|
342
|
+
cmds: List[Dict[str, Any]],
|
|
343
|
+
all: bool = False,
|
|
344
|
+
execute_only: bool = False
|
|
352
345
|
):
|
|
353
|
-
|
|
354
|
-
|
|
346
|
+
commands = self.window.core.command.from_commands(cmds)
|
|
347
|
+
if len(commands) == 0:
|
|
348
|
+
return
|
|
355
349
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if
|
|
361
|
-
|
|
350
|
+
event = Event(event_type, {'commands': commands})
|
|
351
|
+
mode = self.window.core.config.get('mode')
|
|
352
|
+
self.log("Executing plugin commands..." if event_type == Event.CMD_EXECUTE else "Executing inline plugin commands...")
|
|
353
|
+
change_status = True
|
|
354
|
+
if mode == MODE_AGENT and len(cmds) == 1 and cmds[0].get("cmd") == "goal_update":
|
|
355
|
+
change_status = False
|
|
356
|
+
wait_str = trans('status.cmd.wait')
|
|
357
|
+
if change_status:
|
|
358
|
+
self.window.update_status(wait_str)
|
|
359
|
+
|
|
360
|
+
ctx.results = []
|
|
361
|
+
event.ctx = ctx
|
|
362
|
+
if event_type == Event.CMD_EXECUTE:
|
|
363
|
+
self.window.controller.command.dispatch(event, all=all, execute_only=execute_only)
|
|
362
364
|
else:
|
|
363
|
-
|
|
365
|
+
self.window.controller.command.dispatch(event)
|
|
366
|
+
|
|
367
|
+
current = self.window.ui.get_status()
|
|
368
|
+
if current == wait_str:
|
|
369
|
+
self.window.update_status("")
|
|
370
|
+
return ctx.results
|
|
364
371
|
|
|
365
372
|
def apply_cmds(
|
|
366
373
|
self,
|
|
@@ -377,38 +384,25 @@ class Plugins:
|
|
|
377
384
|
:param all: True to apply all commands, False to apply only enabled commands
|
|
378
385
|
:param execute_only: True to execute commands only, without any additional event
|
|
379
386
|
"""
|
|
380
|
-
|
|
381
|
-
if len(commands) == 0:
|
|
382
|
-
return
|
|
383
|
-
|
|
384
|
-
# dispatch command execute event
|
|
385
|
-
event = Event(Event.CMD_EXECUTE, {
|
|
386
|
-
'commands': commands,
|
|
387
|
-
})
|
|
387
|
+
return self._apply_cmds_common(Event.CMD_EXECUTE, ctx, cmds, all=all, execute_only=execute_only)
|
|
388
388
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if change_status:
|
|
397
|
-
self.window.update_status(trans('status.cmd.wait'))
|
|
389
|
+
def apply_cmds_all(
|
|
390
|
+
self,
|
|
391
|
+
ctx: CtxItem,
|
|
392
|
+
cmds: List[Dict[str, Any]]
|
|
393
|
+
):
|
|
394
|
+
"""
|
|
395
|
+
Apply all commands (inline or not)
|
|
398
396
|
|
|
399
|
-
ctx
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
current = self.window.ui.get_status()
|
|
408
|
-
if current == trans('status.cmd.wait'):
|
|
409
|
-
self.window.update_status("")
|
|
397
|
+
:param ctx: context
|
|
398
|
+
:param cmds: commands
|
|
399
|
+
:return: results
|
|
400
|
+
"""
|
|
401
|
+
if self.window.core.config.get("cmd"):
|
|
402
|
+
return self.apply_cmds(ctx, cmds)
|
|
403
|
+
else:
|
|
404
|
+
return self.apply_cmds_inline(ctx, cmds)
|
|
410
405
|
|
|
411
|
-
return ctx.results
|
|
412
406
|
|
|
413
407
|
def apply_cmds_inline(
|
|
414
408
|
self,
|
|
@@ -421,47 +415,39 @@ class Plugins:
|
|
|
421
415
|
:param ctx: CtxItem
|
|
422
416
|
:param cmds: commands list
|
|
423
417
|
"""
|
|
424
|
-
|
|
425
|
-
if len(commands) == 0:
|
|
426
|
-
return
|
|
427
|
-
|
|
428
|
-
# dispatch inline command event
|
|
429
|
-
event = Event(Event.CMD_INLINE, {
|
|
430
|
-
'commands': commands,
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
# don't change status if only goal update command
|
|
434
|
-
self.log("Executing inline plugin commands...")
|
|
435
|
-
mode = self.window.core.config.get('mode')
|
|
436
|
-
change_status = True
|
|
437
|
-
if mode == MODE_AGENT:
|
|
438
|
-
if len(cmds) == 1 and cmds[0]["cmd"] == "goal_update":
|
|
439
|
-
change_status = False
|
|
440
|
-
if change_status:
|
|
441
|
-
self.window.update_status(trans('status.cmd.wait'))
|
|
442
|
-
|
|
443
|
-
ctx.results = []
|
|
444
|
-
event.ctx = ctx
|
|
445
|
-
self.window.controller.command.dispatch(event)
|
|
446
|
-
|
|
447
|
-
# reset status if nothing executed
|
|
448
|
-
current = self.window.ui.get_status()
|
|
449
|
-
if current == trans('status.cmd.wait'):
|
|
450
|
-
self.window.update_status("")
|
|
451
|
-
|
|
452
|
-
return ctx.results
|
|
418
|
+
return self._apply_cmds_common(Event.CMD_INLINE, ctx, cmds)
|
|
453
419
|
|
|
454
420
|
def reload(self):
|
|
455
421
|
"""Reload plugins"""
|
|
456
|
-
self.window.core.plugins.reload_all()
|
|
422
|
+
self.window.core.plugins.reload_all()
|
|
457
423
|
self.setup()
|
|
458
424
|
self.settings.setup()
|
|
459
425
|
self.update()
|
|
460
426
|
|
|
427
|
+
def save_all(self):
|
|
428
|
+
"""Save plugin settings"""
|
|
429
|
+
pm = self.window.core.plugins
|
|
430
|
+
cfg_plugins = self.window.core.config.data['plugins']
|
|
431
|
+
|
|
432
|
+
for pid, plugin in pm.plugins.items():
|
|
433
|
+
plugin.setup()
|
|
434
|
+
if pid not in cfg_plugins:
|
|
435
|
+
cfg_plugins[pid] = {}
|
|
436
|
+
dest = cfg_plugins[pid]
|
|
437
|
+
for key, opt in plugin.options.items():
|
|
438
|
+
dest[key] = opt['value']
|
|
439
|
+
|
|
440
|
+
for key in list(cfg_plugins.keys()):
|
|
441
|
+
if key not in pm.plugins:
|
|
442
|
+
cfg_plugins.pop(key)
|
|
443
|
+
|
|
444
|
+
self.window.controller.plugins.presets.save_current()
|
|
445
|
+
self.window.core.config.save()
|
|
446
|
+
|
|
461
447
|
def log(self, data: Any):
|
|
462
448
|
"""
|
|
463
449
|
Log data to debug
|
|
464
450
|
|
|
465
451
|
:param data: Data to log
|
|
466
452
|
"""
|
|
467
|
-
self.window.core.debug.info(data)
|
|
453
|
+
self.window.core.debug.info(data)
|