diff --git a/gui/kontor.py b/gui/kontor.py index be15c66..3b601ad 100644 --- a/gui/kontor.py +++ b/gui/kontor.py @@ -6,17 +6,17 @@ from pathlib import Path import yaml from PySide6.QtGui import QAction, QIcon -from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView, QHBoxLayout, QCheckBox +from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView from PySide6.QtWidgets import QApplication, QLabel, QMainWindow from platformdirs import PlatformDirs from comic_model import ComicTableModel -from media_file_model import MediaFileTableModel +from model_config import KontorModelConfig +from table_model import KontorTableModel class MainWindow(QMainWindow): - def __init__(self, config): super().__init__() @@ -28,10 +28,10 @@ class MainWindow(QMainWindow): self.setWindowTitle("Kontor") self.setMinimumSize(800, 500) - self._createActions() - self._createMenuBar() - self._createToolBars() - self._createStatusBar() + self._create_actions() + self._create_menubar() + self._create_toolbars() + self._create_statusbar() self.data = [] self.filter = {} @@ -47,7 +47,7 @@ class MainWindow(QMainWindow): self.setCentralWidget(self.central_widget) - def _createActions(self): + def _create_actions(self): self.newAction = QAction("&New", self) self.aboutAction = QAction("&Über...", self) self.aboutAction.triggered.connect(self.about) @@ -59,7 +59,7 @@ class MainWindow(QMainWindow): self.exitAction.setShortcut("Alt+F4") self.exitAction.triggered.connect(self.close) - def _createMenuBar(self): + def _create_menubar(self): menu_bar = self.menuBar() # File menu file_menu = QMenu("&Datei") @@ -75,14 +75,14 @@ class MainWindow(QMainWindow): menu_bar.addMenu(help_menu) help_menu.addAction(self.aboutAction) - def _createToolBars(self): + def _create_toolbars(self): # Kontor toolbar kontor_tool_bar = self.addToolBar("Kontor") kontor_tool_bar.addAction(self.importAction) kontor_tool_bar.addAction(self.exportAction) kontor_tool_bar.addAction(self.refreshAction) - def _createStatusBar(self): + def _create_statusbar(self): self.statusBar = self.statusBar() self.statusBar.showMessage("Kontor ready", 6000) self.status_label = QLabel("") @@ -110,25 +110,15 @@ class MainWindow(QMainWindow): def generate_tab_media_file(self, db_configuration): media_file_tab = QWidget() + table_config = KontorModelConfig(db_configuration, self, "media_file") + model = KontorTableModel(table_config) layout = QVBoxLayout() - filter_layout = QHBoxLayout() - download_checkbox = QCheckBox() - download_checkbox.setText("Download") - download_checkbox.checkStateChanged.connect(self.refresh) - self.filter["download"] = download_checkbox - review_checkbox = QCheckBox() - review_checkbox.setText("Review") - review_checkbox.checkStateChanged.connect(self.refresh) - self.filter["review"] = review_checkbox - filter_layout.addWidget(review_checkbox) - filter_layout.addWidget(download_checkbox) - filter_layout.addStretch() - model = MediaFileTableModel(db_configuration, self) + # model = MediaFileTableModel(db_configuration, self) self.data.append(model) media_file_tab.setLayout(layout) table_view = QTableView() table_view.setModel(model) - layout.addLayout(filter_layout) + layout.addLayout(table_config.get_filter_layout()) layout.addWidget(table_view) return media_file_tab diff --git a/gui/model_config.py b/gui/model_config.py new file mode 100644 index 0000000..1bea8a5 --- /dev/null +++ b/gui/model_config.py @@ -0,0 +1,82 @@ +import mariadb +from PySide6.QtWidgets import QHBoxLayout, QCheckBox + + +class KontorModelConfig: + + def __init__(self, db_config, main_window, table_name: str): + self.header = [] + self.filter = {} + self.main_window = main_window + self._table = table_name + self.db_conn = mariadb.connect( + host=db_config['mariadb']['host'], + port=db_config['mariadb']['port'], + user=db_config['mariadb']['user'], + password=db_config['mariadb']['password'], + database=db_config['mariadb']['database'] + ) + self.get_table_config() + + def get_table_id(self): + cursor = self.db_conn.cursor() + cursor.execute("SELECT id, created_date, last_modified_date FROM meta_data_table WHERE table_name=?", (self._table, )) + rows = cursor.fetchall() + if len(rows) == 1: + return rows[0][0] + return None + + def get_table_config(self): + table_id = self.get_table_id() + cursor = self.db_conn.cursor() + cursor.execute("SELECT id, column_name, column_order FROM meta_data_column WHERE table_id=? AND is_shown is true", (table_id, )) + rows = cursor.fetchall() + self.header.clear() + for (column_id, column_name, column_order) in rows: + self.header.insert(column_order-1, column_name) + print(f"retrieved {len(rows)} columns, set {len(self.header)} headers") + + def get_header(self) -> list: + self.get_table_config() + return self.header + + def get_filter(self) -> str: + filter_rule = "" + # print(self.filter["download"].isChecked()) + if self.filter["download"].isChecked(): + # print(self.filter["download"].isChecked()) + filter_rule = "WHERE should_download is true" + if self.filter["review"].isChecked(): + if len(filter_rule) > 0: + filter_rule += " AND " + else: + filter_rule += "WHERE " + filter_rule += "review is true" + print(f"{filter_rule=}") + return filter_rule + + def get_statement(self) -> str: + filter_rule = self.get_filter() + self.get_table_config() + columns = "" + for index in range(len(self.header)): + if index > 0: + columns += ", " + columns += self.header[index] + statement = f"SELECT {columns} FROM media_file {filter_rule}" + return statement + + def get_filter_layout(self) -> QHBoxLayout: + filter_layout = QHBoxLayout() + download_checkbox = QCheckBox() + download_checkbox.setText("Download") + download_checkbox.checkStateChanged.connect(self.main_window.refresh) + self.filter["download"] = download_checkbox + review_checkbox = QCheckBox() + review_checkbox.setText("Review") + review_checkbox.checkStateChanged.connect(self.main_window.refresh) + self.filter["review"] = review_checkbox + filter_layout.addWidget(review_checkbox) + filter_layout.addWidget(download_checkbox) + filter_layout.addStretch() + return filter_layout diff --git a/gui/media_file_model.py b/gui/table_model.py similarity index 52% rename from gui/media_file_model.py rename to gui/table_model.py index e5af2a4..5fc5dc9 100644 --- a/gui/media_file_model.py +++ b/gui/table_model.py @@ -1,41 +1,23 @@ from datetime import datetime -import mariadb -from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt -from PySide6.QtGui import QColor +from PySide6.QtCore import QAbstractTableModel, QModelIndex +from PySide6.QtGui import Qt + +from model_config import KontorModelConfig -class MediaFileTableModel(QAbstractTableModel): +class KontorTableModel(QAbstractTableModel): - def __init__(self, db_config, main_window): + def __init__(self, model_config: KontorModelConfig): super().__init__() - self.main_window = main_window - self._data = [] - self.mariadb_conn = mariadb.connect( - host=db_config['mariadb']['host'], - port=db_config['mariadb']['port'], - user=db_config['mariadb']['user'], - password=db_config['mariadb']['password'], - database=db_config['mariadb']['database'] - ) - self.refresh() + self._main_window = model_config.main_window + self._config = model_config + self._data = None def refresh(self): data = [] - cursor = self.mariadb_conn.cursor() - filter_rule = "" - print(self.main_window.filter["download"].isChecked()) - if self.main_window.filter["download"].isChecked(): - print(self.main_window.filter["download"].isChecked()) - filter_rule = "WHERE should_download is true" - if self.main_window.filter["review"].isChecked(): - if len(filter_rule) > 0: - filter_rule += " AND " - else: - filter_rule += "WHERE " - filter_rule += "review is true" - print(f"{filter_rule=}") - cursor.execute(f"SELECT id, url, review, should_download, file_name, cloud_link FROM media_file {filter_rule}") + cursor = self._config.db_conn.cursor() + cursor.execute(self._config.get_statement()) rows = cursor.fetchall() print(len(rows)) if len(rows) > 0: @@ -46,8 +28,8 @@ class MediaFileTableModel(QAbstractTableModel): self.endResetModel() else: self._data = None - self.layoutChanged.emit() - self.main_window.statusBar.showMessage(f"{len(rows)} Einträge geladen", 3000) + self.layoutChanged.emit() + self._main_window.statusBar.showMessage(f"{len(rows)} Einträge geladen", 3000) def rowCount(self, parent=QModelIndex()): # The length of the outer list. @@ -57,19 +39,7 @@ class MediaFileTableModel(QAbstractTableModel): def headerData(self, col, orientation, role=Qt.ItemDataRole.DisplayRole): if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole: - match col: - case 0: - return "ID" - case 1: - return "URL" - case 2: - return "Review" - case 3: - return "Download" - case 4: - return "Filename" - case 5: - return "Cloud Link" + return self._config.header[col] if orientation == Qt.Orientation.Vertical and role == Qt.ItemDataRole.DisplayRole: return str(col+1) @@ -84,24 +54,23 @@ class MediaFileTableModel(QAbstractTableModel): return value if isinstance(value, bytes): if value == b'\x01': - return self.main_window.tick + return self._main_window.tick else: - return self.main_window.cross + return self._main_window.cross return value if role == Qt.ItemDataRole.DecorationRole: if isinstance(value, bytes): # print('{}: {}'.format(value, type(value))) if value == b'\x01': - return self.main_window.tick + return self._main_window.tick else: - return self.main_window.cross + return self._main_window.cross def columnCount(self, index=QModelIndex()): # The following takes the first sub-list, and returns # the length (only works if all rows are an equal length) - if self._data is None: - return 5 - return len(self._data[0]) + print(f"Header count: {len(self._config.get_header())}") + return len(self._config.get_header()) def setData(self, index, value, role=Qt.ItemDataRole.EditRole): if role == Qt.ItemDataRole.EditRole: