Skip to content

Commit 83b0798

Browse files
authored
Merge pull request #132 from yjg30737/Dev
Dev
2 parents e161581 + 98c8f00 commit 83b0798

File tree

93 files changed

+3824
-1899
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+3824
-1899
lines changed

pyproject.toml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "pyqt-openai"
7+
version = "0.7.8"
8+
description = "PyQt/PySide(Python cross-platform GUI toolkit) OpenAI Chatbot"
9+
authors = [{ name = "Jung Gyu Yoon", email = "[email protected]" }]
10+
license = { text = "MIT" }
11+
readme = "README.md"
12+
dependencies = [
13+
"PyQt5 >= 5.14",
14+
"PyQt6",
15+
"qtpy",
16+
"aiohttp",
17+
"openai",
18+
"pyperclip",
19+
"jinja2",
20+
"llama-index",
21+
"requests",
22+
"langchain",
23+
"pillow",
24+
"replicate",
25+
"toml"
26+
]
27+
keywords = ['openai', 'pyqt', 'pyqt5', 'pyqt6', 'pyside6', 'chatbot', 'gpt', 'replicate']
28+
29+
# TODO testing each version
30+
requires-python = ">= 3.9"
31+
# 3.9
32+
# 3.10
33+
# 3.11
34+
# 3.12
35+
36+
# TODO add classifiers
37+
38+
[project.urls]
39+
homepage = "https://github.com/yjg30737/pyqt-openai.git"
40+
41+
[tool.setuptools]
42+
packages = [
43+
{ include = "pyqt_openai" }
44+
]
45+
46+
[tool.setuptools.package-data]
47+
pyqt_openai = [
48+
"ico/add.svg",
49+
"ico/case.svg",
50+
"ico/close.svg",
51+
"ico/copy.svg",
52+
"ico/customize.svg",
53+
"ico/delete.svg",
54+
"ico/discord.svg",
55+
"ico/export.svg",
56+
"ico/favorite_no.svg",
57+
"ico/favorite_yes.svg",
58+
"ico/fullscreen.svg",
59+
"ico/github.svg",
60+
"ico/history.svg",
61+
"ico/import.svg",
62+
"ico/info.svg",
63+
"ico/next.svg",
64+
"ico/openai.png",
65+
"ico/openai.svg",
66+
"ico/prev.svg",
67+
"ico/prompt.svg",
68+
"ico/question.svg",
69+
"ico/refresh.svg",
70+
"ico/regex.svg",
71+
"ico/save.svg",
72+
"ico/search.svg",
73+
"ico/setting.svg",
74+
"ico/sidebar.svg",
75+
"ico/stackontop.svg",
76+
"ico/user.png",
77+
"ico/user.svg",
78+
"ico/vertical_three_dots.svg",
79+
"ico/word.svg"
80+
]
81+
82+
[project.gui-scripts]
83+
pyqt-openai = "pyqt_openai.main:main"

pyqt_openai/__init__.py

Lines changed: 223 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,223 @@
1-
from pyqt_openai import *
1+
"""
2+
This file is used to store the constants and the global variables that are used throughout the application.
3+
"""
4+
5+
import json
6+
import os
7+
from pathlib import Path
8+
9+
import toml
10+
11+
# Load the pyproject.toml file
12+
SRC_DIR = Path(__file__).resolve().parent
13+
ROOT_DIR = SRC_DIR.parent
14+
SETUP_FILENAME = ROOT_DIR / "pyproject.toml"
15+
16+
with open(SETUP_FILENAME, "r") as file:
17+
pyproject_data = toml.load(file)
18+
19+
# For the sake of following the PEP8 standard, we will declare module-level dunder names.
20+
# PEP8 standard about dunder names: https://peps.python.org/pep-0008/#module-level-dunder-names
21+
22+
__version__ = pyproject_data["project"]["version"]
23+
__author__ = pyproject_data["project"]["authors"][0]['name']
24+
25+
# Constants
26+
# ----------------------------
27+
# APP
28+
APP_NAME = pyproject_data["project"]["name"]
29+
CONTACT = pyproject_data["project"]["authors"][0]['email']
30+
APP_ICON = 'icon.png'
31+
APP_INITIAL_WINDOW_SIZE = (1280, 768)
32+
LICENSE_URL = 'https://github.com/yjg30737/pyqt-openai/blob/main/LICENSE'
33+
PAYPAL_URL = 'https://paypal.me/yjg30737'
34+
BUYMEACOFFEE_URL = 'https://www.buymeacoffee.com/yjg30737'
35+
GITHUB_URL = 'https://github.com/yjg30737/pyqt-openai'
36+
DISCORD_URL = 'https://discord.gg/cHekprskVE'
37+
COLUMN_TO_EXCLUDE_FROM_SHOW_HIDE = ['id']
38+
DEFAULT_LANGUAGE = 'en_US'
39+
LANGUAGE_FILE = 'translations.json'
40+
LANGUAGE_DICT = {
41+
"English": "en_US",
42+
"Spanish": "es_ES",
43+
"Chinese": "zh_CN",
44+
"Russian": "ru_RU",
45+
"Korean": "ko_KR",
46+
"French": "fr_FR",
47+
"German": "de_DE",
48+
"Italian": "it_IT",
49+
"Hindi": "hi_IN",
50+
"Arabic": "ar_AE",
51+
"Japanese": "ja_JP",
52+
"Bengali": "bn_IN",
53+
"Urdu": "ur_PK",
54+
"Indonesian": "id_ID",
55+
"Portuguese": "pt_BR"
56+
}
57+
58+
## ICONS
59+
ICON_ADD = 'ico/add.svg'
60+
ICON_CASE = 'ico/case.svg'
61+
ICON_CLOSE = 'ico/close.svg'
62+
ICON_COPY = 'ico/copy.svg'
63+
ICON_CUSTOMIZE = 'ico/customize.svg'
64+
ICON_DELETE = 'ico/delete.svg'
65+
ICON_DISCORD = 'ico/discord.svg'
66+
ICON_EXPORT = 'ico/export.svg'
67+
ICON_FAVORITE_NO = 'ico/favorite_no.svg'
68+
ICON_FAVORITE_YES = 'ico/favorite_yes.svg'
69+
ICON_FULLSCREEN = 'ico/fullscreen.svg'
70+
ICON_GITHUB = 'ico/github.svg'
71+
ICON_HELP = 'ico/help.svg'
72+
ICON_HISTORY = 'ico/history.svg'
73+
ICON_IMPORT = 'ico/import.svg'
74+
ICON_INFO = 'ico/info.svg'
75+
ICON_NEXT = 'ico/next.svg'
76+
ICON_OPENAI = 'ico/openai.png'
77+
ICON_PREV = 'ico/prev.svg'
78+
ICON_PROMPT = 'ico/prompt.svg'
79+
ICON_QUESTION = 'ico/question.svg'
80+
ICON_REFRESH = 'ico/refresh.svg'
81+
ICON_REGEX = 'ico/regex.svg'
82+
ICON_SAVE = 'ico/save.svg'
83+
ICON_SEARCH = 'ico/search.svg'
84+
ICON_SETTING = 'ico/setting.svg'
85+
ICON_SIDEBAR = 'ico/sidebar.svg'
86+
ICON_STACKONTOP = 'ico/stackontop.svg'
87+
ICON_USER = 'ico/user.png'
88+
ICON_VERTICAL_THREE_DOTS = 'ico/vertical_three_dots.svg'
89+
ICON_WORD = 'ico/word.svg'
90+
91+
## CUSTOMIZE
92+
DEFAULT_ICON_SIZE = (24, 24)
93+
DEFAULT_USER_IMAGE_PATH = ICON_USER
94+
DEFAULT_AI_IMAGE_PATH = ICON_OPENAI
95+
DEFAULT_FONT_SIZE = 12
96+
DEFAULT_FONT_FAMILY = 'Arial'
97+
FONT_FAMILY_FOR_SOURCE = 'Courier'
98+
99+
## SHORTCUT
100+
SHORTCUT_GENERAL_ACTION = 'Enter'
101+
SHORTCUT_FIND_PREV = 'Ctrl+Shift+D'
102+
SHORTCUT_FIND_NEXT = 'Ctrl+D'
103+
SHORTCUT_FIND_CLOSE = 'Escape'
104+
SHORTCUT_PROMPT_BEGINNING = 'Ctrl+B'
105+
SHORTCUT_PROMPT_ENDING = 'Ctrl+E'
106+
SHORTCUT_SUPPORT_PROMPT_COMMAND = 'Ctrl+Shift+P'
107+
SHORTCUT_FULL_SCREEN = 'F11'
108+
109+
## DIRECTORY PATH & FILE'S NAME
110+
MAIN_INDEX = 'main.py'
111+
IMAGE_DEFAULT_SAVE_DIRECTORY = 'image_result'
112+
LLAMA_INDEX_DEFAULT_READ_DIRECTORY = './example'
113+
INI_FILE_NAME = 'pyqt_openai.ini'
114+
DB_FILE_NAME = 'conv'
115+
116+
## EXTENSIONS
117+
IMAGE_FILE_EXT = 'Image File (*.jpg *.png)'
118+
TEXT_FILE_EXT = 'Text File (*.txt)'
119+
JSON_FILE_EXT = 'JSON File (*.json)'
120+
READ_FILE_EXT = f'{TEXT_FILE_EXT};;{IMAGE_FILE_EXT}'
121+
122+
## LINK
123+
CHATGPT_IMPORT_MANUAL_LINK_1 = 'https://cdn.discordapp.com/attachments/1089739277379846226/1259834113884557362/image.png?ex=66a6d4b3&is=66a58333&hm=3544e9a6ec1610bc552f93b794e113c48c1505d5ba820628b9cd68876597f7dc&'
124+
CHATGPT_IMPORT_MANUAL_LINK_2 = 'https://cdn.discordapp.com/attachments/1089739277379846226/1265952420773498880/image.png?ex=66a6ad51&is=66a55bd1&hm=0279112be31354eb1a45f1d72d28363285dd6b640854b6dc98e58de98f4fc349&'
125+
126+
## PROMPT
127+
PROMPT_BEGINNING_KEY_NAME = 'prompt_beginning'
128+
PROMPT_JSON_KEY_NAME = 'prompt_json'
129+
PROMPT_MAIN_KEY_NAME = 'prompt_main'
130+
PROMPT_END_KEY_NAME = 'prompt_ending'
131+
PROMPT_NAME_REGEX = '^[a-zA-Z_0-9]+$'
132+
INDENT_SIZE = 4
133+
134+
# DB
135+
DB_NAME_REGEX = '[a-zA-Z0-9]{1,20}'
136+
137+
THREAD_TABLE_NAME_OLD = 'conv_tb'
138+
THREAD_TRIGGER_NAME_OLD = 'conv_tr'
139+
MESSAGE_TABLE_NAME_OLD = 'conv_unit_tb'
140+
141+
THREAD_TABLE_NAME = 'thread_tb'
142+
THREAD_TRIGGER_NAME = 'thread_tr'
143+
MESSAGE_TABLE_NAME = 'message_tb'
144+
145+
IMAGE_TABLE_NAME = 'image_tb'
146+
147+
THREAD_MESSAGE_INSERTED_TR_NAME_OLD = 'conv_tb_updated_by_unit_inserted_tr'
148+
THREAD_MESSAGE_UPDATED_TR_NAME_OLD = 'conv_tb_updated_by_unit_updated_tr'
149+
THREAD_MESSAGE_DELETED_TR_NAME_OLD = 'conv_tb_updated_by_unit_deleted_tr'
150+
151+
THREAD_MESSAGE_INSERTED_TR_NAME = 'thread_message_inserted_tr'
152+
THREAD_MESSAGE_UPDATED_TR_NAME = 'thread_message_updated_tr'
153+
THREAD_MESSAGE_DELETED_TR_NAME = 'thread_message_deleted_tr'
154+
155+
THREAD_ORDERBY = 'update_dt'
156+
157+
PROPERTY_PROMPT_GROUP_TABLE_NAME_OLD = 'prop_prompt_grp_tb'
158+
PROPERTY_PROMPT_UNIT_TABLE_NAME_OLD = 'prop_prompt_unit_tb'
159+
TEMPLATE_PROMPT_GROUP_TABLE_NAME_OLD = 'template_prompt_grp_tb'
160+
TEMPLATE_PROMPT_TABLE_NAME_OLD = 'template_prompt_tb'
161+
PROPERTY_PROMPT_UNIT_DEFAULT_VALUE = [{'name': 'Task', 'content': ''},
162+
{'name': 'Topic', 'content': ''},
163+
{'name': 'Style', 'content': ''},
164+
{'name': 'Tone', 'content': ''},
165+
{'name': 'Audience', 'content': ''},
166+
{'name': 'Length', 'content': ''},
167+
{'name': 'Form', 'content': ''}]
168+
169+
PROMPT_GROUP_TABLE_NAME = 'prompt_group_tb'
170+
PROMPT_ENTRY_TABLE_NAME = 'prompt_entry_tb'
171+
172+
# DEFAULT JSON FILENAME FOR PROMPT
173+
AWESOME_CHATGPT_PROMPTS_FILENAME = 'prompt_res/awesome_chatgpt_prompts.json'
174+
ALEX_BROGAN_PROMPT_FILENAME = 'prompt_res/alex_brogan.json'
175+
176+
FORM_PROMPT_GROUP_SAMPLE = json.dumps([
177+
{
178+
"name": 'Default',
179+
"data": PROPERTY_PROMPT_UNIT_DEFAULT_VALUE
180+
}
181+
], indent=4)
182+
183+
SENTENCE_PROMPT_GROUP_SAMPLE = '''[
184+
{
185+
"name": "alex_brogan",
186+
"data": [
187+
{
188+
"name": "sample_1",
189+
"content": "Identify the 20% of [topic or skill] that will yield 80% of the desired results and provide a focused learning plan to master it."
190+
},
191+
{
192+
"name": "sample_2",
193+
"content": "Explain [topic or skill] in the simplest terms possible as if teaching it to a complete beginner. Identify gaps in my understanding and suggest resources to fill them."
194+
}
195+
]
196+
},
197+
{
198+
"name": "awesome_chatGPT_prompts",
199+
"data": [
200+
{
201+
"name": "linux_terminal",
202+
"content": "I want you to act as a linux terminal. I will type commands and you will reply with what the terminal should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. do not write explanations. do not type commands unless I instruct you to do so. when i need to tell you something in english, i will do so by putting text inside curly brackets {like this}. my first command is pwd"
203+
},
204+
{
205+
"name": "english_translator_and_improver",
206+
"content": "I want you to act as an English translator, spelling corrector and improver. I will speak to you in any language and you will detect the language, translate it and answer in the corrected and improved version of my text, in English. I want you to replace my simplified A0-level words and sentences with more beautiful and elegant, upper level English words and sentences. Keep the meaning same, but make them more literary. I want you to only reply the correction, the improvements and nothing else, do not write explanations. My first sentence is \"istanbulu cok seviyom burada olmak cok guzel\""
207+
},
208+
]
209+
}
210+
]'''
211+
212+
# Load the default prompt
213+
if os.path.exists(AWESOME_CHATGPT_PROMPTS_FILENAME):
214+
AWESOME_CHATGPT_PROMPTS = json.load(open(AWESOME_CHATGPT_PROMPTS_FILENAME))[0]
215+
if os.path.exists(ALEX_BROGAN_PROMPT_FILENAME):
216+
ALEX_BROGAN_PROMPT = json.load(open(ALEX_BROGAN_PROMPT_FILENAME))[0]
217+
218+
# Update the __all__ list with the PEP8 standard dunder names
219+
__all__ = ['__version__',
220+
'__author__']
221+
222+
# Update the __all__ list with the constants
223+
__all__.extend([name for name, value in globals().items() if name.isupper()])

pyqt_openai/aboutDialog.py

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,13 @@
11
import datetime
2+
import pyqt_openai
23

3-
from qtpy.QtCore import Qt, QUrl
4-
from qtpy.QtGui import QPixmap, QDesktopServices
4+
from qtpy.QtCore import Qt
5+
from qtpy.QtGui import QPixmap
56
from qtpy.QtWidgets import QDialog, QPushButton, QHBoxLayout, QWidget, QVBoxLayout, QLabel
67

7-
from pyqt_openai.res.language_dict import LangClass
8-
from pyqt_openai.widgets.svgLabel import SvgLabel
9-
from pyqt_openai.util.script import get_version
10-
11-
12-
class ClickableLabel(SvgLabel):
13-
def __init__(self):
14-
super().__init__()
15-
self.__url = '127.0.0.1'
16-
17-
def setUrl(self, url):
18-
self.__url = url
19-
20-
def mouseReleaseEvent(self, QMouseEvent):
21-
if QMouseEvent.button() == Qt.MouseButtons.LeftButton:
22-
QDesktopServices.openUrl(QUrl(self.__url))
8+
from pyqt_openai import APP_ICON, LICENSE_URL, GITHUB_URL, DISCORD_URL, APP_NAME, CONTACT
9+
from pyqt_openai.lang.translations import LangClass
10+
from pyqt_openai.widgets.linkLabel import LinkLabel
2311

2412

2513
class AboutDialog(QDialog):
@@ -34,40 +22,39 @@ def __initUi(self):
3422
self.__okBtn = QPushButton(LangClass.TRANSLATIONS['OK'])
3523
self.__okBtn.clicked.connect(self.accept)
3624

37-
p = QPixmap('pyqtopenai.png')
25+
p = QPixmap(APP_ICON)
3826
logoLbl = QLabel()
3927
logoLbl.setPixmap(p)
4028

4129
descWidget1 = QLabel()
4230
descWidget1.setText(f'''
43-
<h1>pyqt-openai</h1>
44-
Software Version {get_version()}<br/><br/>
31+
<h1>{APP_NAME}</h1>
32+
Software Version {pyqt_openai.__version__}<br/><br/>
4533
© 2023 {datetime.datetime.now().year}. Used under the MIT License.<br/>
4634
Copyright (c) {datetime.datetime.now().year} yjg30737<br/>
4735
''')
4836

49-
descWidget2 = ClickableLabel()
50-
descWidget2.setText('Read MIT License Full Text')
51-
descWidget2.setUrl('https://github.com/yjg30737/pyqt-openai/blob/main/LICENSE')
52-
descWidget2.setStyleSheet('QLabel:hover { color: blue }')
37+
descWidget2 = LinkLabel()
38+
descWidget2.setText(LangClass.TRANSLATIONS['Read MIT License Full Text'])
39+
descWidget2.setUrl(LICENSE_URL)
5340

5441
descWidget3 = QLabel()
5542
descWidget3.setText(f'''
56-
<br/><br/>Contact: [email protected]<br/>
57-
<p>{LangClass.TRANSLATIONS['Powered by qtpy']}</p>
43+
<br/><br/>Contact: {CONTACT}<br/>
44+
<p>Powered by qtpy</p>
5845
''')
5946

6047
descWidget1.setAlignment(Qt.AlignmentFlag.AlignTop)
6148
descWidget2.setAlignment(Qt.AlignmentFlag.AlignTop)
6249
descWidget3.setAlignment(Qt.AlignmentFlag.AlignTop)
6350

64-
self.__githubLbl = ClickableLabel()
65-
self.__githubLbl.setSvgFile('ico/github.svg')
66-
self.__githubLbl.setUrl('https://github.com/yjg30737/pyqt-openai')
51+
self.__githubLbl = LinkLabel()
52+
self.__githubLbl.setSvgFile(pyqt_openai.ICON_GITHUB)
53+
self.__githubLbl.setUrl(GITHUB_URL)
6754

68-
self.__discordLbl = ClickableLabel()
69-
self.__discordLbl.setSvgFile('ico/discord.svg')
70-
self.__discordLbl.setUrl('https://discord.gg/cHekprskVE')
55+
self.__discordLbl = LinkLabel()
56+
self.__discordLbl.setSvgFile(pyqt_openai.ICON_DISCORD)
57+
self.__discordLbl.setUrl(DISCORD_URL)
7158
self.__discordLbl.setFixedSize(22, 19)
7259

7360
lay = QHBoxLayout()

0 commit comments

Comments
 (0)