pygpt-net 2.4.37__py3-none-any.whl → 2.4.39__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 (81) hide show
  1. CHANGELOG.md +11 -0
  2. README.md +24 -5
  3. pygpt_net/CHANGELOG.txt +11 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/__init__.py +3 -1
  6. pygpt_net/controller/calendar/__init__.py +3 -1
  7. pygpt_net/controller/chat/render.py +8 -5
  8. pygpt_net/controller/config/placeholder.py +29 -0
  9. pygpt_net/controller/ctx/__init__.py +32 -24
  10. pygpt_net/controller/ctx/common.py +3 -2
  11. pygpt_net/controller/dialogs/confirm.py +2 -2
  12. pygpt_net/controller/lang/custom.py +2 -7
  13. pygpt_net/controller/lang/mapping.py +2 -2
  14. pygpt_net/controller/layout.py +2 -2
  15. pygpt_net/controller/notepad.py +8 -5
  16. pygpt_net/controller/settings/editor.py +6 -0
  17. pygpt_net/controller/theme/__init__.py +33 -8
  18. pygpt_net/controller/theme/common.py +22 -1
  19. pygpt_net/controller/theme/markdown.py +26 -14
  20. pygpt_net/controller/theme/menu.py +26 -5
  21. pygpt_net/controller/ui/tabs.py +201 -58
  22. pygpt_net/core/attachments/context.py +14 -12
  23. pygpt_net/core/audio/__init__.py +59 -1
  24. pygpt_net/core/ctx/__init__.py +11 -1
  25. pygpt_net/core/ctx/container.py +16 -9
  26. pygpt_net/core/ctx/output.py +86 -67
  27. pygpt_net/core/debug/tabs.py +3 -2
  28. pygpt_net/core/filesystem/__init__.py +5 -19
  29. pygpt_net/core/filesystem/url.py +7 -3
  30. pygpt_net/core/render/base.py +14 -3
  31. pygpt_net/core/render/markdown/renderer.py +3 -1
  32. pygpt_net/core/render/plain/renderer.py +3 -3
  33. pygpt_net/core/render/web/body.py +39 -17
  34. pygpt_net/core/render/web/renderer.py +7 -5
  35. pygpt_net/core/tabs/__init__.py +180 -71
  36. pygpt_net/core/tabs/tab.py +13 -4
  37. pygpt_net/data/config/config.json +14 -4
  38. pygpt_net/data/config/models.json +3 -3
  39. pygpt_net/data/config/modes.json +3 -3
  40. pygpt_net/data/config/settings.json +55 -10
  41. pygpt_net/data/config/settings_section.json +3 -0
  42. pygpt_net/data/css/style.light.css +1 -0
  43. pygpt_net/data/css/{web.css → web-blocks.css} +144 -133
  44. pygpt_net/data/css/web-chatgpt.css +342 -0
  45. pygpt_net/data/css/web-chatgpt.dark.css +64 -0
  46. pygpt_net/data/css/web-chatgpt.light.css +75 -0
  47. pygpt_net/data/css/web-chatgpt_wide.css +342 -0
  48. pygpt_net/data/css/web-chatgpt_wide.dark.css +64 -0
  49. pygpt_net/data/css/web-chatgpt_wide.light.css +75 -0
  50. pygpt_net/data/locale/locale.de.ini +12 -0
  51. pygpt_net/data/locale/locale.en.ini +14 -1
  52. pygpt_net/data/locale/locale.es.ini +12 -0
  53. pygpt_net/data/locale/locale.fr.ini +12 -0
  54. pygpt_net/data/locale/locale.it.ini +12 -0
  55. pygpt_net/data/locale/locale.pl.ini +12 -0
  56. pygpt_net/data/locale/locale.uk.ini +12 -0
  57. pygpt_net/data/locale/locale.zh.ini +12 -0
  58. pygpt_net/plugin/audio_input/simple.py +21 -5
  59. pygpt_net/provider/core/config/patch.py +22 -1
  60. pygpt_net/provider/core/ctx/base.py +4 -1
  61. pygpt_net/provider/core/ctx/db_sqlite/__init__.py +10 -1
  62. pygpt_net/provider/core/ctx/db_sqlite/storage.py +22 -1
  63. pygpt_net/ui/layout/chat/input.py +10 -18
  64. pygpt_net/ui/layout/chat/output.py +26 -44
  65. pygpt_net/ui/layout/toolbox/footer.py +18 -2
  66. pygpt_net/ui/menu/config.py +7 -11
  67. pygpt_net/ui/menu/theme.py +9 -2
  68. pygpt_net/ui/widget/lists/context.py +1 -0
  69. pygpt_net/ui/widget/tabs/layout.py +195 -0
  70. pygpt_net/ui/widget/tabs/output.py +124 -35
  71. pygpt_net/ui/widget/textarea/html.py +11 -1
  72. pygpt_net/ui/widget/textarea/output.py +10 -1
  73. pygpt_net/ui/widget/textarea/search_input.py +4 -1
  74. pygpt_net/ui/widget/textarea/web.py +49 -9
  75. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/METADATA +25 -6
  76. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/RECORD +81 -74
  77. /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
  78. /pygpt_net/data/css/{web.light.css → web-blocks.light.css} +0 -0
  79. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/LICENSE +0 -0
  80. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/WHEEL +0 -0
  81. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.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: 2024.11.05 23:00:00 #
9
+ # Updated Date: 2024.12.09 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from datetime import datetime
@@ -128,7 +128,7 @@ class Renderer(BaseRenderer):
128
128
  :param clear: True if clear all output before append
129
129
  """
130
130
  if clear:
131
- self.clear_output()
131
+ self.clear_output(meta)
132
132
 
133
133
  i = 0
134
134
  for item in items:
@@ -399,7 +399,7 @@ class Renderer(BaseRenderer):
399
399
  :param meta: context meta
400
400
  """
401
401
  self.reset()
402
- self.get_output_node().clear()
402
+ self.get_output_node(meta).clear()
403
403
 
404
404
  def clear_input(self):
405
405
  """Clear 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: 2024.11.26 04:00:00 #
9
+ # Updated Date: 2024.12.09 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -46,21 +46,35 @@ class Body:
46
46
 
47
47
  :return: CSS styles
48
48
  """
49
- dark_styles = ["dracula", "fruity", "github-dark", "gruvbox-dark", "inkpot", "material", "monokai",
50
- "native", "nord", "nord-darker", "one-dark", "paraiso-dark", "rrt", "solarized-dark",
51
- "stata-dark", "vim", "zenburn"]
52
- style = self.window.core.config.get("render.code_syntax")
53
- if style is None or style == "":
54
- style = "default"
49
+ syntax_dark = [
50
+ "dracula",
51
+ "fruity",
52
+ "github-dark",
53
+ "gruvbox-dark",
54
+ "inkpot",
55
+ "material",
56
+ "monokai",
57
+ "native",
58
+ "nord",
59
+ "nord-darker",
60
+ "one-dark",
61
+ "paraiso-dark",
62
+ "rrt",
63
+ "solarized-dark",
64
+ "stata-dark",
65
+ "vim",
66
+ "zenburn",
67
+ ]
68
+ syntax_style = self.window.core.config.get("render.code_syntax")
69
+ if syntax_style is None or syntax_style == "":
70
+ syntax_style = "default"
55
71
  fonts_path = os.path.join(self.window.core.config.get_app_path(), "data", "fonts").replace("\\", "/")
56
72
  stylesheet = self.window.controller.theme.markdown.get_web_css().replace('%fonts%', fonts_path)
57
- if style in dark_styles:
73
+ if syntax_style in syntax_dark:
58
74
  stylesheet += "pre { color: #fff; }"
59
75
  else:
60
76
  stylesheet += "pre { color: #000; }"
61
- content = stylesheet + """
62
- """ + self.highlight.get_style_defs()
63
- return content
77
+ return stylesheet + " " + self.highlight.get_style_defs()
64
78
 
65
79
  def prepare_action_icons(self, ctx: CtxItem) -> str:
66
80
  """
@@ -187,9 +201,9 @@ class Body:
187
201
  """
188
202
  icon_path = os.path.join(
189
203
  self.window.core.config.get_app_path(),
190
- "data", "icons", "public_filled.svg"
204
+ "data", "icons", "language.svg"
191
205
  )
192
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
206
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
193
207
  num_str = ""
194
208
  if num is not None and num_all is not None and num_all > 1:
195
209
  num_str = " [{}]".format(num)
@@ -235,7 +249,7 @@ class Body:
235
249
  self.window.core.config.get_app_path(),
236
250
  "data", "icons", "db.svg"
237
251
  )
238
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
252
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
239
253
  if html_sources != "":
240
254
  html += "<p>{icon}<small><b>{prefix}:</b></small></p>".format(
241
255
  prefix=trans('chat.prefix.doc'),
@@ -259,7 +273,7 @@ class Body:
259
273
  self.window.core.config.get_app_path(),
260
274
  "data", "icons", "attachments.svg"
261
275
  )
262
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
276
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
263
277
  num_str = ""
264
278
  if num is not None and num_all is not None and num_all > 1:
265
279
  num_str = " [{}]".format(num)
@@ -311,7 +325,7 @@ class Body:
311
325
  html += "</div>"
312
326
  return html
313
327
 
314
- def get_html(self) -> str:
328
+ def get_html(self, pid: int) -> str:
315
329
  """
316
330
  Build webview HTML code
317
331
 
@@ -319,12 +333,14 @@ class Body:
319
333
  """
320
334
  classes = []
321
335
  classes_str = ""
336
+ style = self.window.core.config.get("theme.style", "blocks")
322
337
  if self.window.core.config.get('render.blocks'):
323
338
  classes.append("display-blocks")
324
339
  if self.window.core.config.get('ctx.edit_icons'):
325
340
  classes.append("display-edit-icons")
326
341
  if self.is_timestamp_enabled():
327
342
  classes.append("display-timestamp")
343
+ classes.append("theme-" + style)
328
344
  if classes:
329
345
  classes_str = ' class="' + " ".join(classes) + '"'
330
346
 
@@ -354,13 +370,14 @@ class Body:
354
370
  let scrollTimeout = null;
355
371
  let prevScroll = 0;
356
372
  let bridge;
373
+ let pid = """ + str(pid) + """
357
374
  new QWebChannel(qt.webChannelTransport, function (channel) {
358
375
  bridge = channel.objects.bridge;
359
376
  });
360
377
  history.scrollRestoration = "manual";
361
378
  document.addEventListener('keydown', function(event) {
362
379
  if (event.ctrlKey && event.key === 'f') {
363
- window.location.href = 'bridge://open_find'; // send to bridge
380
+ window.location.href = 'bridge://open_find:' + pid; // send to bridge
364
381
  event.preventDefault();
365
382
  }
366
383
  if (event.key === 'Escape') {
@@ -368,6 +385,11 @@ class Body:
368
385
  event.preventDefault();
369
386
  }
370
387
  });
388
+ document.addEventListener('click', function(event) {
389
+ if (event.target.tagName !== 'A' && !event.target.closest('a')) {
390
+ window.location.href = 'bridge://focus';
391
+ }
392
+ });
371
393
  function highlightCode() {
372
394
  document.querySelectorAll('pre code').forEach(el => {
373
395
  if (!el.classList.contains('hljs')) hljs.highlightElement(el);
@@ -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: 2024.11.26 04:00:00 #
9
+ # Updated Date: 2024.12.09 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -19,6 +19,7 @@ from pygpt_net.core.text.utils import has_unclosed_code_tag
19
19
  from pygpt_net.item.ctx import CtxItem, CtxMeta
20
20
  from pygpt_net.ui.widget.textarea.input import ChatInput
21
21
  from pygpt_net.utils import trans
22
+ from pygpt_net.core.tabs import Tab
22
23
 
23
24
  from .body import Body
24
25
  from .helpers import Helpers
@@ -59,16 +60,17 @@ class Renderer(BaseRenderer):
59
60
  node.set_meta(meta)
60
61
  self.reset(meta)
61
62
 
62
- def on_page_loaded(self, meta: CtxMeta = None):
63
+ def on_page_loaded(self, meta: CtxMeta = None, tab: Tab = None):
63
64
  """
64
65
  On page loaded callback from WebEngine widget
65
66
 
66
67
  :param meta: context meta
68
+ :param tab: Tab
67
69
  """
68
70
  if meta is None:
69
71
  return
70
- pid = self.get_or_create_pid(meta)
71
- if pid is None:
72
+ pid = tab.pid
73
+ if pid is None or pid not in self.pids:
72
74
  return
73
75
  self.pids[pid].loaded = True
74
76
  if self.pids[pid].html != "" and not self.pids[pid].use_buffer:
@@ -818,7 +820,7 @@ class Renderer(BaseRenderer):
818
820
  if self.pids[pid].loaded:
819
821
  return # wait for page load
820
822
 
821
- html = self.body.get_html()
823
+ html = self.body.get_html(pid)
822
824
  self.pids[pid].document = html
823
825
  self.get_output_node_by_pid(pid).setHtml(html, baseUrl="file://")
824
826