From 0f685f82525f7b1ed65954aae6fbaf5f000a3e88 Mon Sep 17 00:00:00 2001
From: JE-Chen <33644111+JE-Chen@users.noreply.github.com>
Date: Tue, 21 Nov 2023 16:18:22 +0800
Subject: [PATCH 1/2] AddPyside open bing GPT
---
GPT_EXE/browser/__init__.py | 0
GPT_EXE/browser/browser_download_window.py | 30 ++++++++++++++++++
GPT_EXE/browser/browser_view.py | 31 +++++++++++++++++++
GPT_EXE/browser/browser_widget.py | 30 ++++++++++++++++++
GPT_EXE/browser_that_open_bing_chat.py | 25 +++++++++++++++
requirements.txt | 4 ++-
test/unit_test/manual_test/test_bot_manual.py | 2 +-
7 files changed, 120 insertions(+), 2 deletions(-)
create mode 100644 GPT_EXE/browser/__init__.py
create mode 100644 GPT_EXE/browser/browser_download_window.py
create mode 100644 GPT_EXE/browser/browser_view.py
create mode 100644 GPT_EXE/browser/browser_widget.py
create mode 100644 GPT_EXE/browser_that_open_bing_chat.py
diff --git a/GPT_EXE/browser/__init__.py b/GPT_EXE/browser/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/GPT_EXE/browser/browser_download_window.py b/GPT_EXE/browser/browser_download_window.py
new file mode 100644
index 0000000..b7beec2
--- /dev/null
+++ b/GPT_EXE/browser/browser_download_window.py
@@ -0,0 +1,30 @@
+from PySide6.QtCore import Qt
+from PySide6.QtWebEngineCore import QWebEngineDownloadRequest
+from PySide6.QtWidgets import QWidget, QBoxLayout, QPlainTextEdit
+
+
+class BrowserDownloadWindow(QWidget):
+
+ def __init__(self, download_instance: QWebEngineDownloadRequest):
+ super().__init__()
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
+ self.box_layout = QBoxLayout(QBoxLayout.Direction.TopToBottom)
+ self.show_download_detail_plaintext = QPlainTextEdit()
+ self.show_download_detail_plaintext.setReadOnly(True)
+ self.setWindowTitle("Download")
+ self.download_instance = download_instance
+ self.download_instance.isFinishedChanged.connect(self.print_finish)
+ self.download_instance.interruptReasonChanged.connect(self.print_interrupt)
+ self.download_instance.stateChanged.connect(self.print_state)
+ self.download_instance.accept()
+ self.box_layout.addWidget(self.show_download_detail_plaintext)
+ self.setLayout(self.box_layout)
+
+ def print_finish(self):
+ self.show_download_detail_plaintext.appendPlainText(str(self.download_instance.isFinished()))
+
+ def print_interrupt(self):
+ self.show_download_detail_plaintext.appendPlainText(str(self.download_instance.interruptReason()))
+
+ def print_state(self):
+ self.show_download_detail_plaintext.appendPlainText(str(self.download_instance.state()))
diff --git a/GPT_EXE/browser/browser_view.py b/GPT_EXE/browser/browser_view.py
new file mode 100644
index 0000000..f924335
--- /dev/null
+++ b/GPT_EXE/browser/browser_view.py
@@ -0,0 +1,31 @@
+from typing import List
+
+from PySide6.QtCore import Qt
+from PySide6.QtWebEngineCore import QWebEngineDownloadRequest
+from PySide6.QtWebEngineWidgets import QWebEngineView
+
+from .browser_download_window import BrowserDownloadWindow
+
+
+class BrowserView(QWebEngineView):
+
+ def __init__(self, start_url: str = "https://www.google.com/"):
+ super().__init__()
+ self.setUrl(start_url)
+ self.download_list: List[QWebEngineDownloadRequest] = list()
+ self.download_window_list: List[BrowserDownloadWindow] = list()
+ self.page().profile().downloadRequested.connect(self.download_file)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
+
+ def download_file(self, download_instance: QWebEngineDownloadRequest):
+ self.download_list.append(download_instance)
+ download_detail_window = BrowserDownloadWindow(download_instance)
+ self.download_window_list.append(download_detail_window)
+ download_detail_window.show()
+
+ def closeEvent(self, event) -> None:
+ for download_instance in self.download_list:
+ download_instance.cancel()
+ for download_window in self.download_window_list:
+ download_window.close()
+ super().closeEvent(event)
diff --git a/GPT_EXE/browser/browser_widget.py b/GPT_EXE/browser/browser_widget.py
new file mode 100644
index 0000000..712a9ec
--- /dev/null
+++ b/GPT_EXE/browser/browser_widget.py
@@ -0,0 +1,30 @@
+from PySide6.QtGui import QAction, Qt
+from PySide6.QtWidgets import QWidget, QGridLayout, QPushButton, QInputDialog
+
+from .browser_view import BrowserView
+
+
+class JEBrowser(QWidget):
+
+ def __init__(self, start_url: str = "https://www.bing.com/chat"):
+ super().__init__()
+ # Browser setting
+ self.browser = BrowserView(start_url)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
+ # Action
+ self.find_action = QAction()
+ self.find_action.setShortcut("Ctrl+f")
+ self.find_action.triggered.connect(self.find_text)
+ self.addAction(self.find_action)
+ # Layout
+ self.grid_layout = QGridLayout()
+ self.grid_layout.addWidget(self.browser, 0, 0, -1, -1)
+ self.setLayout(self.grid_layout)
+
+ def find_text(self):
+ search_box = QInputDialog(self)
+ search_text, press_ok = search_box.getText(self, "Find text", "Find text")
+ if press_ok:
+ self.browser.findText(search_text)
+ else:
+ self.browser.findText("")
diff --git a/GPT_EXE/browser_that_open_bing_chat.py b/GPT_EXE/browser_that_open_bing_chat.py
new file mode 100644
index 0000000..2266273
--- /dev/null
+++ b/GPT_EXE/browser_that_open_bing_chat.py
@@ -0,0 +1,25 @@
+import sys
+
+from PySide6.QtCore import QCoreApplication
+from PySide6.QtWidgets import QMainWindow, QApplication
+from qt_material import apply_stylesheet
+
+from GPT_EXE.browser.browser_widget import JEBrowser
+
+
+class JustOpenGPTBrowser(QMainWindow):
+
+ def __init__(self):
+ super().__init__()
+ self.browser_widget = JEBrowser()
+ self.setCentralWidget(self.browser_widget)
+
+
+if __name__ == "__main__":
+ new_editor = QCoreApplication.instance()
+ if new_editor is None:
+ new_editor = QApplication(sys.argv)
+ window = JustOpenGPTBrowser()
+ apply_stylesheet(new_editor, theme='dark_amber.xml')
+ window.showMaximized()
+ sys.exit(new_editor.exec())
diff --git a/requirements.txt b/requirements.txt
index ed9fe43..8dc115b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,4 +5,6 @@ prompt_toolkit
requests
rich
re_edge_gpt
-regex
\ No newline at end of file
+regex
+PySide6
+qt-material
\ No newline at end of file
diff --git a/test/unit_test/manual_test/test_bot_manual.py b/test/unit_test/manual_test/test_bot_manual.py
index cd0aa8c..0da0a23 100644
--- a/test/unit_test/manual_test/test_bot_manual.py
+++ b/test/unit_test/manual_test/test_bot_manual.py
@@ -17,7 +17,7 @@ async def test_ask() -> None:
str(Path(str(Path.cwd()) + "/bing_cookies.json")), encoding="utf-8").read())
bot = await Chatbot.create(cookies=cookies)
response = await bot.ask(
- prompt="Deer soup",
+ prompt="How to get extract iron on mine",
conversation_style=ConversationStyle.balanced,
simplify_response=True
)
From de26ff5301bba58f7188b16ac3fbcafec7d8bd74 Mon Sep 17 00:00:00 2001
From: JE-Chen <33644111+JE-Chen@users.noreply.github.com>
Date: Wed, 22 Nov 2023 19:38:16 +0800
Subject: [PATCH 2/2] Refactor
---
README.md | 7 +++----
images/rate_limit.png | Bin 0 -> 6637 bytes
test/unit_test/manual_test/test_bot_manual.py | 2 +-
3 files changed, 4 insertions(+), 5 deletions(-)
create mode 100644 images/rate_limit.png
diff --git a/README.md b/README.md
index 0c0fa71..d9d6535 100644
--- a/README.md
+++ b/README.md
@@ -238,6 +238,9 @@ if __name__ == "__main__":
+> * Q: Exception: Throttled: Request is throttled.
+> * A: Bing's chat rate limit.
+> * ![rate_limit.png](images/rate_limit.png)
> * Q: RuntimeError: This event loop is already running
> * A: If you are using Jupyter, pls use nest_asyncio.apply()
> * Like: https://github.com/Integration-Automation/ReEdgeGPT/issues/30
@@ -259,7 +262,3 @@ if __name__ == "__main__":
> * A: Bing block your connect, Try to use proxy or clear cookie.
-
----
-> Origin repo (archived): https://github.com/acheong08/EdgeGPT
----
\ No newline at end of file
diff --git a/images/rate_limit.png b/images/rate_limit.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a10b025cbc9eeda292ef53b94da9581f0a1d444
GIT binary patch
literal 6637
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 None:
bot = None
try:
- cookies = json.loads(open(
+ cookies: list[dict] = json.loads(open(
str(Path(str(Path.cwd()) + "/bing_cookies.json")), encoding="utf-8").read())
bot = await Chatbot.create(cookies=cookies)
response = await bot.ask(