Compare commits

..

5 Commits

Author SHA1 Message Date
crennis
9afa8bec49 Made Connection GUI working. Crashes when testing, will fix 2023-05-04 16:34:34 +02:00
crennis
d62abec3b8 Made GUIs accesible, currently only saving and testing the API key is working. Nothing else. 2023-05-04 15:56:48 +02:00
crennis
b1100e8338 Added Modules to Gui 2023-05-04 15:55:42 +02:00
crennis
5cf1dd708a Updated gitignore 2023-05-04 15:55:04 +02:00
crennis
e0e5116006 Updated Uis 2023-05-04 15:51:52 +02:00
15 changed files with 655 additions and 264 deletions

1
.gitignore vendored
View File

@ -242,3 +242,4 @@ fabric.properties
.idea/
apikey
config.json

View File

@ -1,43 +0,0 @@
# -*- 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..."))

View File

@ -0,0 +1,13 @@
{
"database":
{
"dbtype": "PostgreSQL",
"ip": "localhost",
"password": "password",
"user": "admin",
"port": "5432",
"database": "PostgreSQL"
},
"apikey": "sk-abc***"
}

View File

@ -1,77 +0,0 @@
# -*- 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..."))

View File

@ -1,6 +0,0 @@
from PyQt5 import QtCore, QtGui, QtWidgets
class UiConnect(QtWidgets):
def __init__(self):
self.setupUi(self)

View File

@ -0,0 +1,85 @@
import psycopg2
import os
class Postgres:
def __init__(self, ip, port, username, password, database):
self.db_ip = ip
self.db_port = port
self.db_username = username
self.db_password = password
self.db_name = database
self.conn = psycopg2.connect(
host=self.db_ip,
port=self.db_port,
user=self.db_username,
password=self.db_password,
database=self.db_name
)
self.tables = []
self.tableschema = {}
self.get_schema()
def __str__(self):
return f'PostgreSQL Server: {self.db_ip}:{self.db_port} as {self.db_username} on database {self.db_name}'
def get_schema(self) -> dict:
fetch = self.fetchall("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';")
for item in fetch:
self.tables.append(item[0])
for table in self.tables:
fetch = self.fetchall(f"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = '{table}';")
self.tableschema.update({table: fetch})
return self.tableschema
def fetchall(self, query: str):
cur = self.conn.cursor()
cur.execute(query)
result = cur.fetchall()
cur.close()
return result
def fetchone(self, query: str):
cur = self.conn.cursor()
cur.execute(query)
result = cur.fetchone()
cur.close()
return result
def fetchmany(self, query: str, size: int):
cur = self.conn.cursor()
cur.execute(query)
result = cur.fetchmany(size)
cur.close()
return result
def execute(self, query: str):
cur = self.conn.cursor()
cur.execute(query)
self.conn.commit()
cur.close()
def executemany(self, query: str, values):
cur = self.conn.cursor()
cur.executemany(query, values)
self.conn.commit()
cur.close()
def test_connection(self) -> bool:
try:
self.conn = psycopg2.connect(
host=self.db_ip,
port=self.db_port,
user=self.db_username,
password=self.db_password,
database=self.db_name
)
return True
except:
return False
def close(self):
self.conn.close()

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '.\Window.ui'
# Form implementation generated from reading ui file 'Window.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
@ -14,11 +14,11 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
MainWindow.resize(796, 591)
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.setGeometry(QtCore.QRect(20, 30, 650, 21))
self.textInput.setObjectName("textInput")
self.textLabel = QtWidgets.QLabel(self.centralwidget)
self.textLabel.setGeometry(QtCore.QRect(20, 10, 71, 16))
@ -26,38 +26,42 @@ class Ui_MainWindow(object):
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.setGeometry(QtCore.QRect(680, 30, 100, 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.setGeometry(QtCore.QRect(410, 60, 91, 20))
self.shellLabel.setObjectName("shellLabel")
self.executeButton = QtWidgets.QPushButton(self.centralwidget)
self.executeButton.setGeometry(QtCore.QRect(690, 150, 91, 24))
self.executeButton.setGeometry(QtCore.QRect(680, 200, 100, 24))
self.executeButton.setObjectName("executeButton")
self.pasteButton = QtWidgets.QPushButton(self.centralwidget)
self.pasteButton.setGeometry(QtCore.QRect(690, 80, 91, 24))
self.pasteButton.setGeometry(QtCore.QRect(300, 200, 100, 24))
self.pasteButton.setObjectName("pasteButton")
self.outputLabel = QtWidgets.QLabel(self.centralwidget)
self.outputLabel.setGeometry(QtCore.QRect(20, 180, 661, 16))
self.outputLabel.setGeometry(QtCore.QRect(20, 230, 761, 16))
self.outputLabel.setObjectName("outputLabel")
self.outputTable = QtWidgets.QTableWidget(self.centralwidget)
self.outputTable.setGeometry(QtCore.QRect(20, 240, 761, 311))
self.outputTable.setGeometry(QtCore.QRect(20, 270, 761, 281))
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.setGeometry(QtCore.QRect(20, 250, 49, 16))
self.outputTableLabel.setObjectName("outputTableLabel")
self.shellInput = QtWidgets.QTextEdit(self.centralwidget)
self.shellInput.setGeometry(QtCore.QRect(410, 80, 375, 111))
self.shellInput.setObjectName("shellInput")
self.statementOutput = QtWidgets.QTextEdit(self.centralwidget)
self.statementOutput.setEnabled(True)
self.statementOutput.setGeometry(QtCore.QRect(20, 80, 375, 111))
self.statementOutput.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.statementOutput.setFrameShadow(QtWidgets.QFrame.Sunken)
self.statementOutput.setTextInteractionFlags(QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse)
self.statementOutput.setObjectName("statementOutput")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setGeometry(QtCore.QRect(0, 0, 796, 26))
self.menubar.setObjectName("menubar")
self.menuSettings = QtWidgets.QMenu(self.menubar)
self.menuSettings.setObjectName("menuSettings")
@ -88,8 +92,13 @@ class Ui_MainWindow(object):
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.outputLabel.setText(_translate("MainWindow", "outputLabel"))
self.outputTableLabel.setText(_translate("MainWindow", "Output"))
self.statementOutput.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7.8pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.menuSettings.setTitle(_translate("MainWindow", "Settings"))
self.actionConnect_DB.setText(_translate("MainWindow", "Connect DB"))
self.actionConnect_API_Key.setText(_translate("MainWindow", "Connect API Key"))

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
<width>796</width>
<height>591</height>
</rect>
</property>
<property name="windowTitle">
@ -19,7 +19,7 @@
<rect>
<x>20</x>
<y>30</y>
<width>661</width>
<width>650</width>
<height>21</height>
</rect>
</property>
@ -50,22 +50,12 @@
<string>SQL Statement:</string>
</property>
</widget>
<widget class="QLineEdit" name="statementInput">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>661</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="convertButton">
<property name="geometry">
<rect>
<x>690</x>
<x>680</x>
<y>30</y>
<width>91</width>
<width>100</width>
<height>24</height>
</rect>
</property>
@ -73,21 +63,11 @@
<string>Convert to SQL</string>
</property>
</widget>
<widget class="QLineEdit" name="shellInput">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>661</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="shellLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>126</y>
<x>410</x>
<y>60</y>
<width>91</width>
<height>20</height>
</rect>
@ -99,9 +79,9 @@
<widget class="QPushButton" name="executeButton">
<property name="geometry">
<rect>
<x>690</x>
<y>150</y>
<width>91</width>
<x>680</x>
<y>200</y>
<width>100</width>
<height>24</height>
</rect>
</property>
@ -112,9 +92,9 @@
<widget class="QPushButton" name="pasteButton">
<property name="geometry">
<rect>
<x>690</x>
<y>80</y>
<width>91</width>
<x>300</x>
<y>200</y>
<width>100</width>
<height>24</height>
</rect>
</property>
@ -126,8 +106,8 @@
<property name="geometry">
<rect>
<x>20</x>
<y>180</y>
<width>661</width>
<y>230</y>
<width>761</width>
<height>16</height>
</rect>
</property>
@ -139,9 +119,9 @@
<property name="geometry">
<rect>
<x>20</x>
<y>240</y>
<y>270</y>
<width>761</width>
<height>311</height>
<height>281</height>
</rect>
</property>
</widget>
@ -149,7 +129,7 @@
<property name="geometry">
<rect>
<x>20</x>
<y>220</y>
<y>250</y>
<width>49</width>
<height>16</height>
</rect>
@ -158,14 +138,53 @@
<string>Output</string>
</property>
</widget>
<widget class="QTextEdit" name="shellInput">
<property name="geometry">
<rect>
<x>410</x>
<y>80</y>
<width>375</width>
<height>111</height>
</rect>
</property>
</widget>
<widget class="QTextEdit" name="statementOutput">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>375</width>
<height>111</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
<width>796</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuSettings">

43
gui/gui/apikey.py Normal file
View File

@ -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_ApiKey(object):
def setupUi(self, ApiKey):
ApiKey.setObjectName("ApiKey")
ApiKey.resize(276, 98)
self.label = QtWidgets.QLabel(ApiKey)
self.label.setGeometry(QtCore.QRect(20, 10, 91, 16))
self.label.setObjectName("label")
self.apikeyInput = QtWidgets.QLineEdit(ApiKey)
self.apikeyInput.setGeometry(QtCore.QRect(120, 10, 141, 21))
self.apikeyInput.setObjectName("apikeyInput")
self.testButton = QtWidgets.QPushButton(ApiKey)
self.testButton.setGeometry(QtCore.QRect(14, 40, 111, 24))
self.testButton.setObjectName("testButton")
self.saveButton = QtWidgets.QPushButton(ApiKey)
self.saveButton.setGeometry(QtCore.QRect(140, 40, 121, 24))
self.saveButton.setObjectName("saveButton")
self.outputLabel = QtWidgets.QLabel(ApiKey)
self.outputLabel.setGeometry(QtCore.QRect(20, 70, 231, 16))
self.outputLabel.setObjectName("outputLabel")
self.retranslateUi(ApiKey)
QtCore.QMetaObject.connectSlotsByName(ApiKey)
def retranslateUi(self, ApiKey):
_translate = QtCore.QCoreApplication.translate
ApiKey.setWindowTitle(_translate("ApiKey", "Form"))
self.label.setText(_translate("ApiKey", "OpenAI API-Key"))
self.testButton.setText(_translate("ApiKey", "Test Key"))
self.saveButton.setText(_translate("ApiKey", "Save"))
self.outputLabel.setText(_translate("ApiKey", "Key working..."))

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<class>ApiKey</class>
<widget class="QWidget" name="ApiKey">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>265</width>
<height>91</height>
<width>276</width>
<height>98</height>
</rect>
</property>
<property name="windowTitle">
@ -26,17 +26,17 @@
<string>OpenAI API-Key</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<widget class="QLineEdit" name="apikeyInput">
<property name="geometry">
<rect>
<x>110</x>
<x>120</x>
<y>10</y>
<width>141</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="testButton">
<property name="geometry">
<rect>
<x>14</x>
@ -49,10 +49,10 @@
<string>Test Key</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="saveButton">
<property name="geometry">
<rect>
<x>134</x>
<x>140</x>
<y>40</y>
<width>121</width>
<height>24</height>
@ -62,7 +62,7 @@
<string>Save</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="outputLabel">
<property name="geometry">
<rect>
<x>20</x>

84
gui/gui/connection.py Normal file
View File

@ -0,0 +1,84 @@
# -*- 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_Connection(object):
def setupUi(self, Connection):
Connection.setObjectName("Connection")
Connection.resize(249, 252)
self.label = QtWidgets.QLabel(Connection)
self.label.setGeometry(QtCore.QRect(20, 10, 101, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Connection)
self.label_2.setGeometry(QtCore.QRect(20, 70, 49, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Connection)
self.label_3.setGeometry(QtCore.QRect(20, 100, 61, 16))
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(Connection)
self.label_4.setGeometry(QtCore.QRect(20, 130, 81, 16))
self.label_4.setObjectName("label_4")
self.label_5 = QtWidgets.QLabel(Connection)
self.label_5.setGeometry(QtCore.QRect(20, 160, 61, 16))
self.label_5.setObjectName("label_5")
self.portInput = QtWidgets.QLineEdit(Connection)
self.portInput.setGeometry(QtCore.QRect(100, 70, 131, 21))
self.portInput.setText("")
self.portInput.setObjectName("portInput")
self.usernameInput = QtWidgets.QLineEdit(Connection)
self.usernameInput.setGeometry(QtCore.QRect(100, 100, 131, 21))
self.usernameInput.setText("")
self.usernameInput.setObjectName("usernameInput")
self.passwordInput = QtWidgets.QLineEdit(Connection)
self.passwordInput.setGeometry(QtCore.QRect(100, 130, 131, 21))
self.passwordInput.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhSensitiveData)
self.passwordInput.setObjectName("passwordInput")
self.databaseInput = QtWidgets.QLineEdit(Connection)
self.databaseInput.setGeometry(QtCore.QRect(100, 160, 131, 21))
self.databaseInput.setObjectName("databaseInput")
self.testButton = QtWidgets.QPushButton(Connection)
self.testButton.setEnabled(False)
self.testButton.setGeometry(QtCore.QRect(14, 190, 101, 24))
self.testButton.setObjectName("testButton")
self.saveButton = QtWidgets.QPushButton(Connection)
self.saveButton.setEnabled(False)
self.saveButton.setGeometry(QtCore.QRect(130, 190, 101, 24))
self.saveButton.setObjectName("saveButton")
self.returnLabel = QtWidgets.QLabel(Connection)
self.returnLabel.setGeometry(QtCore.QRect(20, 220, 211, 16))
self.returnLabel.setObjectName("returnLabel")
self.label_6 = QtWidgets.QLabel(Connection)
self.label_6.setGeometry(QtCore.QRect(20, 40, 101, 16))
self.label_6.setObjectName("label_6")
self.ipInput = QtWidgets.QLineEdit(Connection)
self.ipInput.setGeometry(QtCore.QRect(100, 40, 131, 21))
self.ipInput.setText("")
self.ipInput.setObjectName("ipInput")
self.dbtypeCombo = QtWidgets.QComboBox(Connection)
self.dbtypeCombo.setGeometry(QtCore.QRect(100, 10, 131, 22))
self.dbtypeCombo.setObjectName("dbtypeCombo")
self.retranslateUi(Connection)
QtCore.QMetaObject.connectSlotsByName(Connection)
def retranslateUi(self, Connection):
_translate = QtCore.QCoreApplication.translate
Connection.setWindowTitle(_translate("Connection", "Form"))
self.label.setText(_translate("Connection", "Database"))
self.label_2.setText(_translate("Connection", "Port"))
self.label_3.setText(_translate("Connection", "Username"))
self.label_4.setText(_translate("Connection", "Password"))
self.label_5.setText(_translate("Connection", "Database"))
self.testButton.setText(_translate("Connection", "Test Connection"))
self.saveButton.setText(_translate("Connection", "Save"))
self.returnLabel.setText(_translate("Connection", "Connection ... / Saved..."))
self.label_6.setText(_translate("Connection", "IP"))

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<class>Connection</class>
<widget class="QWidget" name="Connection">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>249</width>
<height>217</height>
<height>252</height>
</rect>
</property>
<property name="windowTitle">
@ -23,14 +23,14 @@
</rect>
</property>
<property name="text">
<string>IP</string>
<string>Database</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>40</y>
<y>70</y>
<width>49</width>
<height>16</height>
</rect>
@ -43,7 +43,7 @@
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<y>100</y>
<width>61</width>
<height>16</height>
</rect>
@ -56,7 +56,7 @@
<property name="geometry">
<rect>
<x>20</x>
<y>100</y>
<y>130</y>
<width>81</width>
<height>16</height>
</rect>
@ -69,7 +69,7 @@
<property name="geometry">
<rect>
<x>20</x>
<y>130</y>
<y>160</y>
<width>61</width>
<height>16</height>
</rect>
@ -78,33 +78,7 @@
<string>Database</string>
</property>
</widget>
<widget class="QLineEdit" name="IP">
<property name="geometry">
<rect>
<x>100</x>
<y>10</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLineEdit" name="port">
<property name="geometry">
<rect>
<x>100</x>
<y>40</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLineEdit" name="username">
<widget class="QLineEdit" name="portInput">
<property name="geometry">
<rect>
<x>100</x>
@ -117,7 +91,7 @@
<string/>
</property>
</widget>
<widget class="QLineEdit" name="password">
<widget class="QLineEdit" name="usernameInput">
<property name="geometry">
<rect>
<x>100</x>
@ -126,11 +100,11 @@
<height>21</height>
</rect>
</property>
<property name="inputMethodHints">
<set>Qt::ImhHiddenText|Qt::ImhSensitiveData</set>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLineEdit" name="database">
<widget class="QLineEdit" name="passwordInput">
<property name="geometry">
<rect>
<x>100</x>
@ -139,15 +113,28 @@
<height>21</height>
</rect>
</property>
<property name="inputMethodHints">
<set>Qt::ImhHiddenText|Qt::ImhSensitiveData</set>
</property>
</widget>
<widget class="QPushButton" name="TestConnection">
<widget class="QLineEdit" name="databaseInput">
<property name="geometry">
<rect>
<x>100</x>
<y>160</y>
<width>131</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="testButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>14</x>
<y>160</y>
<y>190</y>
<width>101</width>
<height>24</height>
</rect>
@ -163,7 +150,7 @@
<property name="geometry">
<rect>
<x>130</x>
<y>160</y>
<y>190</y>
<width>101</width>
<height>24</height>
</rect>
@ -176,7 +163,7 @@
<property name="geometry">
<rect>
<x>20</x>
<y>190</y>
<y>220</y>
<width>211</width>
<height>16</height>
</rect>
@ -185,24 +172,43 @@
<string>Connection ... / Saved...</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>20</x>
<y>40</y>
<width>101</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>IP</string>
</property>
</widget>
<widget class="QLineEdit" name="ipInput">
<property name="geometry">
<rect>
<x>100</x>
<y>40</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QComboBox" name="dbtypeCombo">
<property name="geometry">
<rect>
<x>100</x>
<y>10</y>
<width>131</width>
<height>22</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>IP</sender>
<signal>textChanged(QString)</signal>
<receiver>saveButton</receiver>
<slot>customSlot()</slot>
<hints>
<hint type="sourcelabel">
<x>171</x>
<y>25</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>170</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

23
gui/gui/convert.py Normal file
View File

@ -0,0 +1,23 @@
import os
import subprocess
def convert():
# get a list of all .ui files in the current directory
ui_files = [f for f in os.listdir('.') if f.endswith('.ui')]
# loop over each .ui file and convert it to a .py file
for ui_filename in ui_files:
# construct the name of the output .py file
py_filename = os.path.splitext(ui_filename)[0] + '.py'
# run the pyuic5 command to convert the .ui file to a .py file
cmd = f'pyuic5 {ui_filename} -o {py_filename}'
subprocess.call(cmd, shell=True)
# print a message to indicate that the conversion is complete
print(f'{ui_filename} converted to {py_filename}')
if __name__ == '__main__':
convert()

View File

@ -1,31 +1,198 @@
import json
import os
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog
from mainWindow import Ui_MainWindow
from connection import Ui_Form
import modules.aisql as aisql
from gui.apikey import Ui_ApiKey as ApiKeyForm
from gui.connection import Ui_Connection as ConnectionForm
from gui.gui.Window import Ui_MainWindow
configfolder = "config"
configfile = "config.json"
dbtypes = {
0: "PostgreSQL",
1: "MySQL",
2: "SQLite"
}
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Open Connection Window
self.ui.actionConnect_DB.triggered.connect(self.open_connection)
# Open API Key Window
self.ui.actionConnect_API_Key.triggered.connect(self.open_apikey)
# Pressed Convert Button
self.ui.convertButton.clicked.connect(self.on_convert_button_clicked)
def open_connection(self):
self.connection_window = ConnectionWindow(self)
self.connection_window.show()
def open_apikey(self):
self.apikey_window = ApiKeyWindow(self)
self.apikey_window.show()
def on_convert_button_clicked(self):
print("Convert Button Clicked")
print(self.ui.textInput.text())
### Connection Window ###
class ConnectionWindow(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Form()
self.ui = ConnectionForm()
self.ui.setupUi(self)
self.ui.saveButton.setEnabled(False)
self.ui.testButton.setEnabled(False)
self.ui.returnLabel.setText("")
def customSlot(self, text):
if self.ui.IP.text():
self.ui.saveButton.setEnabled(True)
else:
# Load DB Config from file
with open(os.path.join(configfolder, configfile), "r") as f:
self.config = json.load(f)
self.dbtype = self.config["database"]["dbtype"]
self.dbip = self.config["database"]["ip"]
self.dbport = self.config["database"]["port"]
self.dbuser = self.config["database"]["user"]
self.dbpass = self.config["database"]["password"]
self.dbname = self.config["database"]["database"]
self.ui.dbtypeCombo.addItems(dbtypes.values())
self.ui.dbtypeCombo.setCurrentIndex(self.dbtype)
self.ui.ipInput.setText(self.dbip)
self.ui.portInput.setText(self.dbport)
self.ui.usernameInput.setText(self.dbuser)
self.ui.passwordInput.setText(self.dbpass)
self.ui.databaseInput.setText(self.dbname)
# Unlock Buttons if ip, port and database is not empty
self.ui.ipInput.textChanged.connect(self.on_text_changed)
self.ui.portInput.textChanged.connect(self.on_text_changed)
self.ui.databaseInput.textChanged.connect(self.on_text_changed)
# Pressed Save Button
self.ui.saveButton.clicked.connect(self.on_save_button_clicked)
# Pressed Test Button
self.ui.testButton.clicked.connect(self.on_test_button_clicked)
def on_text_changed(self):
if self.ui.ipInput.text() == "" or self.ui.portInput.text() == "" or self.ui.databaseInput.text() == "":
self.ui.saveButton.setEnabled(False)
self.ui.testButton.setEnabled(False)
else:
self.ui.saveButton.setEnabled(True)
self.ui.testButton.setEnabled(True)
def on_save_button_clicked(self):
self.dbtype = self.ui.dbtypeCombo.currentIndex()
self.dbip = self.ui.ipInput.text()
self.dbport = self.ui.portInput.text()
self.dbuser = self.ui.usernameInput.text()
self.dbpass = self.ui.passwordInput.text()
self.dbname = self.ui.databaseInput.text()
self.config["database"]["dbtype"] = self.dbtype
self.config["database"]["ip"] = self.dbip
self.config["database"]["port"] = self.dbport
self.config["database"]["user"] = self.dbuser
self.config["database"]["password"] = self.dbpass
self.config["database"]["database"] = self.dbname
with open(os.path.join(configfolder, configfile), "w") as f:
json.dump(self.config, f, indent=4)
self.close()
# FIXME: Crash when testing connection
def on_test_button_clicked(self):
self.dbtype = self.ui.dbtypeCombo.currentIndex()
self.dbip = self.ui.ipInput.text()
self.dbport = self.ui.portInput.text()
self.dbuser = self.ui.usernameInput.text()
self.dbpass = self.ui.passwordInput.text()
self.dbname = self.ui.databaseInput.text()
if self.dbtype == 0: # PostgreSQL
import database.postgresql as postgresql
db = postgresql.Postgre(self.dbip, self.dbport, self.dbuser, self.dbpass, self.dbname)
if db.test_connection():
self.ui.returnLabel.setText("Connection successful")
self.ui.returnLabel.setStyleSheet("color: green")
else:
self.ui.returnLabel.setText("Connection failed")
self.ui.returnLabel.setStyleSheet("color: red")
### Api Key Window ###
class ApiKeyWindow(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = ApiKeyForm()
self.ui.setupUi(self)
self.ui.outputLabel.setText("")
# Load API Key from file
with open(os.path.join(configfolder, configfile), "r") as f:
self.config = json.load(f)
self.apikey = self.config["apikey"]
self.ui.apikeyInput.setText(self.apikey)
if self.apikey == "":
self.ui.saveButton.setEnabled(False)
self.ui.testButton.setEnabled(False)
else:
self.ui.saveButton.setEnabled(True)
self.ui.testButton.setEnabled(True)
# Unlock Buttons if text is entered
self.ui.apikeyInput.textChanged.connect(self.on_text_changed)
# Pressed Save Button
self.ui.saveButton.clicked.connect(self.on_save_button_clicked)
# Pressed Test Button
self.ui.testButton.clicked.connect(self.on_test_button_clicked)
def on_text_changed(self):
if self.ui.apikeyInput.text() == "":
self.ui.saveButton.setEnabled(False)
self.ui.testButton.setEnabled(False)
else:
self.ui.saveButton.setEnabled(True)
self.ui.testButton.setEnabled(True)
def on_save_button_clicked(self):
self.apikey = self.ui.apikeyInput.text()
with open(os.path.join(configfolder, configfile), "w") as f:
self.config["apikey"] = self.apikey
json.dump(self.config, f)
# Close Window
self.close()
def on_test_button_clicked(self):
test_key = self.ui.apikeyInput.text()
ai = aisql.AI(test_key)
if ai.test_key():
self.ui.outputLabel.setText("API Key is valid")
self.ui.outputLabel.setStyleSheet("color: green")
else:
self.ui.outputLabel.setText("API Key is invalid")
self.ui.outputLabel.setStyleSheet("color: red")
if __name__ == "__main__":
app = QApplication(sys.argv)

67
gui/modules/aisql.py Normal file
View File

@ -0,0 +1,67 @@
import openai
class AI:
def __init__(self, api_key):
self.api_key = api_key
openai.api_key = self.api_key
self.convertlog = []
def humantosql(self, text: str, dbtype: str, tableschema: list) -> str:
if not self.convertlog:
self.convertlog = [{"role": "system",
"content": f"You convert Human Language to SQL. Only answer as an Valid SQL Statement. Always modify your previous answer and do not create something new. You are using this Database: {dbtype}. For better context here are the tables and columns: {tableschema}"}]
prompt = {"role": "user", "content": text}
self.convertlog.append(prompt)
self.response = openai.ChatCompletion.create(
model="gpt-4",
messages=self.convertlog
)
self.response = self.response['choices'][0]['message']['content']
self.convertlog.append({"role": "assistant", "content": self.response})
if self.validate(self.response) is True:
return self.response
else:
valid = self.humantosql("Only answer as a Valid SQL-Statement don't add any additional text", dbtype,
tableschema)
return valid
def decide(self, sql: str) -> str:
prompt = [{"role": "system",
"content": "You have to decide which function it should use. Answer with [FETCHALL] to fetch all, [FETCHONE] to fetch only one, [FETCHMANY=N] to fetchmany with N being the range, [EXECUTE] to just execute, [EXECUTEMANY=N] to execute many with N being the range"},
{"role": "user", "content": sql}]
response = openai.ChatCompletion.create(
model="gpt-4",
messages=prompt
)
response = response['choices'][0]['message']['content']
return response
def validate(self, sql: str) -> bool:
prompt = [{"role": "system",
"content": "You check if the User Input is a valid SQL-Statement. You also return False if there is any kind of text before and after the statement. You only return True or False. Most important: ONLY ANSWER True OR False."},
{"role": "user", "content": sql}]
valid = openai.ChatCompletion.create(
model="gpt-4",
messages=prompt
)
valid = valid['choices'][0]['message']['content']
if valid == "True":
return True
else:
return False
def test_key(self) -> bool:
openai.api_key = str(self.api_key)
try:
openai.Engine.list()
return True
except Exception as e:
print(e)
return False