remove obsolete kontor-gui
This commit is contained in:
@@ -1,9 +0,0 @@
|
|||||||
deployment/
|
|
||||||
venv/
|
|
||||||
kontor.bin
|
|
||||||
bin/
|
|
||||||
include/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
lib64
|
|
||||||
env/
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
.PHONY: clean virtualenv test docker dist dist-upload
|
|
||||||
|
|
||||||
clean:
|
|
||||||
find . -name '*.py[co]' -delete
|
|
||||||
|
|
||||||
virtualenv:
|
|
||||||
virtualenv --prompt '|> kontor <| ' env
|
|
||||||
env/bin/pip install -r requirements.txt
|
|
||||||
env/bin/python setup.py develop
|
|
||||||
@echo
|
|
||||||
@echo "VirtualENV Setup Complete. Now run: source env/bin/activate"
|
|
||||||
@echo
|
|
||||||
|
|
||||||
test:
|
|
||||||
python -m pytest \
|
|
||||||
-v \
|
|
||||||
--cov=kontor \
|
|
||||||
--cov-report=term \
|
|
||||||
--cov-report=html:coverage-report \
|
|
||||||
tests/
|
|
||||||
|
|
||||||
docker: clean
|
|
||||||
docker build -t kontor-api:latest .
|
|
||||||
|
|
||||||
dist: clean
|
|
||||||
rm -rf dist/*
|
|
||||||
python setup.py sdist
|
|
||||||
python setup.py bdist_wheel
|
|
||||||
|
|
||||||
dist-upload:
|
|
||||||
twine upload dist/*
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# kontor-gui
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
from PySide6.QtCore import Signal, QSortFilterProxyModel
|
|
||||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QTableView, QMdiSubWindow, \
|
|
||||||
QHeaderView
|
|
||||||
|
|
||||||
from gui.model_config import KontorModelConfig
|
|
||||||
from gui.table_model import KontorTableModel
|
|
||||||
|
|
||||||
|
|
||||||
class ComicWindow(QMdiSubWindow):
|
|
||||||
closed = Signal()
|
|
||||||
|
|
||||||
def __init__(self, main_window):
|
|
||||||
super().__init__()
|
|
||||||
self.data_views = list()
|
|
||||||
self._main_window = main_window
|
|
||||||
self.log = main_window.log
|
|
||||||
self._init_gui()
|
|
||||||
self.tick = main_window.tick
|
|
||||||
self.cross = main_window.cross
|
|
||||||
|
|
||||||
def _init_gui(self):
|
|
||||||
self.setWindowTitle("Comics")
|
|
||||||
self.setWidget(QWidget())
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.tabs = QTabWidget()
|
|
||||||
self.tabs.addTab(self.generate_data_tab("comic"), "Comics")
|
|
||||||
self.tabs.addTab(self.generate_data_tab("publisher"), "Publisher")
|
|
||||||
self.tabs.currentChanged.connect(self._tab_changed)
|
|
||||||
layout.addWidget(self.tabs)
|
|
||||||
self.setLayout(layout)
|
|
||||||
self.setWidget(self.tabs)
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
self.closed.emit()
|
|
||||||
super().closeEvent(event)
|
|
||||||
self._main_window.remove_sub_window('comic')
|
|
||||||
|
|
||||||
def refresh(self):
|
|
||||||
# self.log.info("refresh")
|
|
||||||
self.data_views[self.tabs.currentIndex()].refresh()
|
|
||||||
|
|
||||||
def _tab_changed(self, tab_index):
|
|
||||||
self.data_views[tab_index].refresh()
|
|
||||||
|
|
||||||
def update_status(self, message):
|
|
||||||
self._main_window.update_status(message)
|
|
||||||
|
|
||||||
def generate_data_tab(self, table_name):
|
|
||||||
data_tab = QWidget()
|
|
||||||
|
|
||||||
table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name)
|
|
||||||
model = KontorTableModel(table_config)
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.data_views.append(model)
|
|
||||||
data_tab.setLayout(layout)
|
|
||||||
table_view = QTableView()
|
|
||||||
header = table_view.horizontalHeader()
|
|
||||||
header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
|
|
||||||
proxy_model = QSortFilterProxyModel()
|
|
||||||
proxy_model.setSourceModel(model)
|
|
||||||
table_view.setSortingEnabled(True)
|
|
||||||
table_view.setModel(proxy_model)
|
|
||||||
layout.addLayout(table_config.get_filter_layout())
|
|
||||||
layout.addWidget(table_view)
|
|
||||||
model.refresh()
|
|
||||||
return data_tab
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
|
|
||||||
class DataViewMeta(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def get_header(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ComicView(DataViewMeta):
|
|
||||||
def get_header(self):
|
|
||||||
pass
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
from PySide6.QtCore import QModelIndex, QAbstractTableModel
|
|
||||||
from PySide6.QtGui import Qt
|
|
||||||
|
|
||||||
from gui.data_view import DataViewMeta
|
|
||||||
|
|
||||||
|
|
||||||
class DataViewModel(QAbstractTableModel):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.main_window = None
|
|
||||||
self._config = None
|
|
||||||
self._data = List[DataViewMeta]
|
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
|
||||||
return len(self._data)
|
|
||||||
|
|
||||||
def columnCount(self, parent=QModelIndex()):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.ItemDataRole.EditRole):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
return None
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from PySide6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QHBoxLayout, QPushButton, QFileDialog, \
|
|
||||||
QCheckBox, QComboBox
|
|
||||||
|
|
||||||
|
|
||||||
class ExportKontorDialog(QDialog):
|
|
||||||
def __init__(self, parent=None, kontor_db=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
self.parent = parent
|
|
||||||
self.kontor_db = kontor_db
|
|
||||||
self.file_name = "data.json"
|
|
||||||
self.tables = []
|
|
||||||
self._table_options = {}
|
|
||||||
|
|
||||||
self.export_options = {"JSON": {"ext": ".json"}, "YAML": {"ext": ".yaml"}, "SQLite": {"ext": ".db"}}
|
|
||||||
self.current_export_type = "JSON"
|
|
||||||
|
|
||||||
buttons = (QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
||||||
|
|
||||||
self.buttonBox = QDialogButtonBox(buttons)
|
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
|
|
||||||
self.label = QLabel()
|
|
||||||
self.label.setText("Export DB to data.json")
|
|
||||||
|
|
||||||
self.combo_box = QComboBox()
|
|
||||||
self.combo_box.addItems(["JSON", "YAML", "SQLite"])
|
|
||||||
self.combo_box.currentTextChanged.connect(self.change_export_type)
|
|
||||||
file_layout = QHBoxLayout()
|
|
||||||
file_layout.addWidget(self.label)
|
|
||||||
file_layout.addWidget(self.combo_box)
|
|
||||||
file_button = QPushButton("Select file")
|
|
||||||
file_button.clicked.connect(self.select_file)
|
|
||||||
file_layout.addWidget(file_button)
|
|
||||||
layout.addLayout(file_layout)
|
|
||||||
|
|
||||||
for table_name in self.kontor_db.get_table_names():
|
|
||||||
check_box = QCheckBox(table_name)
|
|
||||||
check_box.setChecked(True)
|
|
||||||
self.tables.append(table_name)
|
|
||||||
self._table_options[table_name] = check_box
|
|
||||||
check_box.stateChanged.connect(self.change_selection)
|
|
||||||
layout.addWidget(check_box)
|
|
||||||
layout.addWidget(self.buttonBox)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def change_selection(self):
|
|
||||||
self.tables.clear()
|
|
||||||
for (name, box) in self._table_options.items():
|
|
||||||
if box.isChecked():
|
|
||||||
self.tables.append(name)
|
|
||||||
|
|
||||||
def change_export_type(self, text):
|
|
||||||
self.current_export_type = text
|
|
||||||
self.label.setText(f'Export DB to data.{self.export_options[text]["ext"]}')
|
|
||||||
|
|
||||||
def select_file(self):
|
|
||||||
file_dialog = QFileDialog()
|
|
||||||
file_dialog.setFileMode(QFileDialog.FileMode.AnyFile)
|
|
||||||
file_dialog.setDefaultSuffix(self.export_options[self.current_export_type]["ext"])
|
|
||||||
file_dialog.setNameFilter(f'*{self.export_options[self.current_export_type]["ext"]}')
|
|
||||||
if file_dialog.exec():
|
|
||||||
self.file_name = file_dialog.selectedFiles()[0]
|
|
||||||
export_file = Path(self.file_name)
|
|
||||||
self.file_name = export_file.with_suffix(self.export_options[self.current_export_type]["ext"])
|
|
||||||
self.label.setText(f"Export DB to {self.file_name}")
|
|
||||||
|
|
||||||
def get_tables_to_export(self) -> list:
|
|
||||||
return self.tables
|
|
||||||
|
|
||||||
|
|
||||||
class ImportKontorDialog(QDialog):
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
self.file_name = None
|
|
||||||
|
|
||||||
QBtn = (QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
||||||
|
|
||||||
self.buttonBox = QDialogButtonBox(QBtn)
|
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
self.label = QLabel()
|
|
||||||
self.label.setText("Import DB from data.json")
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
file_layout = QHBoxLayout()
|
|
||||||
file_layout.addWidget(self.label)
|
|
||||||
file_button = QPushButton("Select file")
|
|
||||||
file_button.clicked.connect(self.select_file)
|
|
||||||
file_layout.addWidget(file_button)
|
|
||||||
layout.addLayout(file_layout)
|
|
||||||
layout.addWidget(self.buttonBox)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def select_file(self):
|
|
||||||
file_dialog = QFileDialog()
|
|
||||||
file_dialog.setFileMode(QFileDialog.FileMode.ExistingFile)
|
|
||||||
if file_dialog.exec():
|
|
||||||
self.file_name = file_dialog.selectedFiles()[0]
|
|
||||||
self.label.setText(f"Import DB from {self.file_name}")
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
from PySide6.QtCore import Qt
|
|
||||||
from PySide6.QtGui import QAction, QIcon, QGuiApplication
|
|
||||||
from PySide6.QtWidgets import QMenu, QMessageBox, QProgressBar, QMdiArea
|
|
||||||
from PySide6.QtWidgets import QLabel, QMainWindow
|
|
||||||
from sqlalchemy import Engine
|
|
||||||
from kontor_schema import KontorDB
|
|
||||||
|
|
||||||
from .comic_window import ComicWindow
|
|
||||||
from .media_window import MediaWindow
|
|
||||||
from .meta_data_window import MetaDataWindow
|
|
||||||
from .progress import ProgressUpdate
|
|
||||||
from .dialogs import ExportKontorDialog, ImportKontorDialog
|
|
||||||
from .worker import VideoDownloader
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
|
||||||
|
|
||||||
def __init__(self, engine: Engine, log):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.downloader = None
|
|
||||||
self.tick = QIcon('res/tick.png')
|
|
||||||
self.cross = QIcon('res/cross.png')
|
|
||||||
self.import_icon = QIcon("res/application-import.png")
|
|
||||||
self.export_icon = QIcon("res/application-export.png")
|
|
||||||
self.circle_icon = QIcon("res/arrow-circle-double.png")
|
|
||||||
|
|
||||||
self.data = []
|
|
||||||
self.filter = {}
|
|
||||||
self.kontor_db = KontorDB(engine, log)
|
|
||||||
self.log = log
|
|
||||||
self._subwindows = {}
|
|
||||||
self.media_dir = "/data/media"
|
|
||||||
self.dl_tool = "yt-dlp"
|
|
||||||
|
|
||||||
self._setup_ui()
|
|
||||||
|
|
||||||
def _setup_ui(self):
|
|
||||||
self.setWindowTitle("Kontor")
|
|
||||||
self.setMinimumSize(1200, 800)
|
|
||||||
self._create_actions()
|
|
||||||
self.mdi_area = QMdiArea()
|
|
||||||
self.setCentralWidget(self.mdi_area)
|
|
||||||
self.mdi_area.setObjectName('mdi_area')
|
|
||||||
self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
|
||||||
self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
|
||||||
self._create_menubar()
|
|
||||||
self._create_toolbars()
|
|
||||||
self.status_progress = QProgressBar()
|
|
||||||
self.progress_update = ProgressUpdate(self.status_progress)
|
|
||||||
self._create_statusbar()
|
|
||||||
center_point = QGuiApplication.screens()[0].geometry().center()
|
|
||||||
self.move(center_point - self.frameGeometry().center())
|
|
||||||
|
|
||||||
def _create_actions(self):
|
|
||||||
self.newAction = QAction("&New", self)
|
|
||||||
self.aboutAction = QAction("&Über...", self)
|
|
||||||
self.aboutAction.triggered.connect(self.about)
|
|
||||||
self.showComicWindow = QAction("&Comic Window", self)
|
|
||||||
self.showComicWindow.triggered.connect(self.show_comic_window)
|
|
||||||
self.showTyscWindow = QAction("TYSC Window", self)
|
|
||||||
self.showMediaWindow = QAction("&Media Window", self)
|
|
||||||
self.showMediaWindow.triggered.connect(self.show_media_window)
|
|
||||||
self.showMetaDataWindow = QAction("Meta Data Window", self)
|
|
||||||
self.showMetaDataWindow.triggered.connect(self.show_meta_data_window)
|
|
||||||
self.importAction = QAction(self.import_icon, "&Import", self)
|
|
||||||
self.importAction.triggered.connect(self.import_from_file)
|
|
||||||
self.exportAction = QAction(self.export_icon, "&Export", self)
|
|
||||||
self.exportAction.triggered.connect(self.export_to_file)
|
|
||||||
self.refreshAction = QAction(self.circle_icon, "&Refresh", self)
|
|
||||||
self.refreshAction.triggered.connect(self.refresh)
|
|
||||||
self.updateTitleAction = QAction("&Update Titles", self)
|
|
||||||
self.updateTitleAction.triggered.connect(self.update_title)
|
|
||||||
self.downloadAction = QAction("&Download Videos", self)
|
|
||||||
self.downloadAction.triggered.connect(self.start_download)
|
|
||||||
self.checkFileAction = QAction("&Check files", self)
|
|
||||||
self.checkFileAction.triggered.connect(self.check_files)
|
|
||||||
self.exitAction = QAction("&Beenden", self)
|
|
||||||
self.exitAction.setShortcut("Alt+F4")
|
|
||||||
self.exitAction.triggered.connect(self.close)
|
|
||||||
|
|
||||||
def _create_menubar(self):
|
|
||||||
menu_bar = self.menuBar()
|
|
||||||
# File menu
|
|
||||||
file_menu = QMenu("&Datei")
|
|
||||||
menu_bar.addMenu(file_menu)
|
|
||||||
file_menu.addAction(self.exitAction)
|
|
||||||
# Kontor menu
|
|
||||||
kontor_menu = QMenu("&Kontor")
|
|
||||||
menu_bar.addMenu(kontor_menu)
|
|
||||||
kontor_menu.addAction(self.importAction)
|
|
||||||
kontor_menu.addAction(self.exportAction)
|
|
||||||
comic_menu = QMenu("&Comic")
|
|
||||||
comic_menu.addAction(self.showComicWindow)
|
|
||||||
tysc_menu = QMenu("&TradeYourSportCards")
|
|
||||||
media_file_menu = QMenu("&MediaFile")
|
|
||||||
media_file_menu.addAction(self.updateTitleAction)
|
|
||||||
media_file_menu.addAction(self.downloadAction)
|
|
||||||
media_file_menu.addAction(self.checkFileAction)
|
|
||||||
kontor_menu.addMenu(comic_menu)
|
|
||||||
kontor_menu.addMenu(tysc_menu)
|
|
||||||
kontor_menu.addMenu(media_file_menu)
|
|
||||||
window_menu = QMenu("&Window")
|
|
||||||
layouts_menu = QMenu("&Layouts")
|
|
||||||
window_menu.addMenu(layouts_menu)
|
|
||||||
window_menu.addAction(self.showComicWindow)
|
|
||||||
window_menu.addAction(self.showMediaWindow)
|
|
||||||
window_menu.addAction(self.showMetaDataWindow)
|
|
||||||
menu_bar.addMenu(window_menu)
|
|
||||||
# Help menu
|
|
||||||
help_menu = QMenu("&Hilfe")
|
|
||||||
menu_bar.addMenu(help_menu)
|
|
||||||
help_menu.addAction(self.aboutAction)
|
|
||||||
|
|
||||||
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 _create_statusbar(self):
|
|
||||||
self.statusBar = self.statusBar()
|
|
||||||
self.statusBar.showMessage("Kontor ready", 6000)
|
|
||||||
self.status_label = QLabel("")
|
|
||||||
self.status_progress.setEnabled(False)
|
|
||||||
self.statusBar.addPermanentWidget(self.status_progress)
|
|
||||||
|
|
||||||
def about(self):
|
|
||||||
QMessageBox.about(self, "Über Kontor", "Python: 3.11\nKontor: 0.1.0")
|
|
||||||
|
|
||||||
def show_comic_window(self):
|
|
||||||
if 'comic' not in self._subwindows:
|
|
||||||
comic = ComicWindow(self)
|
|
||||||
comic.closed.connect(self.sub_window_closed)
|
|
||||||
self._subwindows['comic'] = comic
|
|
||||||
self.mdi_area.addSubWindow(comic)
|
|
||||||
comic.show()
|
|
||||||
else:
|
|
||||||
comic = self._subwindows.pop('comic')
|
|
||||||
comic.close()
|
|
||||||
self.mdi_area.removeSubWindow(comic)
|
|
||||||
|
|
||||||
def show_media_window(self):
|
|
||||||
if 'media' not in self._subwindows:
|
|
||||||
media = MediaWindow(self)
|
|
||||||
media.closed.connect(self.sub_window_closed)
|
|
||||||
self._subwindows['media'] = media
|
|
||||||
self.mdi_area.addSubWindow(media)
|
|
||||||
media.show()
|
|
||||||
else:
|
|
||||||
media = self._subwindows.pop('media')
|
|
||||||
media.close()
|
|
||||||
self.mdi_area.removeSubWindow(media)
|
|
||||||
|
|
||||||
def show_meta_data_window(self):
|
|
||||||
if 'meta_data' not in self._subwindows:
|
|
||||||
meta_data = MetaDataWindow(self)
|
|
||||||
meta_data.closed.connect(self.sub_window_closed)
|
|
||||||
self._subwindows['meta_data'] = meta_data
|
|
||||||
self.mdi_area.addSubWindow(meta_data)
|
|
||||||
meta_data.show()
|
|
||||||
else:
|
|
||||||
meta_data = self._subwindows.pop('meta_data')
|
|
||||||
meta_data.close()
|
|
||||||
self.mdi_area.removeSubWindow(meta_data)
|
|
||||||
|
|
||||||
def remove_sub_window(self, name: str):
|
|
||||||
self.log.info("remove subwindow %s", name)
|
|
||||||
if name in self._subwindows:
|
|
||||||
window = self._subwindows.pop(name)
|
|
||||||
window.close()
|
|
||||||
self.mdi_area.removeSubWindow(window)
|
|
||||||
|
|
||||||
def sub_window_closed(self):
|
|
||||||
self.log.info("close subwindow")
|
|
||||||
|
|
||||||
def import_from_file(self):
|
|
||||||
import_dlg = ImportKontorDialog(self)
|
|
||||||
if import_dlg.exec():
|
|
||||||
print(f"import DB from file {import_dlg.file_name}")
|
|
||||||
self.kontor_db.import_db(import_dlg.file_name)
|
|
||||||
else:
|
|
||||||
print("do nothing for import")
|
|
||||||
|
|
||||||
def export_to_file(self):
|
|
||||||
export_dlg = ExportKontorDialog(self, self.kontor_db)
|
|
||||||
if export_dlg.exec():
|
|
||||||
self.log.info(export_dlg.get_tables_to_export())
|
|
||||||
self.log.info(f"export DB to {export_dlg.file_name}")
|
|
||||||
self.statusBar.showMessage(f"export DB to {export_dlg.file_name}", 3000)
|
|
||||||
self.kontor_db.export_db(export_dlg.current_export_type, export_dlg.file_name)
|
|
||||||
else:
|
|
||||||
self.statusBar.showMessage("Export cancelled", 3000)
|
|
||||||
|
|
||||||
def update_title(self):
|
|
||||||
self.log.info("update title for table MediaFile")
|
|
||||||
self.statusBar.showMessage("update title for table MediaFile", 3000)
|
|
||||||
self.status_progress.setEnabled(True)
|
|
||||||
self.kontor_db.update_titles()
|
|
||||||
self.status_progress.setEnabled(False)
|
|
||||||
self.refresh()
|
|
||||||
|
|
||||||
def start_download(self):
|
|
||||||
self.status_progress.setEnabled(True)
|
|
||||||
self.statusBar.showMessage("download videos for table MediaFile", 3000)
|
|
||||||
self.downloader = VideoDownloader(self.kontor_db, self.log)
|
|
||||||
self.downloader.setTotalProgress.connect(self.status_progress.setMaximum)
|
|
||||||
self.downloader.setCurrentProgress.connect(self.downloadProgress)
|
|
||||||
self.downloader.succeeded.connect(self.downloadSucceeded)
|
|
||||||
self.downloader.finished.connect(self.downloadFinished)
|
|
||||||
self.downloader.start()
|
|
||||||
|
|
||||||
def downloadProgress(self, value: int):
|
|
||||||
self.status_progress.setValue(value)
|
|
||||||
self.refresh()
|
|
||||||
|
|
||||||
def downloadSucceeded(self):
|
|
||||||
self.status_progress.setValue(self.status_progress.maximum())
|
|
||||||
self.statusBar.showMessage("Download succeeded", 3000)
|
|
||||||
|
|
||||||
def downloadFinished(self):
|
|
||||||
self.status_progress.setEnabled(False)
|
|
||||||
del self.downloader
|
|
||||||
|
|
||||||
def check_files(self):
|
|
||||||
self.log.info("check files")
|
|
||||||
self.statusBar.showMessage("check files for table MediaFile", 3000)
|
|
||||||
self.kontor_db.check_files()
|
|
||||||
|
|
||||||
def refresh(self):
|
|
||||||
self.log.info("refresh")
|
|
||||||
for (_, window) in self._subwindows.items():
|
|
||||||
window.refresh()
|
|
||||||
|
|
||||||
def update_status(self, message, timeout=3000):
|
|
||||||
self.statusBar.showMessage(message, timeout=timeout)
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
from PySide6.QtCore import Signal, QSortFilterProxyModel
|
|
||||||
from PySide6.QtWidgets import QMdiSubWindow, QWidget, QVBoxLayout, QTabWidget, QTableView
|
|
||||||
|
|
||||||
from .model_config import KontorModelConfig
|
|
||||||
from .table_details import KontorTableDetailsView
|
|
||||||
from .table_model import KontorTableModel
|
|
||||||
|
|
||||||
|
|
||||||
class MediaWindow(QMdiSubWindow):
|
|
||||||
closed = Signal()
|
|
||||||
|
|
||||||
def __init__(self, main_window):
|
|
||||||
super().__init__()
|
|
||||||
self.data_views = list()
|
|
||||||
self._main_window = main_window
|
|
||||||
self.log = main_window.log
|
|
||||||
self._init_gui()
|
|
||||||
self.tick = main_window.tick
|
|
||||||
self.cross = main_window.cross
|
|
||||||
|
|
||||||
def _init_gui(self):
|
|
||||||
self.setWindowTitle("Media")
|
|
||||||
self.setWidget(QWidget())
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.tabs = QTabWidget()
|
|
||||||
self.tabs.addTab(self.generate_data_tab("media_file"), "Media File")
|
|
||||||
self.tabs.addTab(self.generate_data_tab("media_video"), "Media Video")
|
|
||||||
self.tabs.addTab(self.generate_data_tab("media_article"), "Media Article")
|
|
||||||
self.tabs.addTab(self.generate_data_tab_with_details("media_actor"), "Media Actor")
|
|
||||||
self.tabs.currentChanged.connect(self._tab_changed)
|
|
||||||
layout.addWidget(self.tabs)
|
|
||||||
self.setLayout(layout)
|
|
||||||
self.setWidget(self.tabs)
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
self.closed.emit()
|
|
||||||
super().closeEvent(event)
|
|
||||||
self._main_window.remove_sub_window('media')
|
|
||||||
|
|
||||||
def refresh(self):
|
|
||||||
self.log.info("MediaWindow.refresh")
|
|
||||||
self.data_views[self.tabs.currentIndex()].refresh()
|
|
||||||
|
|
||||||
def _tab_changed(self, tab_index):
|
|
||||||
self.data_views[tab_index].refresh()
|
|
||||||
|
|
||||||
def update_status(self, message):
|
|
||||||
self._main_window.update_status(message)
|
|
||||||
|
|
||||||
def generate_data_tab(self, table_name):
|
|
||||||
data_tab = QWidget()
|
|
||||||
|
|
||||||
table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name)
|
|
||||||
model = KontorTableModel(table_config)
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.data_views.append(model)
|
|
||||||
data_tab.setLayout(layout)
|
|
||||||
table_view = QTableView()
|
|
||||||
proxy_model = QSortFilterProxyModel()
|
|
||||||
proxy_model.setSourceModel(model)
|
|
||||||
table_view.setSortingEnabled(True)
|
|
||||||
table_view.setModel(proxy_model)
|
|
||||||
layout.addLayout(table_config.get_filter_layout())
|
|
||||||
layout.addWidget(table_view)
|
|
||||||
model.refresh()
|
|
||||||
table_view.resizeColumnToContents(0)
|
|
||||||
return data_tab
|
|
||||||
|
|
||||||
def generate_data_tab_with_details(self, table_name):
|
|
||||||
table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name)
|
|
||||||
model = KontorTableModel(table_config)
|
|
||||||
self.data_views.append(model)
|
|
||||||
details_view = KontorTableDetailsView(model)
|
|
||||||
return details_view.data_view
|
|
||||||
|
|
||||||
def cell_selected(self, item):
|
|
||||||
self.log.info(f"Cell {item.row()}:{item.column()} clicked")
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
from PySide6.QtCore import Signal, QSortFilterProxyModel
|
|
||||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QTableView, QMdiSubWindow
|
|
||||||
|
|
||||||
from gui.model_config import KontorModelConfig
|
|
||||||
from gui.table_model import KontorTableModel
|
|
||||||
|
|
||||||
|
|
||||||
class MetaDataWindow(QMdiSubWindow):
|
|
||||||
closed = Signal()
|
|
||||||
|
|
||||||
def __init__(self, main_window):
|
|
||||||
super().__init__()
|
|
||||||
self.data_views = list()
|
|
||||||
self._main_window = main_window
|
|
||||||
self.log = main_window.log
|
|
||||||
self._init_gui()
|
|
||||||
self.tick = main_window.tick
|
|
||||||
self.cross = main_window.cross
|
|
||||||
|
|
||||||
def _init_gui(self):
|
|
||||||
self.setWindowTitle("Meta Data")
|
|
||||||
self.setWidget(QWidget())
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.tabs = QTabWidget()
|
|
||||||
self.tabs.addTab(self.generate_data_tab("module_data"), "Module")
|
|
||||||
self.tabs.addTab(self.generate_data_tab("meta_data_table"), "Tables")
|
|
||||||
self.tabs.addTab(self.generate_data_tab("meta_data_column"), "Columns")
|
|
||||||
self.tabs.currentChanged.connect(self._tab_changed)
|
|
||||||
layout.addWidget(self.tabs)
|
|
||||||
self.setLayout(layout)
|
|
||||||
self.setWidget(self.tabs)
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
self.closed.emit()
|
|
||||||
super().closeEvent(event)
|
|
||||||
self._main_window.remove_sub_window('meta_data')
|
|
||||||
|
|
||||||
def refresh(self):
|
|
||||||
# self.log.info("refresh")
|
|
||||||
self.data_views[self.tabs.currentIndex()].refresh()
|
|
||||||
|
|
||||||
def _tab_changed(self, tab_index):
|
|
||||||
self.data_views[tab_index].refresh()
|
|
||||||
|
|
||||||
def update_status(self, message):
|
|
||||||
self._main_window.update_status(message)
|
|
||||||
|
|
||||||
def generate_data_tab(self, table_name):
|
|
||||||
data_tab = QWidget()
|
|
||||||
table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name)
|
|
||||||
model = KontorTableModel(table_config)
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self.data_views.append(model)
|
|
||||||
data_tab.setLayout(layout)
|
|
||||||
table_view = QTableView()
|
|
||||||
# header = table_view.horizontalHeader()
|
|
||||||
# header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
|
|
||||||
proxy_model = QSortFilterProxyModel()
|
|
||||||
proxy_model.setSourceModel(model)
|
|
||||||
table_view.setSortingEnabled(True)
|
|
||||||
table_view.setModel(proxy_model)
|
|
||||||
layout.addLayout(table_config.get_filter_layout())
|
|
||||||
layout.addWidget(table_view)
|
|
||||||
model.refresh()
|
|
||||||
table_view.resizeColumnToContents(0)
|
|
||||||
return data_tab
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
from PySide6.QtWidgets import QHBoxLayout, QCheckBox
|
|
||||||
from kontor_schema import KontorDB, ColumnEntry
|
|
||||||
|
|
||||||
|
|
||||||
class KontorModelConfig:
|
|
||||||
|
|
||||||
def __init__(self, kontor_db: KontorDB, main_window, table_name: str):
|
|
||||||
self.header = {}
|
|
||||||
self.filter = {}
|
|
||||||
self.main_window = main_window
|
|
||||||
self.log = main_window.log
|
|
||||||
self._table_name = table_name
|
|
||||||
self.kontor_db = kontor_db
|
|
||||||
self.get_table_config()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"KontorModelConfig({self._table_name})"
|
|
||||||
|
|
||||||
def get_table_config(self):
|
|
||||||
# self.log.info("get_table_config %s", self)
|
|
||||||
self.header = self.kontor_db.get_column_meta_data(self._table_name)
|
|
||||||
self.filter = self.kontor_db.get_filters(self._table_name)
|
|
||||||
# self.log.info("headers: %s", self.header)
|
|
||||||
# self.log.info("%s filters: %s", self, self.filter)
|
|
||||||
|
|
||||||
def filters(self) -> dict:
|
|
||||||
# self.log.info("%s filters: %s", self, self.filter)
|
|
||||||
_filters = {}
|
|
||||||
# print(self.filter["download"].isChecked())
|
|
||||||
for column, filter_info in self.filter.items():
|
|
||||||
# print(column, filter_info)
|
|
||||||
if filter_info[ColumnEntry.COLUMN_WIDGET].isChecked():
|
|
||||||
_filters[column] = True
|
|
||||||
# print(f"{filter_rule=}")
|
|
||||||
# self.log.info("filters -> %s", _filters)
|
|
||||||
return _filters
|
|
||||||
|
|
||||||
def get_data(self) -> list:
|
|
||||||
# self.log.info("get_data")
|
|
||||||
data = self.kontor_db.data(self._table_name, self.header, self.filters())
|
|
||||||
# self.log.info("get_data: %d %s", len(data), data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_filter_layout(self) -> QHBoxLayout:
|
|
||||||
# self.log.info("get_filter_layout: %s", self.filter)
|
|
||||||
filter_layout = QHBoxLayout()
|
|
||||||
for column, filter_info in self.filter.items():
|
|
||||||
filter_checkbox = QCheckBox()
|
|
||||||
filter_checkbox.setText(filter_info[ColumnEntry.COLUMN_LABEL])
|
|
||||||
filter_checkbox.checkStateChanged.connect(self.main_window.refresh)
|
|
||||||
self.filter[column][ColumnEntry.COLUMN_WIDGET] = filter_checkbox
|
|
||||||
filter_layout.addWidget(filter_checkbox)
|
|
||||||
filter_layout.addStretch()
|
|
||||||
# self.log.info("get_filter_layout: %s", self.filter)
|
|
||||||
return filter_layout
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
from PySide6.QtWidgets import QProgressBar
|
|
||||||
|
|
||||||
|
|
||||||
class ProgressUpdate:
|
|
||||||
def __init__(self, progress: QProgressBar):
|
|
||||||
self.start = 0
|
|
||||||
self.end = 0
|
|
||||||
self.current = 0
|
|
||||||
self.progress = progress
|
|
||||||
|
|
||||||
def start(self, start_value, end_value):
|
|
||||||
self.start = start_value
|
|
||||||
self.end = end_value
|
|
||||||
self.current = start_value
|
|
||||||
self.progress.update()
|
|
||||||
|
|
||||||
def update(self, current):
|
|
||||||
self.progress.update()
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
from PySide6.QtCore import QSortFilterProxyModel
|
|
||||||
from PySide6.QtWidgets import QHBoxLayout, QWidget, QTableView, QVBoxLayout, QFormLayout, QLineEdit, QLabel
|
|
||||||
|
|
||||||
from .table_model import KontorTableModel
|
|
||||||
|
|
||||||
|
|
||||||
class KontorTableDetailsView:
|
|
||||||
def __init__(self, table_model: KontorTableModel):
|
|
||||||
self._data_view: QWidget = QWidget()
|
|
||||||
self._model = table_model
|
|
||||||
self.log = table_model.log
|
|
||||||
self._table_view = QTableView()
|
|
||||||
self._label = QLabel()
|
|
||||||
self.init_gui()
|
|
||||||
|
|
||||||
def init_gui(self):
|
|
||||||
self.log.info("KontorTableDetailsView.init_gui()")
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
self._data_view.setLayout(layout)
|
|
||||||
details_layout = QHBoxLayout()
|
|
||||||
table_with_details = QWidget()
|
|
||||||
table_with_details.setLayout(details_layout)
|
|
||||||
|
|
||||||
self._table_view.setSelectionBehavior(QTableView.SelectionBehavior.SelectRows)
|
|
||||||
proxy_model = QSortFilterProxyModel()
|
|
||||||
proxy_model.setSourceModel(self._model)
|
|
||||||
self._table_view.setSortingEnabled(True)
|
|
||||||
self._table_view.setModel(proxy_model)
|
|
||||||
self._table_view.clicked.connect(self.update_details)
|
|
||||||
self._table_view.activated.connect(self.refresh_details)
|
|
||||||
|
|
||||||
layout.addLayout(self._model.config.get_filter_layout())
|
|
||||||
details_layout.addWidget(self._table_view)
|
|
||||||
|
|
||||||
form = QWidget()
|
|
||||||
form_layout = QFormLayout(form)
|
|
||||||
form.setLayout(form_layout)
|
|
||||||
|
|
||||||
title = QLineEdit(form)
|
|
||||||
form_layout.addRow("ID", self._label)
|
|
||||||
form_layout.addRow("Title", title)
|
|
||||||
# layout.addWidget(table_view)
|
|
||||||
details_layout.addWidget(form)
|
|
||||||
layout.addWidget(table_with_details)
|
|
||||||
self._model.refresh()
|
|
||||||
self._table_view.resizeColumnToContents(0)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def data_view(self):
|
|
||||||
return self._data_view
|
|
||||||
|
|
||||||
def update_details(self, item):
|
|
||||||
print(f"Cell {item.row()}-{item.column()} selected")
|
|
||||||
self.log.info(f"Cell {item.row()}-{item.column()} selected")
|
|
||||||
self._label.setText(self._model.raw_data()[item.row()][0])
|
|
||||||
|
|
||||||
def refresh_details(self):
|
|
||||||
indexes = self._table_view.selectedIndexes()
|
|
||||||
for index in indexes:
|
|
||||||
self.log.info(f"refresh_details: Cell {index.row()}-{index.column()} selected")
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from PySide6.QtCore import QAbstractTableModel, QModelIndex
|
|
||||||
from PySide6.QtGui import Qt, QColor
|
|
||||||
from kontor_schema.database import ColumnEntry
|
|
||||||
|
|
||||||
from .model_config import KontorModelConfig
|
|
||||||
|
|
||||||
|
|
||||||
def get_display_value(value: Any, column_config: dict, window) -> str:
|
|
||||||
if isinstance(value, datetime):
|
|
||||||
return value.strftime("%Y-%m-%d %M:%M:%S")
|
|
||||||
if column_config[ColumnEntry.COLUMN_TYPE] == 'BOOLEAN':
|
|
||||||
if value == 1:
|
|
||||||
return window.tick
|
|
||||||
else:
|
|
||||||
return window.cross
|
|
||||||
if value is None:
|
|
||||||
return ""
|
|
||||||
# window.log.info(f"unknown type: {column_config[ColumnEntry.COLUMN_TYPE]} - {type(value)}")
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
|
|
||||||
def get_edit_value(value, column_config, window):
|
|
||||||
# window.log.info(f"edit value {value}")
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
|
|
||||||
def get_decoration_value(value: Any, column_config: dict, window):
|
|
||||||
if column_config[ColumnEntry.COLUMN_TYPE] == 'BOOLEAN':
|
|
||||||
if value == 1:
|
|
||||||
return window.tick
|
|
||||||
else:
|
|
||||||
return window.cross
|
|
||||||
|
|
||||||
|
|
||||||
def get_background_value(value: Any, column_config: dict, window):
|
|
||||||
if value is None:
|
|
||||||
return QColor('lightgrey')
|
|
||||||
|
|
||||||
|
|
||||||
class KontorTableModel(QAbstractTableModel):
|
|
||||||
|
|
||||||
def __init__(self, model_config: KontorModelConfig):
|
|
||||||
super().__init__()
|
|
||||||
self._main_window = model_config.main_window
|
|
||||||
self._config = model_config
|
|
||||||
self._data = []
|
|
||||||
self.log = model_config.log
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"KontorTableModel({self._config})"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def config(self):
|
|
||||||
return self._config
|
|
||||||
|
|
||||||
@property
|
|
||||||
def raw_data(self):
|
|
||||||
return self._data
|
|
||||||
|
|
||||||
def refresh(self):
|
|
||||||
# self.log.info("refresh")
|
|
||||||
data = self._config.get_data()
|
|
||||||
count = 0
|
|
||||||
# print(data)
|
|
||||||
if data is not None:
|
|
||||||
self.beginResetModel()
|
|
||||||
self._data.clear()
|
|
||||||
self._data = data
|
|
||||||
self.endResetModel()
|
|
||||||
count = len(data)
|
|
||||||
# print(data)
|
|
||||||
# print(self._data)
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
self._main_window.update_status(f"{count} Einträge geladen")
|
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
|
||||||
# self.log.info("rowCount %s: %d", self, len(self._data))
|
|
||||||
# The length of the outer list.
|
|
||||||
if self._data is None:
|
|
||||||
return 0
|
|
||||||
return len(self._data)
|
|
||||||
|
|
||||||
def headerData(self, col, orientation, role=Qt.ItemDataRole.DisplayRole):
|
|
||||||
# self.log.info(f"{self._config.header[col]}")
|
|
||||||
if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole:
|
|
||||||
return self._config.header[col][ColumnEntry.COLUMN_LABEL]
|
|
||||||
if orientation == Qt.Orientation.Vertical and role == Qt.ItemDataRole.DisplayRole:
|
|
||||||
return str(col + 1)
|
|
||||||
|
|
||||||
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
|
|
||||||
if self._data is None:
|
|
||||||
return None
|
|
||||||
value = self._data[index.row()][index.column()]
|
|
||||||
# print('{}:: {}:: {}:: {}: {}'.format(index, role, self._config.header[index.column()][ColumnEntry.COLUMN_TYPE], value, type(value)))
|
|
||||||
match role:
|
|
||||||
case Qt.ItemDataRole.DisplayRole:
|
|
||||||
return get_display_value(value, self._config.header[index.column()], self._config.main_window)
|
|
||||||
case Qt.ItemDataRole.EditRole:
|
|
||||||
return get_edit_value(value, self._config.header[index.column()], self._config.main_window)
|
|
||||||
case Qt.ItemDataRole.DecorationRole:
|
|
||||||
return get_decoration_value(value, self._config.header[index.column()], self._config.main_window)
|
|
||||||
case Qt.ItemDataRole.BackgroundRole:
|
|
||||||
return get_background_value(value, self._config.header[index.column()], self._config.main_window)
|
|
||||||
|
|
||||||
def columnCount(self, index=QModelIndex()):
|
|
||||||
# self.log.info("rowCount %s: %d", self, len(self._config.header))
|
|
||||||
return len(self._config.header)
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.ItemDataRole.EditRole) -> bool:
|
|
||||||
# self._config.log.info(f"{index}: {role}")
|
|
||||||
if role == Qt.ItemDataRole.EditRole:
|
|
||||||
self._data[index.row()][index.column()] = value
|
|
||||||
# self._config.log.info(f"{index.row()}-{index.column()}: {self._data[index.row()][index.column()]}")
|
|
||||||
self.dataChanged.emit(index, index)
|
|
||||||
return True
|
|
||||||
if role == Qt.ItemDataRole.CheckStateRole:
|
|
||||||
print("role == Qt.ItemDataRole.CheckStateRole")
|
|
||||||
checked = value == Qt.CheckState.Checked
|
|
||||||
self._data[index.row()][index.column()] = checked
|
|
||||||
return False
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
if self._config.header[index.column()][ColumnEntry.COLUMN_NAME] == 'id':
|
|
||||||
return Qt.ItemFlag.ItemIsEnabled
|
|
||||||
return Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsUserTristate
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
from PySide6.QtCore import Signal, QThread
|
|
||||||
|
|
||||||
|
|
||||||
class VideoDownloader(QThread):
|
|
||||||
# Signal for the window to establish the maximum value
|
|
||||||
# of the progress bar.
|
|
||||||
setTotalProgress = Signal(int)
|
|
||||||
# Signal to increase the progress.
|
|
||||||
setCurrentProgress = Signal(int)
|
|
||||||
# Signal to be emitted when the file has been downloaded successfully.
|
|
||||||
succeeded = Signal()
|
|
||||||
|
|
||||||
def __init__(self, kontor_db, log):
|
|
||||||
super().__init__()
|
|
||||||
self.kontor_db = kontor_db
|
|
||||||
self.log = log
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.log.info("download videos for table MediaFile")
|
|
||||||
download_entries = self.kontor_db.get_download_list()
|
|
||||||
self.setTotalProgress.emit(len(download_entries))
|
|
||||||
for index, entry in enumerate(download_entries):
|
|
||||||
self.kontor_db.download_file(entry)
|
|
||||||
self.setCurrentProgress.emit(index)
|
|
||||||
self.succeeded.emit()
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
"""
|
|
||||||
PySide6 GUI for Kontor
|
|
||||||
"""
|
|
||||||
import sys
|
|
||||||
import logging.config
|
|
||||||
from pathlib import Path
|
|
||||||
from platformdirs import PlatformDirs
|
|
||||||
from PySide6.QtWidgets import QApplication
|
|
||||||
import yaml
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
from sqlalchemy.orm import sessionmaker
|
|
||||||
from kontor_schema.base import Base
|
|
||||||
|
|
||||||
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
|
||||||
from gui.main_window import MainWindow
|
|
||||||
|
|
||||||
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
|
|
||||||
parser.add_argument('--verbose', '-v', action='count', default=0)
|
|
||||||
parser.add_argument('--config', '-c', default='kontor-docker')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
dirs = PlatformDirs(args.config)
|
|
||||||
database_config = Path(dirs.user_config_dir, 'database-config.yaml')
|
|
||||||
with open(database_config, 'rt') as f:
|
|
||||||
db_config = yaml.safe_load(f.read())
|
|
||||||
connect_string = ('mariadb+mariadbconnector://{}:{}@{}:{}/{}'.format(
|
|
||||||
db_config['mariadb']['user'],
|
|
||||||
db_config['mariadb']['password'],
|
|
||||||
db_config['mariadb']['host'],
|
|
||||||
db_config['mariadb']['port'],
|
|
||||||
db_config['mariadb']['database']
|
|
||||||
))
|
|
||||||
logging_config = Path(dirs.user_config_dir, 'logging-config.yaml')
|
|
||||||
with open(logging_config, 'rt') as f:
|
|
||||||
config = yaml.safe_load(f.read())
|
|
||||||
logging.config.dictConfig(config)
|
|
||||||
logger = logging.getLogger('development')
|
|
||||||
# engine = create_engine(connect_string, echo=True)
|
|
||||||
engine = create_engine(connect_string)
|
|
||||||
Base.metadata.create_all(bind=engine, checkfirst=True)
|
|
||||||
__session__ = sessionmaker(bind=engine)
|
|
||||||
|
|
||||||
window = MainWindow(engine, logger)
|
|
||||||
window.show()
|
|
||||||
app.exec()
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
[project]
|
|
||||||
name = "kontor-gui"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "Kontor GUI"
|
|
||||||
authors = [
|
|
||||||
{name = "Thomas Peetz", email = "thomas.peetz@thpeetz.de"},
|
|
||||||
]
|
|
||||||
dependencies = [
|
|
||||||
"platformdirs",
|
|
||||||
"pyyaml",
|
|
||||||
"PySide6",
|
|
||||||
]
|
|
||||||
requires-python = ">=3.11"
|
|
||||||
readme = "README.md"
|
|
||||||
license = {text = "MIT"}
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["pdm-backend"]
|
|
||||||
build-backend = "pdm.backend"
|
|
||||||
|
|
||||||
|
|
||||||
[tool.pdm]
|
|
||||||
distribution = true
|
|
||||||
|
|
||||||
[dependency-groups]
|
|
||||||
dev = ["-e file:///${PROJECT_ROOT}/../kontor-schema#egg=kontor-schema"]
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
[app]
|
|
||||||
|
|
||||||
# title of your application
|
|
||||||
title = kontor
|
|
||||||
|
|
||||||
# project directory. the general assumption is that project_dir is the parent directory
|
|
||||||
# of input_file
|
|
||||||
project_dir = /home/tpeetz/projects/kontor/python/kontor-gui
|
|
||||||
|
|
||||||
# source file path
|
|
||||||
input_file = /home/tpeetz/projects/kontor/python/kontor-gui/main.py
|
|
||||||
|
|
||||||
# directory where exec is stored
|
|
||||||
exec_directory = .
|
|
||||||
|
|
||||||
# path to .pyproject project file
|
|
||||||
project_file =
|
|
||||||
|
|
||||||
# application icon
|
|
||||||
icon = /usr/local/lib/python3.11/dist-packages/PySide6/scripts/deploy_lib/pyside_icon.jpg
|
|
||||||
|
|
||||||
[python]
|
|
||||||
|
|
||||||
# python path
|
|
||||||
python_path = /home/tpeetz/projects/kontor/python/kontor-gui/env/bin/python
|
|
||||||
|
|
||||||
# python packages to install
|
|
||||||
packages = Nuitka==2.4.8
|
|
||||||
|
|
||||||
# buildozer = for deploying Android application
|
|
||||||
android_packages = buildozer==1.5.0,cython==0.29.33
|
|
||||||
|
|
||||||
[qt]
|
|
||||||
|
|
||||||
# comma separated path to qml files required
|
|
||||||
# normally all the qml files required by the project are added automatically
|
|
||||||
qml_files =
|
|
||||||
|
|
||||||
# excluded qml plugin binaries
|
|
||||||
excluded_qml_plugins =
|
|
||||||
|
|
||||||
# qt modules used. comma separated
|
|
||||||
modules = Widgets,DBus,Core,Gui
|
|
||||||
|
|
||||||
# qt plugins used by the application
|
|
||||||
plugins = platformthemes,imageformats,platforms,generic,iconengines,egldeviceintegrations,styles,xcbglintegrations,platforms/darwin,platforminputcontexts,accessiblebridge
|
|
||||||
|
|
||||||
[android]
|
|
||||||
|
|
||||||
# path to pyside wheel
|
|
||||||
wheel_pyside =
|
|
||||||
|
|
||||||
# path to shiboken wheel
|
|
||||||
wheel_shiboken =
|
|
||||||
|
|
||||||
# plugins to be copied to libs folder of the packaged application. comma separated
|
|
||||||
plugins =
|
|
||||||
|
|
||||||
[nuitka]
|
|
||||||
|
|
||||||
# usage description for permissions requested by the app as found in the info.plist file
|
|
||||||
# of the app bundle
|
|
||||||
# eg = extra_args = --show-modules --follow-stdlib
|
|
||||||
macos.permissions =
|
|
||||||
|
|
||||||
# mode of using nuitka. accepts standalone or onefile. default is onefile.
|
|
||||||
mode = onefile
|
|
||||||
|
|
||||||
# (str) specify any extra nuitka arguments
|
|
||||||
extra_args = --quiet --noinclude-qt-translations
|
|
||||||
|
|
||||||
[buildozer]
|
|
||||||
|
|
||||||
# build mode
|
|
||||||
# possible options = [release, debug]
|
|
||||||
# release creates an aab, while debug creates an apk
|
|
||||||
mode = debug
|
|
||||||
|
|
||||||
# contrains path to pyside6 and shiboken6 recipe dir
|
|
||||||
recipe_dir =
|
|
||||||
|
|
||||||
# path to extra qt android jars to be loaded by the application
|
|
||||||
jars_dir =
|
|
||||||
|
|
||||||
# if empty uses default ndk path downloaded by buildozer
|
|
||||||
ndk_path =
|
|
||||||
|
|
||||||
# if empty uses default sdk path downloaded by buildozer
|
|
||||||
sdk_path =
|
|
||||||
|
|
||||||
# other libraries to be loaded. comma separated.
|
|
||||||
# loaded at app startup
|
|
||||||
local_libs =
|
|
||||||
|
|
||||||
# architecture of deployed platform
|
|
||||||
# possible values = ["aarch64", "armv7a", "i686", "x86_64"]
|
|
||||||
arch =
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
home = /usr/bin
|
|
||||||
include-system-site-packages = false
|
|
||||||
version = 3.11.2
|
|
||||||
executable = /usr/bin/python3.11
|
|
||||||
command = /usr/bin/python -m venv /home/tpeetz/projects/kontor/python/kontor-gui
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
-e ../kontor-schema
|
|
||||||
|
|
||||||
platformdirs
|
|
||||||
pyyaml
|
|
||||||
PySide6
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 513 B |
Binary file not shown.
|
Before Width: | Height: | Size: 524 B |
Binary file not shown.
|
Before Width: | Height: | Size: 836 B |
Binary file not shown.
|
Before Width: | Height: | Size: 544 B |
Binary file not shown.
|
Before Width: | Height: | Size: 634 B |
Reference in New Issue
Block a user