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(