From e0ca5ab613b04924cd11ac55e76e78b4b8f74a5c Mon Sep 17 00:00:00 2001 From: crennis Date: Wed, 3 May 2023 11:29:44 +0200 Subject: [PATCH] Tested some stuff --- .gitignore | 3 + gui/Window.ui | 200 +++++++++++++++++++++++++++++++++ gui/apikey.py | 43 ++++++++ gui/apikey.ui | 81 ++++++++++++++ gui/connection.py | 77 +++++++++++++ gui/connection.ui | 208 +++++++++++++++++++++++++++++++++++ gui/connectionui.py | 6 + gui/main.py | 34 ++++++ gui/mainWindow.py | 96 ++++++++++++++++ nogui/database/postgresql.py | 90 +++++++++++++++ nogui/noguialpha.py | 170 ++++++++++++++++++++++++++++ 11 files changed, 1008 insertions(+) create mode 100644 gui/Window.ui create mode 100644 gui/apikey.py create mode 100644 gui/apikey.ui create mode 100644 gui/connection.py create mode 100644 gui/connection.ui create mode 100644 gui/connectionui.py create mode 100644 gui/main.py create mode 100644 gui/mainWindow.py create mode 100644 nogui/database/postgresql.py create mode 100644 nogui/noguialpha.py diff --git a/.gitignore b/.gitignore index e304199..763ffd3 100644 --- a/.gitignore +++ b/.gitignore @@ -239,3 +239,6 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +.idea/ + +apikey \ No newline at end of file diff --git a/gui/Window.ui b/gui/Window.ui new file mode 100644 index 0000000..07c04a5 --- /dev/null +++ b/gui/Window.ui @@ -0,0 +1,200 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 20 + 30 + 661 + 21 + + + + + + + 20 + 10 + 71 + 16 + + + + Write Text + + + + + + 20 + 60 + 121 + 16 + + + + SQL Statement: + + + + + + 20 + 80 + 661 + 21 + + + + + + + 690 + 30 + 91 + 24 + + + + Convert to SQL + + + + + + 20 + 150 + 661 + 21 + + + + + + + 20 + 126 + 91 + 20 + + + + SQL Shell + + + + + + 690 + 150 + 91 + 24 + + + + Execute + + + + + + 690 + 80 + 91 + 24 + + + + Paste to Shell + + + + + + 20 + 180 + 661 + 16 + + + + outputLabel + + + + + + 20 + 240 + 761 + 311 + + + + + + + 20 + 220 + 49 + 16 + + + + Output + + + + + + + 0 + 0 + 800 + 22 + + + + + Settings + + + + + + + + + + + Connect DB + + + + + Connect API Key + + + + + Exit + + + + + + diff --git a/gui/apikey.py b/gui/apikey.py new file mode 100644 index 0000000..928bbfd --- /dev/null +++ b/gui/apikey.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'apikey.ui' +# +# Created by: PyQt5 UI code generator 5.15.9 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(265, 91) + self.label = QtWidgets.QLabel(Form) + self.label.setGeometry(QtCore.QRect(20, 10, 91, 16)) + self.label.setObjectName("label") + self.lineEdit = QtWidgets.QLineEdit(Form) + self.lineEdit.setGeometry(QtCore.QRect(110, 10, 141, 21)) + self.lineEdit.setObjectName("lineEdit") + self.pushButton = QtWidgets.QPushButton(Form) + self.pushButton.setGeometry(QtCore.QRect(14, 40, 111, 24)) + self.pushButton.setObjectName("pushButton") + self.pushButton_2 = QtWidgets.QPushButton(Form) + self.pushButton_2.setGeometry(QtCore.QRect(134, 40, 121, 24)) + self.pushButton_2.setObjectName("pushButton_2") + self.label_2 = QtWidgets.QLabel(Form) + self.label_2.setGeometry(QtCore.QRect(20, 70, 231, 16)) + self.label_2.setObjectName("label_2") + + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.label.setText(_translate("Form", "OpenAI API-Key")) + self.pushButton.setText(_translate("Form", "Test Key")) + self.pushButton_2.setText(_translate("Form", "Save")) + self.label_2.setText(_translate("Form", "Key working...")) diff --git a/gui/apikey.ui b/gui/apikey.ui new file mode 100644 index 0000000..3fe0831 --- /dev/null +++ b/gui/apikey.ui @@ -0,0 +1,81 @@ + + + Form + + + + 0 + 0 + 265 + 91 + + + + Form + + + + + 20 + 10 + 91 + 16 + + + + OpenAI API-Key + + + + + + 110 + 10 + 141 + 21 + + + + + + + 14 + 40 + 111 + 24 + + + + Test Key + + + + + + 134 + 40 + 121 + 24 + + + + Save + + + + + + 20 + 70 + 231 + 16 + + + + Key working... + + + + + + diff --git a/gui/connection.py b/gui/connection.py new file mode 100644 index 0000000..83c6358 --- /dev/null +++ b/gui/connection.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '.\connection.ui' +# +# Created by: PyQt5 UI code generator 5.15.9 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName("Form") + Form.resize(249, 217) + self.label = QtWidgets.QLabel(Form) + self.label.setGeometry(QtCore.QRect(20, 10, 101, 16)) + self.label.setObjectName("label") + self.label_2 = QtWidgets.QLabel(Form) + self.label_2.setGeometry(QtCore.QRect(20, 40, 49, 16)) + self.label_2.setObjectName("label_2") + self.label_3 = QtWidgets.QLabel(Form) + self.label_3.setGeometry(QtCore.QRect(20, 70, 61, 16)) + self.label_3.setObjectName("label_3") + self.label_4 = QtWidgets.QLabel(Form) + self.label_4.setGeometry(QtCore.QRect(20, 100, 81, 16)) + self.label_4.setObjectName("label_4") + self.label_5 = QtWidgets.QLabel(Form) + self.label_5.setGeometry(QtCore.QRect(20, 130, 61, 16)) + self.label_5.setObjectName("label_5") + self.IP = QtWidgets.QLineEdit(Form) + self.IP.setGeometry(QtCore.QRect(100, 10, 131, 21)) + self.IP.setText("") + self.IP.setObjectName("IP") + self.port = QtWidgets.QLineEdit(Form) + self.port.setGeometry(QtCore.QRect(100, 40, 131, 21)) + self.port.setText("") + self.port.setObjectName("port") + self.username = QtWidgets.QLineEdit(Form) + self.username.setGeometry(QtCore.QRect(100, 70, 131, 21)) + self.username.setText("") + self.username.setObjectName("username") + self.password = QtWidgets.QLineEdit(Form) + self.password.setGeometry(QtCore.QRect(100, 100, 131, 21)) + self.password.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhSensitiveData) + self.password.setObjectName("password") + self.database = QtWidgets.QLineEdit(Form) + self.database.setGeometry(QtCore.QRect(100, 130, 131, 21)) + self.database.setObjectName("database") + self.TestConnection = QtWidgets.QPushButton(Form) + self.TestConnection.setEnabled(False) + self.TestConnection.setGeometry(QtCore.QRect(14, 160, 101, 24)) + self.TestConnection.setObjectName("TestConnection") + self.saveButton = QtWidgets.QPushButton(Form) + self.saveButton.setEnabled(False) + self.saveButton.setGeometry(QtCore.QRect(130, 160, 101, 24)) + self.saveButton.setObjectName("saveButton") + self.returnLabel = QtWidgets.QLabel(Form) + self.returnLabel.setGeometry(QtCore.QRect(20, 190, 211, 16)) + self.returnLabel.setObjectName("returnLabel") + + self.retranslateUi(Form) + QtCore.QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + _translate = QtCore.QCoreApplication.translate + Form.setWindowTitle(_translate("Form", "Form")) + self.label.setText(_translate("Form", "IP")) + self.label_2.setText(_translate("Form", "Port")) + self.label_3.setText(_translate("Form", "Username")) + self.label_4.setText(_translate("Form", "Password")) + self.label_5.setText(_translate("Form", "Database")) + self.TestConnection.setText(_translate("Form", "Test Connection")) + self.saveButton.setText(_translate("Form", "Save")) + self.returnLabel.setText(_translate("Form", "Connection ... / Saved...")) diff --git a/gui/connection.ui b/gui/connection.ui new file mode 100644 index 0000000..8d32d5e --- /dev/null +++ b/gui/connection.ui @@ -0,0 +1,208 @@ + + + Form + + + + 0 + 0 + 249 + 217 + + + + Form + + + + + 20 + 10 + 101 + 16 + + + + IP + + + + + + 20 + 40 + 49 + 16 + + + + Port + + + + + + 20 + 70 + 61 + 16 + + + + Username + + + + + + 20 + 100 + 81 + 16 + + + + Password + + + + + + 20 + 130 + 61 + 16 + + + + Database + + + + + + 100 + 10 + 131 + 21 + + + + + + + + + + 100 + 40 + 131 + 21 + + + + + + + + + + 100 + 70 + 131 + 21 + + + + + + + + + + 100 + 100 + 131 + 21 + + + + Qt::ImhHiddenText|Qt::ImhSensitiveData + + + + + + 100 + 130 + 131 + 21 + + + + + + false + + + + 14 + 160 + 101 + 24 + + + + Test Connection + + + + + false + + + + 130 + 160 + 101 + 24 + + + + Save + + + + + + 20 + 190 + 211 + 16 + + + + Connection ... / Saved... + + + + + + + IP + textChanged(QString) + saveButton + customSlot() + + + 171 + 25 + + + 199 + 170 + + + + + diff --git a/gui/connectionui.py b/gui/connectionui.py new file mode 100644 index 0000000..758fd81 --- /dev/null +++ b/gui/connectionui.py @@ -0,0 +1,6 @@ +from PyQt5 import QtCore, QtGui, QtWidgets + +class UiConnect(QtWidgets): + def __init__(self): + self.setupUi(self) + diff --git a/gui/main.py b/gui/main.py new file mode 100644 index 0000000..6c94e47 --- /dev/null +++ b/gui/main.py @@ -0,0 +1,34 @@ +import sys +from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog +from mainWindow import Ui_MainWindow +from connection import Ui_Form + +class MainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + self.ui.actionConnect_DB.triggered.connect(self.open_connection) + + def open_connection(self): + self.connection_window = ConnectionWindow(self) + self.connection_window.show() + +class ConnectionWindow(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.ui = Ui_Form() + self.ui.setupUi(self) + self.ui.saveButton.setEnabled(False) + + def customSlot(self, text): + if self.ui.IP.text(): + self.ui.saveButton.setEnabled(True) + else: + self.ui.saveButton.setEnabled(False) + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = MainWindow() + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/gui/mainWindow.py b/gui/mainWindow.py new file mode 100644 index 0000000..f28e204 --- /dev/null +++ b/gui/mainWindow.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '.\Window.ui' +# +# Created by: PyQt5 UI code generator 5.15.9 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(800, 600) + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.textInput = QtWidgets.QLineEdit(self.centralwidget) + self.textInput.setGeometry(QtCore.QRect(20, 30, 661, 21)) + self.textInput.setObjectName("textInput") + self.textLabel = QtWidgets.QLabel(self.centralwidget) + self.textLabel.setGeometry(QtCore.QRect(20, 10, 71, 16)) + self.textLabel.setObjectName("textLabel") + self.statementLabel = QtWidgets.QLabel(self.centralwidget) + self.statementLabel.setGeometry(QtCore.QRect(20, 60, 121, 16)) + self.statementLabel.setObjectName("statementLabel") + self.statementInput = QtWidgets.QLineEdit(self.centralwidget) + self.statementInput.setGeometry(QtCore.QRect(20, 80, 661, 21)) + self.statementInput.setObjectName("statementInput") + self.convertButton = QtWidgets.QPushButton(self.centralwidget) + self.convertButton.setGeometry(QtCore.QRect(690, 30, 91, 24)) + self.convertButton.setObjectName("convertButton") + self.shellInput = QtWidgets.QLineEdit(self.centralwidget) + self.shellInput.setGeometry(QtCore.QRect(20, 150, 661, 21)) + self.shellInput.setObjectName("shellInput") + self.shellLabel = QtWidgets.QLabel(self.centralwidget) + self.shellLabel.setGeometry(QtCore.QRect(20, 130, 101, 16)) + self.shellLabel.setObjectName("shellLabel") + self.executeButton = QtWidgets.QPushButton(self.centralwidget) + self.executeButton.setGeometry(QtCore.QRect(690, 150, 91, 24)) + self.executeButton.setObjectName("executeButton") + self.pasteButton = QtWidgets.QPushButton(self.centralwidget) + self.pasteButton.setGeometry(QtCore.QRect(690, 80, 91, 24)) + self.pasteButton.setObjectName("pasteButton") + self.outputLabel = QtWidgets.QLabel(self.centralwidget) + self.outputLabel.setGeometry(QtCore.QRect(20, 180, 661, 16)) + self.outputLabel.setObjectName("outputLabel") + self.outputTable = QtWidgets.QTableWidget(self.centralwidget) + self.outputTable.setGeometry(QtCore.QRect(20, 240, 761, 311)) + self.outputTable.setObjectName("outputTable") + self.outputTable.setColumnCount(0) + self.outputTable.setRowCount(0) + self.outputTableLabel = QtWidgets.QLabel(self.centralwidget) + self.outputTableLabel.setGeometry(QtCore.QRect(20, 220, 49, 16)) + self.outputTableLabel.setObjectName("outputTableLabel") + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22)) + self.menubar.setObjectName("menubar") + self.menuSettings = QtWidgets.QMenu(self.menubar) + self.menuSettings.setObjectName("menuSettings") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.actionConnect_DB = QtWidgets.QAction(MainWindow) + self.actionConnect_DB.setObjectName("actionConnect_DB") + self.actionConnect_API_Key = QtWidgets.QAction(MainWindow) + self.actionConnect_API_Key.setObjectName("actionConnect_API_Key") + self.actionExit = QtWidgets.QAction(MainWindow) + self.actionExit.setObjectName("actionExit") + self.menuSettings.addAction(self.actionConnect_DB) + self.menuSettings.addAction(self.actionConnect_API_Key) + self.menuSettings.addAction(self.actionExit) + self.menubar.addAction(self.menuSettings.menuAction()) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + self.textLabel.setText(_translate("MainWindow", "Write Text")) + self.statementLabel.setText(_translate("MainWindow", "SQL Statement:")) + self.convertButton.setText(_translate("MainWindow", "Convert to SQL")) + self.shellLabel.setText(_translate("MainWindow", "SQL Shell")) + self.executeButton.setText(_translate("MainWindow", "Execute")) + self.pasteButton.setText(_translate("MainWindow", "Paste to Shell")) + self.outputLabel.setText(_translate("MainWindow", "oputputLabel")) + self.outputTableLabel.setText(_translate("MainWindow", "Output")) + self.menuSettings.setTitle(_translate("MainWindow", "Settings")) + self.actionConnect_DB.setText(_translate("MainWindow", "Connect DB")) + self.actionConnect_API_Key.setText(_translate("MainWindow", "Connect API Key")) + self.actionExit.setText(_translate("MainWindow", "Exit")) diff --git a/nogui/database/postgresql.py b/nogui/database/postgresql.py new file mode 100644 index 0000000..a03a601 --- /dev/null +++ b/nogui/database/postgresql.py @@ -0,0 +1,90 @@ +import psycopg2 + +class Postgres: + def __init__(self): + self.db_ip = 'localhost' + self.db_port = '32771' + self.db_username = 'root' + self.db_password = '' + self.db_name = '' + + def config(self, ip, port, username, password, name): + self.db_ip = ip + self.db_port = port + self.db_username = username + self.db_password = password + self.db_name = name + + def fetchall(self, query): + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute(query) + result = cur.fetchall() + cur.close() + conn.close() + return result + + def fetchone(self, query): + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute(query) + result = cur.fetchone() + cur.close() + conn.close() + return result + + def fetchmany(self, query, size): + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute(query) + result = cur.fetchmany(size) + cur.close() + conn.close() + return result + + def execute(self, query): + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute(query) + conn.commit() + cur.close() + conn.close() + + def executemany(self, query, values): + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.executemany(query, values) + conn.commit() + cur.close() + conn.close() + diff --git a/nogui/noguialpha.py b/nogui/noguialpha.py new file mode 100644 index 0000000..88e044b --- /dev/null +++ b/nogui/noguialpha.py @@ -0,0 +1,170 @@ +from getpass import getpass +import openai +import psycopg2 +import database.postgresql as postgresql + +class MainScript: + def __init__(self): + # Set DB server Configs + + self.db_ip = 'localhost' + self.db_port = '32771' + self.db_username = 'root' + self.db_password = '' + self.db_name = '' + + # Set Logs + self.logs = [{'role': 'system', 'content': 'You convert human language to sql statements. Do not add additional information to the statement. The answer should only contain a valid sql statement.'}] + + # Set OpenAI API Key + openai.api_key = open('apikey', 'r').read().strip('\n') + + def dbconfig(self): + print('Welcome to the Configuration Assistant') + + self.db_ip = input(f'Enter the IP of the DB Server (current: {self.db_ip}): ') or self.db_ip + self.db_port = input(f'Enter the Port of the DB Server (current: {self.db_port}): ') or self.db_port + self.db_username = input(f'Enter the Username of the DB Server (current: {self.db_username}): ') or self.db_username + self.db_password = input(f'Enter the Password of the DB Server (current: ***): ') or self.db_password + self.db_name = input(f'Enter the Name of the Database (current: {self.db_name}): ') or self.db_name + + # Test Connection + try: + conn = psycopg2.connect( + host=self.db_ip, + port=self.db_port, + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute('SELECT VERSION()') + print(cur.fetchone()) + cur.close() + conn.close() + print('Connection Successful') + except Exception as e: + print('Connection Failed') + print(e) + print('\nDo you want to check the configuration and retry?') + print('1. Yes') + print('2. No') + option = input('Enter your option: ') + if option == '1': + self.dbconfig() + elif option == '2': + print('Not Configuring DB Server') + else: + print('Invalid Option, Not Configuring DB Server') + + + + def humantosql(self, prompt) -> str: + print('Convert Human Language to SQL') + prompt = {"role": "user", "content": prompt} + + self.logs.append(prompt) + + response = openai.ChatCompletion.create( + model = "gpt-4", + messages = self.logs + ) + self.logs.append({"role": "assistant", "content": response['choices'][0]['message']['content']}) + return response['choices'][0]['message']['content'] + + def runsql(self, sql: str) -> None: + print('Run SQL') + print('SQL: ' + sql) + try: + conn = psycopg2.connect( + host=self.db_ip, + port=int(self.db_port), + user=self.db_username, + password=self.db_password, + database=self.db_name + ) + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print('SQL Executed Successfully') + except Exception as e: + print('SQL Execution Failed') + print(e) + print('\nDo you want to check the configuration and retry?') + print('1. Yes') + print('2. No') + option = input('Enter your option: ') + if option == '1': + self.dbconfig() + self.runsql(sql) + elif option == '2': + print('Not Executing SQL') + else: + print('Invalid Option, Not Executing SQL') + + +if __name__ == '__main__': + main = MainScript() + while True: + + print('\n\n\nWelcome to the NoGUI version of the SQL Assistant') + print('Please select an option from the list below') + print('1. Configure the DB Server') + print('2. Convert Human Language to SQL') + print('3. Run SQL') + print('4. Exit') + + + option = input('Enter your option: ') + if option == '1': + main.dbconfig() + elif option == '2': + prompt = input('Enter your prompt: ') + sql = main.humantosql(prompt) + print(sql) + + print('Do you want to execute the SQL?') + print('1. Yes') + print('2. No') + print('3. Edit Statement') + option = input('Enter your option: ') + if option == '1': + print('Executing SQL') + main.runsql(sql) + elif option == '2': + print('Not Executing SQL') + elif option == '3': + retry = True + while retry: + print('Editing Statement') + prompt = input('What needs Change?: ') + sql = main.humantosql(prompt) + print(sql) + print('Do you want to execute the SQL?') + print('1. Yes') + print('2. No') + print('3. Edit Statement') + option = input('Enter your option: ') + if option == '1': + print('Executing SQL') + main.runsql(sql) + retry = False + elif option == '2': + print('Not Executing SQL') + retry = False + elif option == '3': + retry = True + + + elif option == '3': + sql = input('Enter your SQL: ') + main.runsql(sql) + + elif option == '4': + print('Exiting') + exit() + else: + print('Invalid Option, Please try again') +