pygpt-net 2.7.7__py3-none-any.whl → 2.7.9__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 +12 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +5 -1
- pygpt_net/controller/assistant/batch.py +2 -2
- pygpt_net/controller/assistant/files.py +7 -6
- pygpt_net/controller/assistant/threads.py +0 -0
- pygpt_net/controller/chat/command.py +0 -0
- pygpt_net/controller/dialogs/confirm.py +35 -58
- pygpt_net/controller/lang/mapping.py +9 -9
- pygpt_net/controller/realtime/realtime.py +13 -1
- pygpt_net/controller/remote_store/{google/batch.py → batch.py} +209 -252
- pygpt_net/controller/remote_store/remote_store.py +982 -13
- pygpt_net/core/command/command.py +0 -0
- pygpt_net/core/db/viewer.py +1 -1
- pygpt_net/core/realtime/worker.py +3 -1
- pygpt_net/{controller/remote_store/google → core/remote_store/anthropic}/__init__.py +0 -1
- pygpt_net/core/remote_store/anthropic/files.py +211 -0
- pygpt_net/core/remote_store/anthropic/store.py +208 -0
- pygpt_net/core/remote_store/openai/store.py +5 -4
- pygpt_net/core/remote_store/remote_store.py +5 -1
- pygpt_net/{controller/remote_store/openai → core/remote_store/xai}/__init__.py +0 -1
- pygpt_net/core/remote_store/xai/files.py +225 -0
- pygpt_net/core/remote_store/xai/store.py +219 -0
- pygpt_net/data/config/config.json +10 -6
- pygpt_net/data/config/models.json +38 -22
- pygpt_net/data/config/settings.json +54 -1
- pygpt_net/data/icons/folder_eye.svg +1 -0
- pygpt_net/data/icons/folder_eye_filled.svg +1 -0
- pygpt_net/data/icons/folder_open.svg +1 -0
- pygpt_net/data/icons/folder_open_filled.svg +1 -0
- pygpt_net/data/locale/locale.de.ini +4 -3
- pygpt_net/data/locale/locale.en.ini +14 -4
- pygpt_net/data/locale/locale.es.ini +4 -3
- pygpt_net/data/locale/locale.fr.ini +4 -3
- pygpt_net/data/locale/locale.it.ini +4 -3
- pygpt_net/data/locale/locale.pl.ini +5 -4
- pygpt_net/data/locale/locale.uk.ini +4 -3
- pygpt_net/data/locale/locale.zh.ini +4 -3
- pygpt_net/icons.qrc +4 -0
- pygpt_net/icons_rc.py +282 -138
- pygpt_net/provider/api/anthropic/__init__.py +2 -0
- pygpt_net/provider/api/anthropic/chat.py +84 -1
- pygpt_net/provider/api/anthropic/store.py +307 -0
- pygpt_net/provider/api/anthropic/stream.py +75 -0
- pygpt_net/provider/api/anthropic/worker/__init__.py +0 -0
- pygpt_net/provider/api/anthropic/worker/importer.py +278 -0
- pygpt_net/provider/api/google/chat.py +59 -2
- pygpt_net/provider/api/google/realtime/client.py +70 -24
- pygpt_net/provider/api/google/realtime/realtime.py +48 -12
- pygpt_net/provider/api/google/store.py +124 -3
- pygpt_net/provider/api/google/stream.py +91 -24
- pygpt_net/provider/api/google/worker/importer.py +16 -28
- pygpt_net/provider/api/openai/assistants.py +2 -2
- pygpt_net/provider/api/openai/realtime/realtime.py +26 -6
- pygpt_net/provider/api/openai/store.py +4 -1
- pygpt_net/provider/api/openai/worker/importer.py +19 -61
- pygpt_net/provider/api/openai/worker/importer_assistants.py +230 -0
- pygpt_net/provider/api/x_ai/__init__.py +27 -6
- pygpt_net/provider/api/x_ai/audio.py +43 -11
- pygpt_net/provider/api/x_ai/chat.py +92 -4
- pygpt_net/provider/api/x_ai/realtime/__init__.py +12 -0
- pygpt_net/provider/api/x_ai/realtime/client.py +1864 -0
- pygpt_net/provider/api/x_ai/realtime/realtime.py +213 -0
- pygpt_net/provider/api/x_ai/remote_tools.py +102 -1
- pygpt_net/provider/api/x_ai/store.py +610 -0
- pygpt_net/provider/api/x_ai/stream.py +30 -9
- pygpt_net/provider/api/x_ai/tools.py +51 -0
- pygpt_net/provider/api/x_ai/worker/importer.py +308 -0
- pygpt_net/provider/audio_input/xai_grok_voice.py +390 -0
- pygpt_net/provider/audio_output/xai_tts.py +325 -0
- pygpt_net/provider/core/config/patch.py +29 -3
- pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +2 -2
- pygpt_net/provider/core/model/patch.py +49 -1
- pygpt_net/tools/image_viewer/tool.py +334 -34
- pygpt_net/tools/image_viewer/ui/dialogs.py +317 -21
- pygpt_net/ui/dialog/assistant.py +1 -1
- pygpt_net/ui/dialog/plugins.py +13 -5
- pygpt_net/ui/dialog/remote_store.py +552 -0
- pygpt_net/ui/dialogs.py +3 -5
- pygpt_net/ui/layout/ctx/ctx_list.py +58 -7
- pygpt_net/ui/menu/tools.py +6 -13
- pygpt_net/ui/widget/dialog/{remote_store_google.py → remote_store.py} +10 -10
- pygpt_net/ui/widget/element/button.py +4 -4
- pygpt_net/ui/widget/image/display.py +2 -2
- pygpt_net/ui/widget/lists/context.py +2 -2
- {pygpt_net-2.7.7.dist-info → pygpt_net-2.7.9.dist-info}/METADATA +14 -2
- {pygpt_net-2.7.7.dist-info → pygpt_net-2.7.9.dist-info}/RECORD +87 -75
- pygpt_net/controller/remote_store/google/store.py +0 -615
- pygpt_net/controller/remote_store/openai/batch.py +0 -524
- pygpt_net/controller/remote_store/openai/store.py +0 -699
- pygpt_net/ui/dialog/remote_store_google.py +0 -539
- pygpt_net/ui/dialog/remote_store_openai.py +0 -539
- pygpt_net/ui/widget/dialog/remote_store_openai.py +0 -56
- pygpt_net/ui/widget/lists/remote_store_google.py +0 -248
- pygpt_net/ui/widget/lists/remote_store_openai.py +0 -317
- {pygpt_net-2.7.7.dist-info → pygpt_net-2.7.9.dist-info}/LICENSE +0 -0
- {pygpt_net-2.7.7.dist-info → pygpt_net-2.7.9.dist-info}/WHEEL +0 -0
- {pygpt_net-2.7.7.dist-info → pygpt_net-2.7.9.dist-info}/entry_points.txt +0 -0
|
@@ -6,397 +6,354 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2026.01.
|
|
9
|
+
# Updated Date: 2026.01.06 06:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
|
-
from typing import Optional, Any,
|
|
12
|
+
from typing import Optional, Union, Any, List
|
|
13
13
|
|
|
14
14
|
from PySide6.QtCore import QTimer
|
|
15
|
-
from PySide6.QtWidgets import
|
|
15
|
+
from PySide6.QtWidgets import QApplication, QFileDialog
|
|
16
16
|
|
|
17
17
|
from pygpt_net.utils import trans
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
class Batch:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
"""
|
|
21
|
+
Proxy for batch operations for a specific remote store provider used by Confirm router
|
|
22
|
+
"""
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
self.window = window
|
|
28
|
-
self.files_to_upload = []
|
|
24
|
+
def __init__(self, ctrl):
|
|
25
|
+
self.ctrl = ctrl
|
|
26
|
+
self.window = ctrl.window
|
|
27
|
+
self.files_to_upload: List[str] = []
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
Import File Search stores
|
|
29
|
+
# ---------- Starters (invoked by Confirm router) ----------
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
"""
|
|
31
|
+
def import_stores(self, force: bool = False):
|
|
36
32
|
if not force:
|
|
37
33
|
self.window.ui.dialogs.confirm(
|
|
38
|
-
type='remote_store.
|
|
34
|
+
type=f'remote_store.import',
|
|
39
35
|
id='',
|
|
40
36
|
msg=trans('confirm.remote_store.import'),
|
|
41
37
|
)
|
|
42
38
|
return
|
|
43
|
-
self.window.update_status("Importing
|
|
44
|
-
self.
|
|
45
|
-
self.
|
|
46
|
-
|
|
39
|
+
self.window.update_status("Importing stores...please wait...")
|
|
40
|
+
self.ctrl._core_for(self._get_provider()).truncate()
|
|
41
|
+
self._importer().import_vector_stores()
|
|
42
|
+
|
|
43
|
+
def truncate_stores(self, force: bool = False):
|
|
44
|
+
if not force:
|
|
45
|
+
self.window.ui.dialogs.confirm(
|
|
46
|
+
type=f'remote_store.truncate',
|
|
47
|
+
id='',
|
|
48
|
+
msg=trans('confirm.remote_store.truncate'),
|
|
49
|
+
)
|
|
50
|
+
return
|
|
51
|
+
self.window.update_status("Removing stores...please wait...")
|
|
52
|
+
QApplication.processEvents()
|
|
53
|
+
self._importer().truncate_vector_stores()
|
|
54
|
+
|
|
55
|
+
def refresh_stores(self, force: bool = False):
|
|
56
|
+
if not force:
|
|
57
|
+
self.window.ui.dialogs.confirm(
|
|
58
|
+
type=f'remote_store.refresh',
|
|
59
|
+
id='',
|
|
60
|
+
msg=trans('confirm.remote_store.refresh'),
|
|
61
|
+
)
|
|
62
|
+
return
|
|
63
|
+
self.window.update_status("Refreshing stores...please wait...")
|
|
64
|
+
QApplication.processEvents()
|
|
65
|
+
self._importer().refresh_vector_stores()
|
|
66
|
+
|
|
67
|
+
def import_files_assistant_current(self, force: bool = False):
|
|
68
|
+
"""Import assistant files from API for current assistant"""
|
|
69
|
+
id = self.window.core.config.get('assistant')
|
|
70
|
+
if id is None or id == "":
|
|
71
|
+
return
|
|
72
|
+
if self.window.core.assistants.has(id):
|
|
73
|
+
assistant = self.window.core.assistants.get_by_id(id)
|
|
74
|
+
store_id = assistant.vector_store
|
|
75
|
+
if store_id is None or store_id == "":
|
|
76
|
+
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.assign"))
|
|
77
|
+
return
|
|
78
|
+
if not force:
|
|
79
|
+
self.window.ui.dialogs.confirm(
|
|
80
|
+
type=f'remote_store.files.import.assistant.current',
|
|
81
|
+
id=store_id,
|
|
82
|
+
msg=trans('confirm.remote_store.import_files.store'),
|
|
83
|
+
)
|
|
84
|
+
return
|
|
85
|
+
self.window.core.api.openai.store.importer.import_files(store_id) # for current assistant
|
|
86
|
+
|
|
87
|
+
def import_files_assistant_all(self, force: bool = False):
|
|
88
|
+
"""Import assistant files from API for all assistants"""
|
|
89
|
+
if not force:
|
|
90
|
+
self.window.ui.dialogs.confirm(
|
|
91
|
+
type=f'remote_store.files.import.assistant.all',
|
|
92
|
+
id='',
|
|
93
|
+
msg=trans('confirm.remote_store.import_files'),
|
|
94
|
+
)
|
|
95
|
+
return
|
|
96
|
+
self.window.core.api.openai.store.importer.import_files() # all
|
|
47
97
|
|
|
48
98
|
def import_files(self, force: bool = False):
|
|
49
|
-
"""
|
|
50
|
-
Sync documents with API (all)
|
|
51
|
-
"""
|
|
52
99
|
if not force:
|
|
53
100
|
self.window.ui.dialogs.confirm(
|
|
54
|
-
type='remote_store.
|
|
101
|
+
type=f'remote_store.files.import.all',
|
|
55
102
|
id='',
|
|
56
103
|
msg=trans('confirm.remote_store.import_files'),
|
|
57
104
|
)
|
|
58
105
|
return
|
|
59
|
-
|
|
60
|
-
self.window.core.api.google.store.importer.import_files() # all
|
|
61
|
-
except Exception as e:
|
|
62
|
-
self.window.core.debug.log(e)
|
|
63
|
-
self.window.ui.dialogs.alert(e)
|
|
106
|
+
self._importer().import_files() # all
|
|
64
107
|
|
|
65
108
|
def import_store_files(self, store_id: str, force: bool = False):
|
|
66
|
-
"""
|
|
67
|
-
Sync documents with API (store)
|
|
68
|
-
|
|
69
|
-
:param store_id: store name ('fileSearchStores/...').
|
|
70
|
-
"""
|
|
71
109
|
if store_id is None:
|
|
72
110
|
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
73
111
|
return
|
|
74
|
-
|
|
75
112
|
if not force:
|
|
76
113
|
self.window.ui.dialogs.confirm(
|
|
77
|
-
type='remote_store.
|
|
114
|
+
type=f'remote_store.files.import.store',
|
|
78
115
|
id=store_id,
|
|
79
116
|
msg=trans('confirm.remote_store.import_files.store'),
|
|
80
117
|
)
|
|
81
118
|
return
|
|
82
|
-
|
|
83
|
-
self.window.core.api.google.store.importer.import_files(store_id) # by store
|
|
84
|
-
except Exception as e:
|
|
85
|
-
self.window.core.debug.log(e)
|
|
86
|
-
self.window.ui.dialogs.alert(e)
|
|
119
|
+
self._importer().import_files(store_id)
|
|
87
120
|
|
|
88
121
|
def truncate_files(self, force: bool = False):
|
|
89
|
-
"""
|
|
90
|
-
Truncate all documents in API
|
|
91
|
-
"""
|
|
92
122
|
if not force:
|
|
123
|
+
key = 'confirm.remote_store.files.truncate'
|
|
93
124
|
self.window.ui.dialogs.confirm(
|
|
94
|
-
type='remote_store.
|
|
125
|
+
type=f'remote_store.files.truncate',
|
|
95
126
|
id='',
|
|
96
|
-
msg=trans(
|
|
127
|
+
msg=trans(key),
|
|
97
128
|
)
|
|
98
129
|
return
|
|
99
|
-
self.window.update_status("Removing
|
|
130
|
+
self.window.update_status("Removing files...please wait...")
|
|
100
131
|
QApplication.processEvents()
|
|
101
|
-
self.
|
|
102
|
-
|
|
103
|
-
def truncate_store_files_by_idx(self, idx: Union[int, list], force: bool = False):
|
|
104
|
-
"""
|
|
105
|
-
Truncate all documents in API (store)
|
|
106
|
-
"""
|
|
107
|
-
store_ids = []
|
|
108
|
-
ids = idx if isinstance(idx, list) else [idx]
|
|
109
|
-
for i in ids:
|
|
110
|
-
store_id = self.window.controller.remote_store.google.get_by_tab_idx(i)
|
|
111
|
-
store_ids.append(store_id)
|
|
112
|
-
self.truncate_store_files(store_ids, force)
|
|
132
|
+
self._importer().truncate_files()
|
|
113
133
|
|
|
114
134
|
def truncate_store_files(self, store_id: Union[str, list], force: bool = False):
|
|
115
|
-
"""
|
|
116
|
-
Truncate all documents in API (store)
|
|
117
|
-
"""
|
|
118
135
|
if store_id is None:
|
|
119
136
|
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
120
137
|
return
|
|
121
|
-
|
|
122
138
|
if not force:
|
|
139
|
+
key = 'confirm.remote_store.files.truncate.store'
|
|
123
140
|
self.window.ui.dialogs.confirm(
|
|
124
|
-
type='remote_store.
|
|
141
|
+
type=f'remote_store.files.truncate.store',
|
|
125
142
|
id=store_id,
|
|
126
|
-
msg=trans(
|
|
143
|
+
msg=trans(key),
|
|
127
144
|
)
|
|
128
145
|
return
|
|
129
|
-
self.window.update_status("Removing
|
|
146
|
+
self.window.update_status("Removing files...please wait...")
|
|
130
147
|
QApplication.processEvents()
|
|
131
148
|
ids = store_id if isinstance(store_id, list) else [store_id]
|
|
132
149
|
for sid in ids:
|
|
133
|
-
self.
|
|
134
|
-
|
|
135
|
-
def clear_store_files_by_idx(self, idx: Union[int, list], force: bool = False):
|
|
136
|
-
"""
|
|
137
|
-
Clear documents (store, local only)
|
|
138
|
-
"""
|
|
139
|
-
store_ids = []
|
|
140
|
-
ids = idx if isinstance(idx, list) else [idx]
|
|
141
|
-
for i in ids:
|
|
142
|
-
store_id = self.window.controller.remote_store.google.get_by_tab_idx(i)
|
|
143
|
-
store_ids.append(store_id)
|
|
144
|
-
self.clear_store_files(store_ids, force)
|
|
145
|
-
|
|
146
|
-
def clear_store_files(self, store_id: Optional[Union[str, list]] = None, force: bool = False):
|
|
147
|
-
"""
|
|
148
|
-
Clear documents (store, local only)
|
|
149
|
-
"""
|
|
150
|
-
if store_id is None:
|
|
151
|
-
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
152
|
-
return
|
|
150
|
+
self._importer().truncate_files(sid)
|
|
153
151
|
|
|
152
|
+
def clear_stores(self, force: bool = False):
|
|
154
153
|
if not force:
|
|
155
154
|
self.window.ui.dialogs.confirm(
|
|
156
|
-
type='remote_store.
|
|
157
|
-
id=
|
|
158
|
-
msg=trans('confirm.
|
|
155
|
+
type=f'remote_store.clear',
|
|
156
|
+
id='',
|
|
157
|
+
msg=trans('confirm.remote_store.clear'),
|
|
159
158
|
)
|
|
160
159
|
return
|
|
161
|
-
self.window.update_status("Clearing
|
|
160
|
+
self.window.update_status("Clearing stores...please wait...")
|
|
162
161
|
QApplication.processEvents()
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
self.window.controller.remote_store.google.update_files_list()
|
|
171
|
-
except Exception:
|
|
172
|
-
pass
|
|
173
|
-
|
|
174
|
-
self.window.update_status("OK. Store documents cleared.")
|
|
175
|
-
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
162
|
+
self.ctrl._core_for(self._get_provider()).truncate()
|
|
163
|
+
self.ctrl.update()
|
|
164
|
+
self.ctrl.current = None
|
|
165
|
+
self.ctrl.init()
|
|
166
|
+
self.window.update_status("OK. All stores cleared.")
|
|
167
|
+
if self._get_provider() == "openai":
|
|
168
|
+
self.window.controller.assistant.files.update()
|
|
176
169
|
|
|
177
170
|
def clear_files(self, force: bool = False):
|
|
178
|
-
"""
|
|
179
|
-
Clear documents (all, local only)
|
|
180
|
-
"""
|
|
181
171
|
if not force:
|
|
182
172
|
self.window.ui.dialogs.confirm(
|
|
183
|
-
type='remote_store.
|
|
173
|
+
type=f'remote_store.files.clear.all',
|
|
184
174
|
id='',
|
|
185
175
|
msg=trans('confirm.assistant.files.clear'),
|
|
186
176
|
)
|
|
187
177
|
return
|
|
188
178
|
self.window.update_status("Clearing documents...please wait...")
|
|
189
179
|
QApplication.processEvents()
|
|
190
|
-
self.
|
|
180
|
+
self.ctrl._files_core_for(self._get_provider()).truncate_local()
|
|
181
|
+
self.ctrl.update()
|
|
191
182
|
self.window.update_status("OK. All documents cleared.")
|
|
192
183
|
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
193
184
|
|
|
194
|
-
def
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
185
|
+
def clear_store_files(self, store_id: Optional[Union[str, list]] = None, force: bool = False):
|
|
186
|
+
if store_id is None:
|
|
187
|
+
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
188
|
+
return
|
|
198
189
|
if not force:
|
|
199
190
|
self.window.ui.dialogs.confirm(
|
|
200
|
-
type='remote_store.
|
|
201
|
-
id=
|
|
202
|
-
msg=trans('confirm.
|
|
191
|
+
type=f'remote_store.files.clear.store',
|
|
192
|
+
id=store_id,
|
|
193
|
+
msg=trans('confirm.assistant.files.clear'),
|
|
203
194
|
)
|
|
204
195
|
return
|
|
205
|
-
self.window.update_status("Clearing
|
|
196
|
+
self.window.update_status("Clearing store documents...please wait...")
|
|
206
197
|
QApplication.processEvents()
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
self.
|
|
211
|
-
self.window.
|
|
198
|
+
ids = store_id if isinstance(store_id, list) else [store_id]
|
|
199
|
+
for sid in ids:
|
|
200
|
+
self.ctrl._files_core_for(self._get_provider()).truncate_local(sid)
|
|
201
|
+
self.ctrl.update()
|
|
202
|
+
self.window.update_status("OK. Store documents cleared.")
|
|
203
|
+
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
212
204
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
205
|
+
# ---------- Upload ----------
|
|
206
|
+
|
|
207
|
+
def open_upload_files(self):
|
|
208
|
+
if self.ctrl.current is None:
|
|
209
|
+
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
210
|
+
return
|
|
211
|
+
options = QFileDialog.Options()
|
|
212
|
+
files, _ = QFileDialog.getOpenFileNames(
|
|
213
|
+
self.window,
|
|
214
|
+
"Select file(s)...",
|
|
215
|
+
"",
|
|
216
|
+
"All Files (*)",
|
|
217
|
+
options=options
|
|
218
|
+
)
|
|
219
|
+
if files:
|
|
220
|
+
self.files_to_upload = files
|
|
221
|
+
if self.files_to_upload:
|
|
222
|
+
msg = "Are you sure you want to upload {} file(s)?".format(len(self.files_to_upload))
|
|
218
223
|
self.window.ui.dialogs.confirm(
|
|
219
|
-
type=
|
|
220
|
-
id=
|
|
221
|
-
msg=
|
|
224
|
+
type=f"remote_store.files.upload",
|
|
225
|
+
id=0,
|
|
226
|
+
msg=msg,
|
|
222
227
|
)
|
|
223
|
-
return
|
|
224
|
-
self.window.update_status("Removing File Search stores...please wait...")
|
|
225
|
-
QApplication.processEvents()
|
|
226
|
-
self.window.core.remote_store.google.truncate()
|
|
227
|
-
self.window.core.api.google.store.importer.truncate_vector_stores()
|
|
228
|
-
self.window.controller.remote_store.google.update()
|
|
229
|
-
self.window.controller.remote_store.google.current = None
|
|
230
|
-
self.window.controller.remote_store.google.init()
|
|
231
228
|
|
|
232
|
-
def
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
229
|
+
def open_upload_dir(self):
|
|
230
|
+
if self.ctrl.current is None:
|
|
231
|
+
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
232
|
+
return
|
|
233
|
+
options = QFileDialog.Options()
|
|
234
|
+
directory = QFileDialog.getExistingDirectory(self.window, "Select directory...", options=options)
|
|
235
|
+
if directory:
|
|
236
|
+
self.files_to_upload = self.window.core.filesystem.get_files_from_dir(directory)
|
|
237
|
+
if self.files_to_upload:
|
|
238
|
+
msg = ("Are you sure you want to upload {} file(s) from directory {}?".
|
|
239
|
+
format(len(self.files_to_upload), directory))
|
|
237
240
|
self.window.ui.dialogs.confirm(
|
|
238
|
-
type=
|
|
239
|
-
id=
|
|
240
|
-
msg=
|
|
241
|
+
type=f"remote_store.files.upload",
|
|
242
|
+
id=0,
|
|
243
|
+
msg=msg,
|
|
241
244
|
)
|
|
245
|
+
|
|
246
|
+
def upload(self, force: bool = False):
|
|
247
|
+
if self.ctrl.current is None:
|
|
248
|
+
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
242
249
|
return
|
|
243
|
-
self.window.update_status("
|
|
250
|
+
self.window.update_status("Uploading files...please wait...")
|
|
244
251
|
QApplication.processEvents()
|
|
245
|
-
self.
|
|
252
|
+
self._importer().upload_files(self.ctrl.current, self.files_to_upload)
|
|
253
|
+
self.files_to_upload = []
|
|
254
|
+
|
|
255
|
+
def refresh_delayed(self, ms: int = 1000, all: bool = False):
|
|
256
|
+
if all:
|
|
257
|
+
self.window.update_status("Refreshing all stores...")
|
|
258
|
+
QTimer.singleShot(ms, lambda: self.refresh_stores(force=True))
|
|
259
|
+
return
|
|
260
|
+
self.window.update_status("Refreshing status...")
|
|
261
|
+
QTimer.singleShot(ms, lambda: self.ctrl.refresh_status())
|
|
262
|
+
|
|
263
|
+
# ---------- Importer signal handlers (called by provider Importer) ----------
|
|
246
264
|
|
|
247
265
|
def handle_refreshed_stores(self, num: int):
|
|
248
|
-
self.
|
|
249
|
-
self.window.controller.remote_store.google.update()
|
|
266
|
+
self.ctrl.update()
|
|
250
267
|
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
251
268
|
self.window.update_status("OK. All stores refreshed.")
|
|
252
269
|
|
|
253
270
|
def handle_refreshed_stores_failed(self, error: Any):
|
|
254
271
|
self.window.core.debug.log(error)
|
|
255
|
-
|
|
256
|
-
self.window.controller.remote_store.google.update()
|
|
272
|
+
self.ctrl.update()
|
|
257
273
|
self.window.update_status("Error refreshing stores.")
|
|
258
274
|
self.window.ui.dialogs.alert(error)
|
|
259
275
|
|
|
260
276
|
def handle_imported_stores(self, num: int):
|
|
261
|
-
self.
|
|
277
|
+
self.ctrl.after_imported_stores(self._get_provider())
|
|
278
|
+
self.ctrl.update()
|
|
262
279
|
self.window.update_status("OK. Imported stores: " + str(num) + ".")
|
|
263
280
|
|
|
264
281
|
def handle_imported_stores_failed(self, error: Any):
|
|
265
282
|
self.window.core.debug.log(error)
|
|
266
|
-
self.
|
|
267
|
-
print("Error importing stores", error)
|
|
283
|
+
self.ctrl.update()
|
|
268
284
|
self.window.update_status("Error importing stores.")
|
|
269
285
|
self.window.ui.dialogs.alert(error)
|
|
270
286
|
|
|
271
287
|
def handle_truncated_stores(self, num: int):
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
self.
|
|
278
|
-
self.
|
|
279
|
-
self.window.controller.remote_store.google.current = None
|
|
280
|
-
self.window.controller.remote_store.google.init()
|
|
288
|
+
# Clear local DB for provider
|
|
289
|
+
core = self.ctrl._core_for(self._get_provider())
|
|
290
|
+
core.truncate()
|
|
291
|
+
self.ctrl.after_truncated_stores(self._get_provider())
|
|
292
|
+
self.ctrl.update()
|
|
293
|
+
self.ctrl.current = None
|
|
294
|
+
self.ctrl.init()
|
|
281
295
|
self.window.update_status("OK. Removed stores: " + str(num) + ".")
|
|
282
296
|
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
283
297
|
|
|
284
298
|
def handle_truncated_stores_failed(self, error: Any):
|
|
285
|
-
"""
|
|
286
|
-
Handle error on truncating stores
|
|
287
|
-
|
|
288
|
-
:param error: error message
|
|
289
|
-
"""
|
|
290
299
|
self.window.core.debug.log(error)
|
|
291
|
-
|
|
292
|
-
self.window.controller.remote_store.google.update()
|
|
300
|
+
self.ctrl.update()
|
|
293
301
|
self.window.update_status("Error removing stores.")
|
|
294
302
|
self.window.ui.dialogs.alert(error)
|
|
295
303
|
|
|
296
304
|
def handle_imported_files(self, num: int):
|
|
297
|
-
|
|
305
|
+
try:
|
|
306
|
+
self.window.controller.assistant.files.update()
|
|
307
|
+
except Exception:
|
|
308
|
+
pass
|
|
309
|
+
self.window.update_status("OK. Imported files: " + str(num) + ".")
|
|
298
310
|
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
299
311
|
|
|
300
312
|
def handle_imported_files_failed(self, error: Any):
|
|
301
313
|
self.window.core.debug.log(error)
|
|
302
|
-
print("Error importing documents")
|
|
303
314
|
self.window.update_status("Error importing documents.")
|
|
304
315
|
self.window.ui.dialogs.alert(error)
|
|
305
316
|
|
|
306
317
|
def handle_truncated_files(self, store_id: Optional[str] = None, num: int = 0):
|
|
307
318
|
self.window.update_status("OK. Truncated documents: " + str(num) + ".")
|
|
308
|
-
# Immediate UI refresh of files panel (local DB is already truncated)
|
|
309
319
|
try:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
self.refresh_delayed(1200)
|
|
319
|
-
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
320
|
+
if store_id :
|
|
321
|
+
self.ctrl.refresh_by_store_id_provider(self._get_provider(), store_id)
|
|
322
|
+
else:
|
|
323
|
+
self.refresh_delayed(1200, all=True)
|
|
324
|
+
except Exception as e:
|
|
325
|
+
print(e)
|
|
326
|
+
finally:
|
|
327
|
+
self.window.ui.dialogs.alert(trans("status.finished"))
|
|
320
328
|
|
|
321
329
|
def handle_truncated_files_failed(self, error: Any):
|
|
322
330
|
self.window.core.debug.log(error)
|
|
323
|
-
print("Error truncating documents")
|
|
324
331
|
self.window.update_status("Error truncating documents.")
|
|
325
332
|
self.window.ui.dialogs.alert(error)
|
|
326
333
|
|
|
327
|
-
def open_upload_files(self):
|
|
328
|
-
"""Open upload files dialog"""
|
|
329
|
-
if self.window.controller.remote_store.google.current is None:
|
|
330
|
-
self.window.ui.dialogs.alert("Please select File Search store first.")
|
|
331
|
-
return
|
|
332
|
-
|
|
333
|
-
options = QFileDialog.Options()
|
|
334
|
-
files, _ = QFileDialog.getOpenFileNames(
|
|
335
|
-
self.window,
|
|
336
|
-
"Select file(s)...",
|
|
337
|
-
"",
|
|
338
|
-
"All Files (*)",
|
|
339
|
-
options=options
|
|
340
|
-
)
|
|
341
|
-
if files:
|
|
342
|
-
self.files_to_upload = files
|
|
343
|
-
|
|
344
|
-
if self.files_to_upload:
|
|
345
|
-
msg = "Are you sure you want to upload {} file(s)?".format(len(self.files_to_upload))
|
|
346
|
-
self.window.ui.dialogs.confirm(
|
|
347
|
-
type="remote_store.google.files.upload",
|
|
348
|
-
id=0,
|
|
349
|
-
msg=msg,
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
def open_upload_dir(self):
|
|
353
|
-
"""Open upload directory dialog"""
|
|
354
|
-
if self.window.controller.remote_store.google.current is None:
|
|
355
|
-
self.window.ui.dialogs.alert("Please select File Search store first.")
|
|
356
|
-
return
|
|
357
|
-
|
|
358
|
-
options = QFileDialog.Options()
|
|
359
|
-
directory = QFileDialog.getExistingDirectory(
|
|
360
|
-
self.window,
|
|
361
|
-
"Select directory...",
|
|
362
|
-
options=options
|
|
363
|
-
)
|
|
364
|
-
if directory:
|
|
365
|
-
self.files_to_upload = self.window.core.filesystem.get_files_from_dir(directory)
|
|
366
|
-
|
|
367
|
-
if self.files_to_upload:
|
|
368
|
-
msg = ("Are you sure you want to upload {} file(s) from directory {}?".
|
|
369
|
-
format(len(self.files_to_upload), directory))
|
|
370
|
-
self.window.ui.dialogs.confirm(
|
|
371
|
-
type="remote_store.google.files.upload",
|
|
372
|
-
id=0,
|
|
373
|
-
msg=msg,
|
|
374
|
-
)
|
|
375
|
-
|
|
376
|
-
def refresh_delayed(self, ms: int = 1000):
|
|
377
|
-
self.window.update_status("Refreshing status...")
|
|
378
|
-
QTimer.singleShot(ms, lambda: self.window.controller.remote_store.google.refresh_status())
|
|
379
|
-
|
|
380
|
-
def upload(self, force: bool = False):
|
|
381
|
-
"""Upload files to File Search store"""
|
|
382
|
-
if self.window.controller.remote_store.google.current is None:
|
|
383
|
-
self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
|
|
384
|
-
return
|
|
385
|
-
|
|
386
|
-
store_id = self.window.controller.remote_store.google.current
|
|
387
|
-
self.window.update_status("Uploading files...please wait...")
|
|
388
|
-
QApplication.processEvents()
|
|
389
|
-
self.window.core.api.google.store.importer.upload_files(store_id, self.files_to_upload)
|
|
390
|
-
self.files_to_upload = []
|
|
391
|
-
|
|
392
334
|
def handle_uploaded_files(self, num: int):
|
|
335
|
+
try:
|
|
336
|
+
self.window.controller.assistant.files.update()
|
|
337
|
+
except Exception:
|
|
338
|
+
pass
|
|
393
339
|
self.window.update_status("OK. Uploaded files: " + str(num) + ".")
|
|
394
340
|
self.window.ui.dialogs.alert("OK. Uploaded files: " + str(num) + ".")
|
|
395
341
|
self.refresh_delayed(1500)
|
|
396
342
|
|
|
397
343
|
def handle_uploaded_files_failed(self, error: Any):
|
|
398
344
|
self.window.core.debug.log(error)
|
|
399
|
-
print("Error uploading files")
|
|
400
345
|
self.refresh_delayed(1500)
|
|
401
346
|
self.window.update_status("Error uploading files.")
|
|
402
|
-
self.window.ui.dialogs.alert(error)
|
|
347
|
+
self.window.ui.dialogs.alert(error)
|
|
348
|
+
|
|
349
|
+
# ---------- Internal ----------
|
|
350
|
+
|
|
351
|
+
def _get_provider(self):
|
|
352
|
+
return self.ctrl.provider_key
|
|
353
|
+
|
|
354
|
+
def _importer(self):
|
|
355
|
+
provider = self._get_provider()
|
|
356
|
+
if (hasattr(self.window.core.api, provider)
|
|
357
|
+
and hasattr(getattr(self.window.core.api, provider), 'store')
|
|
358
|
+
and hasattr(getattr(self.window.core.api, provider).store, 'importer')):
|
|
359
|
+
return getattr(self.window.core.api, provider).store.importer
|