job-scrapper/lib/gui.py

442 lines
14 KiB
Python

from PySide6.QtWidgets import QApplication, QWidget, QMainWindow, QTableWidget, QVBoxLayout, QTableWidgetItem, QPushButton, QHBoxLayout, QTableView, QLineEdit, QDialog, QLabel, QTextEdit, QCheckBox, QComboBox, QStyledItemDelegate
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtCore import QUrl,Qt,QSortFilterProxyModel, qDebug, QSize,QObject,QThread,Signal,QAbstractTableModel, Slot
from PySide6.QtSql import QSqlDatabase, QSqlTableModel, QSqlQueryModel, QSqlQuery
from PySide6 import QtGui
from db import addFineFilter
import sysparse
import sys
import db as db
from qsqlmod import SqlQueryModel_editable
DEBUG = True
def log(*s):
if DEBUG:
print(s)
DBFILE = "../db/sqlite3.db"
Cantons = ["AG","ZH","BE","SG","SO"]
class ColorDelegate(QStyledItemDelegate):
currentRow = 0
starred = 0
def __init__(self,main):
super().__init__()
print("initialice overload init of ColorDelegate")
self.main = main
def initStyleOption(self,option,index):
super().initStyleOption(option,index)
data = index.data()
column = index.column()
flag_viewed = self.main.sel_model.model().index(index.row(),8).data()
try:
flag_starred = int(self.main.sel_model.model().index(index.row(),0).data())
except ValueError:
print("probably empty string asign zero")
flag_starred = 0
#print("index:",index)
#print("column ",column)
#print("data:", flag_starred)
if flag_starred == 1:
option.backgroundBrush = QtGui.QColor("red")
elif flag_viewed != 1:
option.backgroundBrush = QtGui.QColor("green")
else:
option.backgroundBrush = QtGui.QColor("white")
#if column == 0:
# try:
# value = float(data)
# except:
# pass
# #print("error not an integer")
# else:
# #self.view.currentRow = index.row()
# #print("row: ",self.currentRow)
# if value == 1:
# self.starred = 1
# else:
# self.starred = 0
# if column == 8:
# try:
# value = float(data)
# except:
# pass
# else:
# if value == 1:
# self.starred = 2
# else:
# self.starred = 0
# if self.starred == 1:
# option.backgroundBrush = QtGui.QColor("red")
# elif self.starred == 2:
# option.backgroundBrush = QtGui.QColor("white")
# else:
# option.backgroundBrush = QtGui.QColor("green")
class ValidationWorker(QObject):
finished = Signal()
def run(self):
ret = db.isStillValid(DBFILE,0)
if ret == 0:
self.finished.emit()
class Worker(QObject):
pwprompt = Signal()
pw = Signal(str)
finished = Signal()
dialog_closed = True
dialog_rejected = False
password = ['empty']
def run(self):
sysparse.parse(config="conf",worker=self)
def return_pw(self,x):
self.password = [x]
self.dialog_closed = True
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.w = None
self.cmdCanton = ''
self.initcmd = 'SELECT * FROM jobs as b '
self.customcmd = ''
self.cmd = ''
self.setWindowTitle("DB_Inspector")
self.isAWhere = False
self.layout = QVBoxLayout()
self.layout2 = QHBoxLayout()
self.b_canton = QPushButton("Modify Filter")
self.b_canton.clicked.connect(self.showQueryWindow)
self.browser = QWebEngineView()
self.browser.setUrl(QUrl("https://jobagent.ch"))
self.EditQuery = QLineEdit()
self.EditQuery.returnPressed.connect(self.queryEditLine)
editables = {0 : ("UPDATE jobs SET star = '{}' WHERE hash = '{}'",7)}
self.model = SqlQueryModel_editable(editables)
self.view = QTableView()
self.view.setModel(self.model)
delegate = ColorDelegate(self)
self.view.setItemDelegate(delegate)
self.setProxyViewSettings()
self.view.activated.connect(self.cell_clicked)
self.sel_model = self.view.selectionModel()
self.sel_model.selectionChanged.connect(self.cell_clicked)
self.PValidate = QPushButton("links valid")
self.PValidate.clicked.connect(self.runValidation)
self.PsyncDB = QPushButton("Perform sync acording to config file")
self.PsyncDB.clicked.connect(self.runWorker)
self.layout.addWidget(self.view)
self.layout.addWidget(self.b_canton)
self.layout.addWidget(self.EditQuery)
self.layout.addWidget(self.PsyncDB)
self.layout.addWidget(self.PValidate)
self.layout2.addLayout(self.layout)
self.layout2.addWidget(self.browser)
widget = QWidget()
widget.setLayout(self.layout2)
self.setCentralWidget(widget)
def setProxyViewSettings(self):
self.view.resizeColumnsToContents()
self.view.setColumnWidth(5,10)
self.view.hideColumn(7)
self.view.setSortingEnabled(True)
self.sel_model = self.view.selectionModel()
self.sel_model.selectionChanged.connect(self.cell_clicked)
def runWorker(self):
self.thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.disable_PsyncDB)
self.thread.started.connect(self.worker.run)
self.worker.pwprompt.connect(self.showDialog)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.enable_PsyncDB)
self.thread.start()
def runValidation(self):
self.validationThread = QThread()
self.validationWorker = ValidationWorker()
self.validationWorker.moveToThread(self.validationThread)
self.validationThread.started.connect(self.disableValidationButton)
self.validationThread.started.connect(self.validationWorker.run)
self.validationThread.start()
self.validationWorker.finished.connect(self.validationThread.quit)
self.validationWorker.finished.connect(self.enableValidationButton)
def enableValidationButton(self):
self.PValidate.setEnabled(True)
def disableValidationButton(self):
self.PValidate.setEnabled(False)
def disable_PsyncDB(self):
self.PsyncDB.setText("Sync Running...")
self.PsyncDB.setEnabled(False)
def enable_PsyncDB(self):
self.PsyncDB.setEnabled(True)
self.PsyncDB.setText("Perform another sync acording to config file")
def showDialog(self):
w = PWPrompt()
w.set_MSG(self.worker.messageContent)
ret = w.exec()
if ret == QDialog.Rejected:
self.worker.dialog_rejected = True
log("[gui] qdialog.rejected set to TRUE")
self.pw = w.pw
self.worker.password = w.pw
log("showDialog,self.pw:",self.pw)
self.worker.dialog_closed=True
def showQueryWindow(self,checked):
if self.w is None:
self.w = QueryWindow()
self.w.show()
self.w.queryFineFilers()
def filter_canton(self,canton):
if canton != "ALL":
self.cmdCanton = f"""
WHERE EXISTS
(SELECT GDENAME FROM Cantons as w
where w.GDEKT = '{canton}' AND
b.location LIKE GDENAME) """
print("cmd canton:", self.cmdCanton)
else:
self.cmdCanton = ''
print("disable fil§.ter")
# self.customSQL(self.cmd)
def queryEditLine(self):
self.cmd = self.EditQuery.text()
if self.customcmd or self.cmd:
if self.cmdCanton:
self.isAWhere = True
connectingstring = " AND "
else:
self.isAWhere = False
connectingstring = " WHERE "
else:
connectingstring = ' '
print(self.initcmd + self.cmdCanton +connectingstring +self.customcmd + self.cmd)
self.customSQL(self.initcmd+ self.cmdCanton + connectingstring + self.customcmd + self.cmd)
if self.customcmd or self.cmd:
addFineFilter("../db/sqlite3.db","filters",self.customcmd + self.cmd)
def cell_clicked(self):
x = self.view.selectionModel().currentIndex().row()
y = self.view.selectionModel().currentIndex().column()
data = self.view.model().index(x,5).data()
print("cell clicked:",x," / ",y, "-->",data)
self.browser.setUrl(QUrl(data))
hash1 = self.view.model().index(x,7).data()
print("hash of selected: ",hash1)
#db.viewedEntry(hash1)
self.view.selectionModel().currentIndex()
self.model.setData({0,8},hash1,role=1001)
def customSQL(self,cmd):
print("Run SQL Query",cmd)
#self.model.setTable("")
self.model.setQuery(cmd +" ;")
#self.model.setTable("jobs")
while (self.model.canFetchMore()):
print("fetch iterations++")
self.model.fetchMore()
self.proxymodel2 = QSortFilterProxyModel(self)
self.proxymodel2.setSourceModel(self.model)
self.view.setModel(self.proxymodel2)
self.setProxyViewSettings()
self.view.show()
class PWPrompt(QDialog):
def __init__(self):
super().__init__()
self.pw = ''
self.MSG1 = QLabel("Please Enter Password")
self.MSG = QLabel("ACCOUNT")
self.BOK = QPushButton("OK")
self.BCancel = QPushButton("Cancel")
self.EPW = QLineEdit()
self.EPW.setEchoMode(QLineEdit.EchoMode.Password)
self.BOK.clicked.connect(self.confirm)
self.BCancel.clicked.connect(self.reject)
self.VLayout = QVBoxLayout()
self.VLayout.addWidget(self.MSG1)
self.VLayout.addWidget(self.MSG)
self.VLayout.addWidget(self.EPW)
self.VLayout.addWidget(self.BOK)
self.VLayout.addWidget(self.BCancel)
self.setLayout(self.VLayout)
def confirm(self):
self.accept()
self.pw = self.EPW.text()
def set_MSG(self,message):
self.MSG.setText(message)
class QueryWindow(QWidget):
def __init__(self):
super().__init__()
self.FlagShow = 0
self.label = QLabel("Query settings")
self.setWindowTitle("Query")
self.EditQuery = QTextEdit()
self.BSubmit = QPushButton("Submit")
self.BSubmit.clicked.connect(self.submit)
self.LFilter = QLabel()
self.LFilter.setText("Filter by Cantons")
self.CFilter = QComboBox()
self.CFilter.addItem("ALL")
for Canton in Cantons:
self.CFilter.addItem(Canton)
self.CFilter.currentTextChanged.connect(window.filter_canton)
self.CFilter.currentTextChanged.connect(self.setTFilter)
self.TFilter = QTextEdit()
self.TFilter.setReadOnly(True)
self.TInitCmd = QLabel()
self.TInitCmd.setText(window.initcmd)
self.vLayout = QVBoxLayout()
self.vLayout.addWidget(self.TInitCmd)
self.vLayout.addWidget(self.TFilter)
self.vLayout.addWidget(self.EditQuery)
self.vLayout.addWidget(self.BSubmit)
self.LShowViews = QLabel()
self.LShowViews.setText("Custom Views in Database")
self.CShowViews = QComboBox()
items = self.getViews()
for item in items:
self.CShowViews.addItem(item)
self.CShowViews.currentTextChanged.connect(self.setView)
self.CShowFineFilters = QComboBox()
self.queryFineFilers()
self.CShowFineFilters.currentTextChanged.connect(window.EditQuery.setText)
self.PApplyView = QCheckBox()
self.PApplyView.setText("Apply View")
self.PApplyView.clicked.connect(self.setView)
self.vrLayout = QVBoxLayout()
self.vrLayout.addWidget(self.LFilter)
self.vrLayout.addWidget(self.CFilter)
self.vrLayout.addWidget(self.LShowViews)
self.vrLayout.addWidget(self.CShowViews)
self.vrLayout.addWidget(self.PApplyView)
self.vrLayout.addWidget(self.CShowFineFilters)
self.WvrLayout = QWidget()
self.WvrLayout.setLayout(self.vrLayout)
self.WvrLayout.setMaximumSize(QSize(200,200))
self.hLayout = QHBoxLayout()
self.hLayout.addLayout(self.vLayout)
self.hLayout.addWidget(self.WvrLayout)
widget = QWidget()
self.setLayout(self.hLayout)
self.EditQuery.setText(window.customcmd)
print("Comboshowview:",self.CShowViews.currentText())
def queryFineFilers(self):
self.CShowFineFilters.clear()
FineFilterItems = self.getFineFilters()
for item in FineFilterItems:
self.CShowFineFilters.addItem(item)
def getFineFilters(self):
item = []
statement = f"""Select cmd FROM filters;"""
query = QSqlQuery(statement)
while query.next():
item.append(query.value(0))
return item
def getViews(self):
item = []
statement = f"""SELECT name FROM sqlite_master where type='view'"""
query = QSqlQuery(statement)
while query.next():
print(query.value(0))
item.append(query.value(0))
print(query.lastError())
return item
def setView(self):
if self.PApplyView.isChecked():
self.view = self.CShowViews.currentText()
print("Selected View:",self.view)
window.initcmd = f"""SELECT * FROM '{self.view}' """
print("window.initcmd:", window.initcmd)
else:
window.initcmd = f"""SELECT * FROM jobs as b """
print("View unchecked")
self.TInitCmd.setText(window.initcmd)
def setTFilter(self):
self.TFilter.setText(window.cmdCanton)
def submit(self):
self.setView()
window.customcmd = self.EditQuery.toPlainText()
window.queryEditLine()
#print("text:",window.customcmd)
#window.customSQL(window.customcmd)
self.hide()
def out(self,s):
print("Current selection",s)
app = QApplication(sys.argv)
con = QSqlDatabase.addDatabase("QSQLITE")
con.setDatabaseName("../db/sqlite3.db")
if not con.open():
qDebug("Error on opening sql database")
sys.exit(1)
window = MainWindow()
window.show()
app.exec()