js_api.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from __future__ import annotations
  2. import json
  3. import os.path
  4. from typing import Iterator
  5. from uuid import uuid4
  6. from functools import partial
  7. import webview
  8. import platformdirs
  9. from plyer import camera
  10. from plyer import filechooser
  11. app_storage_path = platformdirs.user_pictures_dir
  12. user_select_image = partial(
  13. filechooser.open_file,
  14. path=platformdirs.user_pictures_dir(),
  15. filters=[["Image", "*.jpg", "*.jpeg", "*.png", "*.webp", "*.svg"]],
  16. )
  17. from .api import Api
  18. class JsApi(Api):
  19. def get_conversation(self, options: dict, message_id: str = None, scroll: bool = None, **kwargs) -> Iterator:
  20. window = webview.windows[0]
  21. if hasattr(self, "image") and self.image is not None:
  22. kwargs["image"] = open(self.image, "rb")
  23. for message in self._create_response_stream(
  24. self._prepare_conversation_kwargs(options, kwargs),
  25. options.get("conversation_id"),
  26. options.get('provider')
  27. ):
  28. if window.evaluate_js(
  29. f"""
  30. is_stopped() ? true :
  31. this.add_message_chunk({
  32. json.dumps(message)
  33. }, {
  34. json.dumps(message_id)
  35. }, {
  36. json.dumps(options.get('provider'))
  37. }, {
  38. 'true' if scroll else 'false'
  39. }); is_stopped();
  40. """):
  41. break
  42. self.image = None
  43. self.set_selected(None)
  44. def choose_image(self):
  45. user_select_image(
  46. on_selection=self.on_image_selection
  47. )
  48. def take_picture(self):
  49. filename = os.path.join(app_storage_path(), f"chat-{uuid4()}.png")
  50. camera.take_picture(filename=filename, on_complete=self.on_camera)
  51. def on_image_selection(self, filename):
  52. filename = filename[0] if isinstance(filename, list) and filename else filename
  53. if filename and os.path.exists(filename):
  54. self.image = filename
  55. else:
  56. self.image = None
  57. self.set_selected(None if self.image is None else "image")
  58. def on_camera(self, filename):
  59. if filename and os.path.exists(filename):
  60. self.image = filename
  61. else:
  62. self.image = None
  63. self.set_selected(None if self.image is None else "camera")
  64. def set_selected(self, input_id: str = None):
  65. window = webview.windows[0]
  66. if window is not None:
  67. window.evaluate_js(
  68. f"document.querySelector(`.image-label.selected`)?.classList.remove(`selected`);"
  69. )
  70. if input_id is not None and input_id in ("image", "camera"):
  71. window.evaluate_js(
  72. f'document.querySelector(`label[for="{input_id}"]`)?.classList.add(`selected`);'
  73. )
  74. def get_version(self):
  75. return super().get_version()
  76. def get_models(self):
  77. return super().get_models()
  78. def get_providers(self):
  79. return super().get_providers()
  80. def get_provider_models(self, provider: str, **kwargs):
  81. return super().get_provider_models(provider, **kwargs)