pygpt-net 2.7.4__py3-none-any.whl → 2.7.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.
Files changed (159) hide show
  1. pygpt_net/CHANGELOG.txt +15 -0
  2. pygpt_net/__init__.py +4 -4
  3. pygpt_net/app_core.py +4 -2
  4. pygpt_net/controller/__init__.py +5 -1
  5. pygpt_net/controller/assistant/assistant.py +1 -4
  6. pygpt_net/controller/assistant/batch.py +5 -504
  7. pygpt_net/controller/assistant/editor.py +5 -5
  8. pygpt_net/controller/assistant/files.py +16 -16
  9. pygpt_net/controller/chat/handler/google_stream.py +307 -1
  10. pygpt_net/controller/chat/handler/worker.py +10 -25
  11. pygpt_net/controller/chat/handler/xai_stream.py +621 -52
  12. pygpt_net/controller/chat/image.py +2 -2
  13. pygpt_net/controller/debug/fixtures.py +3 -2
  14. pygpt_net/controller/dialogs/confirm.py +73 -101
  15. pygpt_net/controller/files/files.py +65 -4
  16. pygpt_net/controller/lang/mapping.py +9 -9
  17. pygpt_net/controller/painter/capture.py +50 -1
  18. pygpt_net/controller/presets/presets.py +2 -1
  19. pygpt_net/controller/remote_store/__init__.py +12 -0
  20. pygpt_net/{provider/core/assistant_file/db_sqlite → controller/remote_store/google}/__init__.py +2 -2
  21. pygpt_net/controller/remote_store/google/batch.py +402 -0
  22. pygpt_net/controller/remote_store/google/store.py +615 -0
  23. pygpt_net/controller/remote_store/openai/__init__.py +12 -0
  24. pygpt_net/controller/remote_store/openai/batch.py +524 -0
  25. pygpt_net/controller/{assistant → remote_store/openai}/store.py +63 -60
  26. pygpt_net/controller/remote_store/remote_store.py +35 -0
  27. pygpt_net/controller/ui/ui.py +20 -1
  28. pygpt_net/core/assistants/assistants.py +3 -15
  29. pygpt_net/core/db/database.py +5 -3
  30. pygpt_net/core/filesystem/url.py +4 -1
  31. pygpt_net/core/locale/placeholder.py +35 -0
  32. pygpt_net/core/remote_store/__init__.py +12 -0
  33. pygpt_net/core/remote_store/google/__init__.py +11 -0
  34. pygpt_net/core/remote_store/google/files.py +224 -0
  35. pygpt_net/core/remote_store/google/store.py +248 -0
  36. pygpt_net/core/remote_store/openai/__init__.py +11 -0
  37. pygpt_net/core/{assistants → remote_store/openai}/files.py +26 -19
  38. pygpt_net/core/{assistants → remote_store/openai}/store.py +32 -15
  39. pygpt_net/core/remote_store/remote_store.py +24 -0
  40. pygpt_net/core/render/web/body.py +3 -2
  41. pygpt_net/core/types/chunk.py +27 -0
  42. pygpt_net/data/config/config.json +8 -4
  43. pygpt_net/data/config/models.json +77 -3
  44. pygpt_net/data/config/settings.json +45 -0
  45. pygpt_net/data/js/app/template.js +1 -1
  46. pygpt_net/data/js/app.min.js +2 -2
  47. pygpt_net/data/locale/locale.de.ini +44 -41
  48. pygpt_net/data/locale/locale.en.ini +56 -43
  49. pygpt_net/data/locale/locale.es.ini +44 -41
  50. pygpt_net/data/locale/locale.fr.ini +44 -41
  51. pygpt_net/data/locale/locale.it.ini +44 -41
  52. pygpt_net/data/locale/locale.pl.ini +45 -42
  53. pygpt_net/data/locale/locale.uk.ini +44 -41
  54. pygpt_net/data/locale/locale.zh.ini +44 -41
  55. pygpt_net/data/locale/plugin.cmd_history.de.ini +1 -1
  56. pygpt_net/data/locale/plugin.cmd_history.en.ini +1 -1
  57. pygpt_net/data/locale/plugin.cmd_history.es.ini +1 -1
  58. pygpt_net/data/locale/plugin.cmd_history.fr.ini +1 -1
  59. pygpt_net/data/locale/plugin.cmd_history.it.ini +1 -1
  60. pygpt_net/data/locale/plugin.cmd_history.pl.ini +1 -1
  61. pygpt_net/data/locale/plugin.cmd_history.uk.ini +1 -1
  62. pygpt_net/data/locale/plugin.cmd_history.zh.ini +1 -1
  63. pygpt_net/data/locale/plugin.cmd_mouse_control.en.ini +14 -0
  64. pygpt_net/data/locale/plugin.cmd_web.de.ini +1 -1
  65. pygpt_net/data/locale/plugin.cmd_web.en.ini +1 -1
  66. pygpt_net/data/locale/plugin.cmd_web.es.ini +1 -1
  67. pygpt_net/data/locale/plugin.cmd_web.fr.ini +1 -1
  68. pygpt_net/data/locale/plugin.cmd_web.it.ini +1 -1
  69. pygpt_net/data/locale/plugin.cmd_web.pl.ini +1 -1
  70. pygpt_net/data/locale/plugin.cmd_web.uk.ini +1 -1
  71. pygpt_net/data/locale/plugin.cmd_web.zh.ini +1 -1
  72. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +2 -2
  73. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +2 -2
  74. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +2 -2
  75. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +2 -2
  76. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +2 -2
  77. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +2 -2
  78. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +2 -2
  79. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +2 -2
  80. pygpt_net/item/assistant.py +1 -211
  81. pygpt_net/item/ctx.py +3 -3
  82. pygpt_net/item/store.py +238 -0
  83. pygpt_net/js_rc.py +2449 -2447
  84. pygpt_net/migrations/Version20260102190000.py +35 -0
  85. pygpt_net/migrations/__init__.py +3 -1
  86. pygpt_net/plugin/cmd_mouse_control/config.py +471 -1
  87. pygpt_net/plugin/cmd_mouse_control/plugin.py +487 -22
  88. pygpt_net/plugin/cmd_mouse_control/worker.py +464 -87
  89. pygpt_net/plugin/cmd_mouse_control/worker_sandbox.py +729 -0
  90. pygpt_net/plugin/idx_llama_index/config.py +2 -2
  91. pygpt_net/provider/api/anthropic/__init__.py +10 -8
  92. pygpt_net/provider/api/google/__init__.py +21 -58
  93. pygpt_net/provider/api/google/chat.py +545 -129
  94. pygpt_net/provider/api/google/computer.py +190 -0
  95. pygpt_net/provider/api/google/realtime/realtime.py +2 -2
  96. pygpt_net/provider/api/google/remote_tools.py +93 -0
  97. pygpt_net/provider/api/google/store.py +546 -0
  98. pygpt_net/provider/api/google/worker/__init__.py +0 -0
  99. pygpt_net/provider/api/google/worker/importer.py +392 -0
  100. pygpt_net/provider/api/openai/__init__.py +7 -3
  101. pygpt_net/provider/api/openai/computer.py +10 -1
  102. pygpt_net/provider/api/openai/responses.py +0 -0
  103. pygpt_net/provider/api/openai/store.py +6 -6
  104. pygpt_net/provider/api/openai/worker/importer.py +24 -24
  105. pygpt_net/provider/api/x_ai/__init__.py +10 -9
  106. pygpt_net/provider/api/x_ai/chat.py +272 -102
  107. pygpt_net/provider/core/config/patch.py +16 -1
  108. pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +3 -3
  109. pygpt_net/provider/core/model/patch.py +17 -3
  110. pygpt_net/provider/core/preset/json_file.py +13 -7
  111. pygpt_net/provider/core/{assistant_file → remote_file}/__init__.py +1 -1
  112. pygpt_net/provider/core/{assistant_file → remote_file}/base.py +9 -9
  113. pygpt_net/provider/core/remote_file/db_sqlite/__init__.py +12 -0
  114. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/patch.py +1 -1
  115. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/provider.py +23 -20
  116. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/storage.py +35 -27
  117. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/utils.py +5 -4
  118. pygpt_net/provider/core/{assistant_store → remote_store}/__init__.py +1 -1
  119. pygpt_net/provider/core/{assistant_store → remote_store}/base.py +10 -10
  120. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/__init__.py +1 -1
  121. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/patch.py +1 -1
  122. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/provider.py +16 -15
  123. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/storage.py +30 -23
  124. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/utils.py +5 -4
  125. pygpt_net/provider/core/{assistant_store → remote_store}/json_file.py +9 -9
  126. pygpt_net/provider/llms/google.py +2 -2
  127. pygpt_net/tools/image_viewer/ui/dialogs.py +298 -12
  128. pygpt_net/tools/text_editor/ui/widgets.py +5 -1
  129. pygpt_net/ui/base/config_dialog.py +3 -2
  130. pygpt_net/ui/base/context_menu.py +44 -1
  131. pygpt_net/ui/dialog/assistant.py +3 -3
  132. pygpt_net/ui/dialog/plugins.py +3 -1
  133. pygpt_net/ui/dialog/remote_store_google.py +539 -0
  134. pygpt_net/ui/dialog/{assistant_store.py → remote_store_openai.py} +95 -95
  135. pygpt_net/ui/dialogs.py +5 -3
  136. pygpt_net/ui/layout/chat/attachments_uploaded.py +3 -3
  137. pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
  138. pygpt_net/ui/layout/toolbox/indexes.py +22 -19
  139. pygpt_net/ui/layout/toolbox/model.py +28 -5
  140. pygpt_net/ui/menu/tools.py +13 -5
  141. pygpt_net/ui/widget/dialog/remote_store_google.py +56 -0
  142. pygpt_net/ui/widget/dialog/{assistant_store.py → remote_store_openai.py} +9 -9
  143. pygpt_net/ui/widget/element/button.py +4 -4
  144. pygpt_net/ui/widget/image/display.py +25 -8
  145. pygpt_net/ui/widget/lists/remote_store_google.py +248 -0
  146. pygpt_net/ui/widget/lists/{assistant_store.py → remote_store_openai.py} +21 -21
  147. pygpt_net/ui/widget/option/checkbox_list.py +47 -9
  148. pygpt_net/ui/widget/option/combo.py +39 -3
  149. pygpt_net/ui/widget/tabs/output.py +9 -1
  150. pygpt_net/ui/widget/textarea/editor.py +14 -1
  151. pygpt_net/ui/widget/textarea/input.py +20 -7
  152. pygpt_net/ui/widget/textarea/notepad.py +24 -1
  153. pygpt_net/ui/widget/textarea/output.py +23 -1
  154. pygpt_net/ui/widget/textarea/web.py +16 -1
  155. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/METADATA +41 -2
  156. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/RECORD +158 -132
  157. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/LICENSE +0 -0
  158. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/WHEEL +0 -0
  159. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,402 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
+ # ================================================== #
11
+
12
+ from typing import Optional, Any, Union
13
+
14
+ from PySide6.QtCore import QTimer
15
+ from PySide6.QtWidgets import QFileDialog, QApplication
16
+
17
+ from pygpt_net.utils import trans
18
+
19
+
20
+ class Batch:
21
+ def __init__(self, window=None):
22
+ """
23
+ File Search stores batch controller (Google)
24
+
25
+ :param window: Window instance
26
+ """
27
+ self.window = window
28
+ self.files_to_upload = []
29
+
30
+ def import_stores(self, force: bool = False):
31
+ """
32
+ Import File Search stores
33
+
34
+ :param force: if true, imports without confirmation
35
+ """
36
+ if not force:
37
+ self.window.ui.dialogs.confirm(
38
+ type='remote_store.google.import',
39
+ id='',
40
+ msg=trans('confirm.remote_store.import'),
41
+ )
42
+ return
43
+ self.window.update_status("Importing File Search stores...please wait...")
44
+ self.window.core.remote_store.google.truncate()
45
+ self.window.core.api.google.store.importer.import_vector_stores()
46
+ self.window.controller.remote_store.google.update()
47
+
48
+ def import_files(self, force: bool = False):
49
+ """
50
+ Sync documents with API (all)
51
+ """
52
+ if not force:
53
+ self.window.ui.dialogs.confirm(
54
+ type='remote_store.google.files.import.all',
55
+ id='',
56
+ msg=trans('confirm.remote_store.import_files'),
57
+ )
58
+ return
59
+ try:
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)
64
+
65
+ 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
+ if store_id is None:
72
+ self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
73
+ return
74
+
75
+ if not force:
76
+ self.window.ui.dialogs.confirm(
77
+ type='remote_store.google.files.import.store',
78
+ id=store_id,
79
+ msg=trans('confirm.remote_store.import_files.store'),
80
+ )
81
+ return
82
+ try:
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)
87
+
88
+ def truncate_files(self, force: bool = False):
89
+ """
90
+ Truncate all documents in API
91
+ """
92
+ if not force:
93
+ self.window.ui.dialogs.confirm(
94
+ type='remote_store.google.files.truncate',
95
+ id='',
96
+ msg=trans('confirm.remote_store.openai.files.truncate'), # reuse same translation key
97
+ )
98
+ return
99
+ self.window.update_status("Removing documents...please wait...")
100
+ QApplication.processEvents()
101
+ self.window.core.api.google.store.importer.truncate_files()
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)
113
+
114
+ def truncate_store_files(self, store_id: Union[str, list], force: bool = False):
115
+ """
116
+ Truncate all documents in API (store)
117
+ """
118
+ if store_id is None:
119
+ self.window.ui.dialogs.alert(trans("dialog.remote_store.alert.select"))
120
+ return
121
+
122
+ if not force:
123
+ self.window.ui.dialogs.confirm(
124
+ type='remote_store.google.files.truncate.store',
125
+ id=store_id,
126
+ msg=trans('confirm.remote_store.openai.files.truncate.store'),
127
+ )
128
+ return
129
+ self.window.update_status("Removing documents...please wait...")
130
+ QApplication.processEvents()
131
+ ids = store_id if isinstance(store_id, list) else [store_id]
132
+ for sid in ids:
133
+ self.window.core.api.google.store.importer.truncate_files(sid)
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
153
+
154
+ if not force:
155
+ self.window.ui.dialogs.confirm(
156
+ type='remote_store.google.files.clear.store',
157
+ id=store_id,
158
+ msg=trans('confirm.assistant.files.clear'),
159
+ )
160
+ return
161
+ self.window.update_status("Clearing store documents...please wait...")
162
+ QApplication.processEvents()
163
+
164
+ ids = store_id if isinstance(store_id, list) else [store_id]
165
+ for sid in ids:
166
+ self.window.core.remote_store.google.files.truncate_local(sid)
167
+
168
+ # Immediate UI refresh from local DB
169
+ try:
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"))
176
+
177
+ def clear_files(self, force: bool = False):
178
+ """
179
+ Clear documents (all, local only)
180
+ """
181
+ if not force:
182
+ self.window.ui.dialogs.confirm(
183
+ type='remote_store.google.files.clear.all',
184
+ id='',
185
+ msg=trans('confirm.assistant.files.clear'),
186
+ )
187
+ return
188
+ self.window.update_status("Clearing documents...please wait...")
189
+ QApplication.processEvents()
190
+ self.window.core.remote_store.google.files.truncate_local()
191
+ self.window.update_status("OK. All documents cleared.")
192
+ self.window.ui.dialogs.alert(trans("status.finished"))
193
+
194
+ def clear_stores(self, force: bool = False):
195
+ """
196
+ Clear File Search stores (local only)
197
+ """
198
+ if not force:
199
+ self.window.ui.dialogs.confirm(
200
+ type='remote_store.google.clear',
201
+ id='',
202
+ msg=trans('confirm.remote_store.clear'),
203
+ )
204
+ return
205
+ self.window.update_status("Clearing File Search stores...please wait...")
206
+ QApplication.processEvents()
207
+ self.window.core.remote_store.google.truncate()
208
+ self.window.controller.remote_store.google.update()
209
+ self.window.update_status("OK. All stores cleared.")
210
+ self.window.controller.remote_store.google.current = None
211
+ self.window.controller.remote_store.google.init()
212
+
213
+ def truncate_stores(self, force: bool = False):
214
+ """
215
+ Truncate File Search stores in API
216
+ """
217
+ if not force:
218
+ self.window.ui.dialogs.confirm(
219
+ type='remote_store.google.truncate',
220
+ id='',
221
+ msg=trans('confirm.remote_store.truncate'),
222
+ )
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
+
232
+ def refresh_stores(self, force: bool = False):
233
+ """
234
+ Refresh all File Search stores
235
+ """
236
+ if not force:
237
+ self.window.ui.dialogs.confirm(
238
+ type='remote_store.google.refresh',
239
+ id='',
240
+ msg=trans('confirm.remote_store.refresh'),
241
+ )
242
+ return
243
+ self.window.update_status("Refreshing File Search stores...please wait...")
244
+ QApplication.processEvents()
245
+ self.window.core.api.google.store.importer.refresh_vector_stores()
246
+
247
+ def handle_refreshed_stores(self, num: int):
248
+ self.window.controller.remote_store.google.update_current()
249
+ self.window.controller.remote_store.google.update()
250
+ self.window.ui.dialogs.alert(trans("status.finished"))
251
+ self.window.update_status("OK. All stores refreshed.")
252
+
253
+ def handle_refreshed_stores_failed(self, error: Any):
254
+ self.window.core.debug.log(error)
255
+ print("Error refreshing stores", error)
256
+ self.window.controller.remote_store.google.update()
257
+ self.window.update_status("Error refreshing stores.")
258
+ self.window.ui.dialogs.alert(error)
259
+
260
+ def handle_imported_stores(self, num: int):
261
+ self.window.controller.remote_store.google.update()
262
+ self.window.update_status("OK. Imported stores: " + str(num) + ".")
263
+
264
+ def handle_imported_stores_failed(self, error: Any):
265
+ self.window.core.debug.log(error)
266
+ self.window.controller.remote_store.google.update()
267
+ print("Error importing stores", error)
268
+ self.window.update_status("Error importing stores.")
269
+ self.window.ui.dialogs.alert(error)
270
+
271
+ def handle_truncated_stores(self, num: int):
272
+ """
273
+ Handle truncated stores
274
+
275
+ :param num: number of removed files
276
+ """
277
+ self.window.core.remote_store.google.truncate()
278
+ self.window.controller.remote_store.google.update()
279
+ self.window.controller.remote_store.google.current = None
280
+ self.window.controller.remote_store.google.init()
281
+ self.window.update_status("OK. Removed stores: " + str(num) + ".")
282
+ self.window.ui.dialogs.alert(trans("status.finished"))
283
+
284
+ def handle_truncated_stores_failed(self, error: Any):
285
+ """
286
+ Handle error on truncating stores
287
+
288
+ :param error: error message
289
+ """
290
+ self.window.core.debug.log(error)
291
+ print("Error removing stores", error)
292
+ self.window.controller.remote_store.google.update()
293
+ self.window.update_status("Error removing stores.")
294
+ self.window.ui.dialogs.alert(error)
295
+
296
+ def handle_imported_files(self, num: int):
297
+ self.window.update_status("OK. Imported documents: " + str(num) + ".")
298
+ self.window.ui.dialogs.alert(trans("status.finished"))
299
+
300
+ def handle_imported_files_failed(self, error: Any):
301
+ self.window.core.debug.log(error)
302
+ print("Error importing documents")
303
+ self.window.update_status("Error importing documents.")
304
+ self.window.ui.dialogs.alert(error)
305
+
306
+ def handle_truncated_files(self, store_id: Optional[str] = None, num: int = 0):
307
+ self.window.update_status("OK. Truncated documents: " + str(num) + ".")
308
+ # Immediate UI refresh of files panel (local DB is already truncated)
309
+ try:
310
+ self.window.controller.remote_store.google.update_files_list()
311
+ except Exception:
312
+ pass
313
+
314
+ # Refresh remote status to update counts and bytes
315
+ if store_id is not None:
316
+ self.window.controller.remote_store.google.refresh_by_store_id(store_id)
317
+ else:
318
+ self.refresh_delayed(1200)
319
+ self.window.ui.dialogs.alert(trans("status.finished"))
320
+
321
+ def handle_truncated_files_failed(self, error: Any):
322
+ self.window.core.debug.log(error)
323
+ print("Error truncating documents")
324
+ self.window.update_status("Error truncating documents.")
325
+ self.window.ui.dialogs.alert(error)
326
+
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
+ def handle_uploaded_files(self, num: int):
393
+ self.window.update_status("OK. Uploaded files: " + str(num) + ".")
394
+ self.window.ui.dialogs.alert("OK. Uploaded files: " + str(num) + ".")
395
+ self.refresh_delayed(1500)
396
+
397
+ def handle_uploaded_files_failed(self, error: Any):
398
+ self.window.core.debug.log(error)
399
+ print("Error uploading files")
400
+ self.refresh_delayed(1500)
401
+ self.window.update_status("Error uploading files.")
402
+ self.window.ui.dialogs.alert(error)