Added Browser Window (WIP)

Added the first draft of the browser window and implemented switching between it and the importer window via menu action.
Also renamed window.py to importer_window and abstracted some features into a superclass from which the browser window can also inherit. This allows an equal interface for them.
Also fixed a bug in the db_adapter.py where an old column name was used for a query.
dev
Peery 3 years ago
parent b81ca5a40c
commit 2bb9b06a8f

@ -10,7 +10,8 @@ from PyQt5.QtWidgets import QApplication
from ArtNet.db.db_adapter import DBAdapter from ArtNet.db.db_adapter import DBAdapter
from ArtNet.file.file_reader import FileReader from ArtNet.file.file_reader import FileReader
from ArtNet.file.config_reader import ConfigReader from ArtNet.file.config_reader import ConfigReader
from ArtNet.gui.window import Window from ArtNet.gui.importer_window import ImporterWindow
from ArtNet.gui.browse_window import BrowseWindow
from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog
from ArtNet.web.link_generator import LinkGenerator from ArtNet.web.link_generator import LinkGenerator
@ -69,12 +70,15 @@ class ArtNetManager:
self.change_db_connection(host=db_data["host"], port=db_data["port"], self.change_db_connection(host=db_data["host"], port=db_data["port"],
user=db_data["user"], password=db_data["password"], user=db_data["user"], password=db_data["password"],
database=db_data["database"]) database=db_data["database"])
self.window = Window(self) self.curr_active_window = None
self.import_window = ImporterWindow(self)
self.browse_window = BrowseWindow(self)
if len(self.config.data["file_root"]) == 0 or not os.path.isdir( if len(self.config.data["file_root"]) == 0 or not os.path.isdir(
self.config.data["file_root"]): # no file_root given by config or invalid self.config.data["file_root"]): # no file_root given by config or invalid
logging.info("Querying for new file root due to lack of valid one ...") logging.info("Querying for new file root due to lack of valid one ...")
self.window.on_artnet_root_change_clicked() self.import_window.on_artnet_root_change_clicked()
self.__file_reader = FileReader(self.config.data["file_root"]) self.__file_reader = FileReader(self.config.data["file_root"])
self.curr_image_index: int = None self.curr_image_index: int = None
@ -82,20 +86,41 @@ class ArtNetManager:
self.all_images: list = None self.all_images: list = None
self.update_all_images_list() self.update_all_images_list()
self.window.set_temporary_status_message("Hello o7", 5000) self.import_window.set_temporary_status_message("Hello o7", 5000)
def run(self): def run(self):
if len(self.all_images) == 0: if len(self.all_images) == 0:
raise FileNotFoundError("No files or folders were in artnet root!") raise FileNotFoundError("No files or folders were in artnet root!")
self.curr_image_index = 0 self.curr_image_index = 0
self.curr_active_window = self.import_window
self.refresh_shown_image() self.refresh_shown_image()
self.window.show() self.import_window.show()
status = self.__app.exec_() status = self.__app.exec_()
logging.info(f"Shutting client down with status: {status}") logging.info(f"Shutting client down with status: {status}")
sys.exit(status) sys.exit(status)
def switch_to_browser(self, displayed_image_index: int = None):
logging.debug("Switching to browser window ...")
if displayed_image_index is not None:
self.curr_image_index = displayed_image_index
self.refresh_shown_image()
self.curr_active_window.hide()
self.browse_window.show()
self.curr_active_window = self.browse_window
def switch_to_importer(self, displayed_image_index: int = None):
logging.debug("Switching to importer window ...")
if displayed_image_index is not None:
self.curr_image_index = displayed_image_index
self.refresh_shown_image()
self.curr_active_window.hide()
self.import_window.show()
self.curr_active_window = self.browse_window
def update_all_images_list(self): def update_all_images_list(self):
""" """
Updates the internal list of all images in the artnet root Updates the internal list of all images in the artnet root
@ -114,7 +139,7 @@ class ArtNetManager:
if self.db_connection.get_art_by_path(image) is not None: if self.db_connection.get_art_by_path(image) is not None:
self.known_image_amount += 1 self.known_image_amount += 1
self.window.ui.imageNumberSpinBox.setMaximum(len(self.all_images)) self.import_window.ui.imageNumberSpinBox.setMaximum(len(self.all_images))
def scrape_tags(self, file_name: str, art_ID: int, url: str = None): def scrape_tags(self, file_name: str, art_ID: int, url: str = None):
""" """
@ -186,7 +211,7 @@ class ArtNetManager:
for tag in tags: for tag in tags:
if len(self.db_connection.get_tag_by_name(tag)) == 0: # tag doesn't exist yet if len(self.db_connection.get_tag_by_name(tag)) == 0: # tag doesn't exist yet
result = self.window.force_edit_tag_dialog(name=tag) result = self.import_window.force_edit_tag_dialog(name=tag)
if result is None: # tag creation was aborted if result is None: # tag creation was aborted
continue continue
@ -194,8 +219,8 @@ class ArtNetManager:
tag = result['name'] # overwrite with possibly new tag name tag = result['name'] # overwrite with possibly new tag name
tag = self.db_connection.get_tag_by_name(tag)[0][0] tag = self.db_connection.get_tag_by_name(tag)[0][0]
self.window.curr_tags.append(tag) self.import_window.curr_tags.append(tag)
self.window.data_changed = True self.import_window.data_changed = True
def get_md5_of_image(self, path: str): def get_md5_of_image(self, path: str):
""" """
@ -348,10 +373,11 @@ class ArtNetManager:
def refresh_shown_image(self): def refresh_shown_image(self):
""" """
Refresh the image display to show the most current data according to the selected image Refresh the image display to show the most current data according to self.curr_image_index.
This index points to the image displayed as an index on self.all_images
:return: :return:
""" """
self.window.setting_up_data = True self.curr_active_window.setting_up_data = True
image_db_result = self.db_connection.get_art_by_hash( image_db_result = self.db_connection.get_art_by_hash(
self.get_md5_of_image(self.all_images[self.curr_image_index]) self.get_md5_of_image(self.all_images[self.curr_image_index])
@ -360,7 +386,7 @@ class ArtNetManager:
s = self.all_images[self.curr_image_index].split(os.path.sep) s = self.all_images[self.curr_image_index].split(os.path.sep)
if image_db_result is not None: if image_db_result is not None:
image_title = image_db_result["title"] if isinstance(image_db_result["title"], str) and \ image_title = image_db_result["title"] if isinstance(image_db_result["title"], str) and \
len(image_db_result["title"]) > 0 else self.window.UNKNOWN_TITLE len(image_db_result["title"]) > 0 else self.import_window.UNKNOWN_TITLE
image_author = self.db_connection.get_authors_of_art_by_ID(image_db_result["ID"]) image_author = self.db_connection.get_authors_of_art_by_ID(image_db_result["ID"])
image_link = image_db_result["link"] image_link = image_db_result["link"]
image_description = image_db_result["description"] image_description = image_db_result["description"]
@ -375,15 +401,15 @@ class ArtNetManager:
image_description = None image_description = None
logging.info(f"Displaying #{self.curr_image_index} \"{self.all_images[self.curr_image_index]}\"") logging.info(f"Displaying #{self.curr_image_index} \"{self.all_images[self.curr_image_index]}\"")
self.window.display_image(image_title, image_author, self.curr_active_window.display_image(image_title, image_author,
os.path.join(self.config.data["file_root"], self.all_images[self.curr_image_index]), os.path.join(self.config.data["file_root"], self.all_images[self.curr_image_index]),
self.all_images[self.curr_image_index], self.all_images[self.curr_image_index],
art_ID, image_link, file_name=s[-1], description=image_description) art_ID, image_link, file_name=s[-1], description=image_description)
self.window.set_tag_list( self.curr_active_window.set_tag_list(
[self.db_connection.get_tag_by_ID(x)[0][1].strip() for x in self.db_connection.get_art_tags_by_ID(art_ID)]) [self.db_connection.get_tag_by_ID(x)[0][1].strip() for x in self.db_connection.get_art_tags_by_ID(art_ID)])
self.window.data_changed = False self.curr_active_window.data_changed = False
self.window.setting_up_data = False self.curr_active_window.setting_up_data = False
def create_db_connection(self, host: str, port: int, database: str, user: str, password: str) -> DBAdapter: def create_db_connection(self, host: str, port: int, database: str, user: str, password: str) -> DBAdapter:
logging.info(f"Changing db connection to {host}:{port} {user}@{database} ...") logging.info(f"Changing db connection to {host}:{port} {user}@{database} ...")

@ -328,7 +328,7 @@ class DBAdapter:
:return: :return:
""" """
d = {"id": id} d = {"id": id}
self.db_cursor.execute("SELECT name, domain, artist FROM Presence WHERE artist = %(id)s", d) self.db_cursor.execute("SELECT name, domain, artist_id FROM Presence WHERE artist_id = %(id)s", d)
return self.db_cursor.fetchall() return self.db_cursor.fetchall()

@ -0,0 +1,27 @@
import logging
from ArtNet.gui.windows.browser.picture_browser import Ui_MainWindow
from ArtNet.gui.windows.artnet_mainwindow import ArtnetMainWindow
class BrowseWindow(ArtnetMainWindow):
UNKNOWN_TITLE = "-Title Unknown-"
def __init__(self, main):
super().__init__(main)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.actionArtNet_Importer.triggered.connect(self.on_importer_clicked)
def display_image(self, image_title: str, image_authors: list, full_path: str, relative_path: str, art_ID: int,
link: str, file_name: str, description: str):
"""
Display the described image in the GraphicsView
"""
def on_importer_clicked(self):
logging.debug("Clicked on open ArtNet importer!")
self.main.switch_to_importer()

@ -7,7 +7,9 @@ from PyQt5.QtGui import QPixmap, QResizeEvent, QKeyEvent, QStandardItemModel, QS
from PyQt5 import QtMultimedia from PyQt5 import QtMultimedia
from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtMultimediaWidgets import QVideoWidget
from ArtNet.gui.windows.picture_importer import Ui_MainWindow from ArtNet.gui.windows.importer.picture_importer import Ui_MainWindow
from ArtNet.gui.windows.artnet_mainwindow import ArtnetMainWindow
from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog
from ArtNet.gui.dialogs.tag_modify_dialog.tag_mod_dialog import TagModifyDialog from ArtNet.gui.dialogs.tag_modify_dialog.tag_mod_dialog import TagModifyDialog
from ArtNet.gui.dialogs.tag_select_dialog.tag_select_dialog import TagSelectDialog from ArtNet.gui.dialogs.tag_select_dialog.tag_select_dialog import TagSelectDialog
@ -18,15 +20,13 @@ from ArtNet.gui.dialogs.tag_import_dialog.tag_imp_dialog import TagImportDialog
from ArtNet.web.link_generator import LinkGenerator from ArtNet.web.link_generator import LinkGenerator
class Window(QtWidgets.QMainWindow): class ImporterWindow(ArtnetMainWindow):
UNKNOWN_TITLE = "-Title Unknown-" UNKNOWN_TITLE = "-Title Unknown-"
UNKNOWN_PRESENCE = "(Not in Database)" UNKNOWN_PRESENCE = "(Not in Database)"
def __init__(self, main): def __init__(self, main):
super(Window, self).__init__() super().__init__(main)
self.__main = main
self.__pixmap: QPixmap = None self.__pixmap: QPixmap = None
self.__video: QVideoWidget = None self.__video: QVideoWidget = None
@ -49,7 +49,6 @@ class Window(QtWidgets.QMainWindow):
self.curr_imply_tags: list = list() self.curr_imply_tags: list = list()
self.curr_tag_aliases: list = list() self.curr_tag_aliases: list = list()
self.setting_up_data: bool = True
self.__data_changed: bool = False self.__data_changed: bool = False
self.ui = Ui_MainWindow() self.ui = Ui_MainWindow()
@ -63,6 +62,7 @@ class Window(QtWidgets.QMainWindow):
self.ui.actionDelete_a_Tag.triggered.connect(self.on_tag_deletion_clicked) self.ui.actionDelete_a_Tag.triggered.connect(self.on_tag_deletion_clicked)
self.ui.actionCreate_New_Category_2.triggered.connect(self.on_category_creation_clicked) self.ui.actionCreate_New_Category_2.triggered.connect(self.on_category_creation_clicked)
self.ui.actionDelete_a_Category_2.triggered.connect(self.on_category_deletion_clicked) self.ui.actionDelete_a_Category_2.triggered.connect(self.on_category_deletion_clicked)
self.ui.actionArtNet_Browser.triggered.connect(self.on_browser_clicked)
self.ui.imageNumberSpinBox.valueChanged.connect(self.on_image_id_spinbox_changed) self.ui.imageNumberSpinBox.valueChanged.connect(self.on_image_id_spinbox_changed)
@ -93,22 +93,6 @@ class Window(QtWidgets.QMainWindow):
self.on_tag_search_change() self.on_tag_search_change()
self.center() self.center()
@property
def data_changed(self):
return self.__data_changed
@data_changed.setter
def data_changed(self, v: bool):
self.__data_changed = v
if self.curr_image_title is None:
return
if " (Not in Database)" in self.curr_image_title and v and not self.setting_up_data:
self.curr_image_title = self.curr_image_title.replace(" (Not in Database)", "")
self.setting_up_data = True
self.ui.image_title_line.setText(self.curr_image_title)
self.setting_up_data = False
def center(self): def center(self):
""" """
Centers the window in the middle of the screen Centers the window in the middle of the screen
@ -143,7 +127,7 @@ class Window(QtWidgets.QMainWindow):
""" """
new_title = self.curr_image_title new_title = self.curr_image_title
new_description = self.ui.description_edit.toPlainText().strip() new_description = self.ui.description_edit.toPlainText().strip()
if new_title == self.curr_file_name or len(new_title) == 0 or new_title == Window.UNKNOWN_TITLE: if new_title == self.curr_file_name or len(new_title) == 0 or new_title == ImporterWindow.UNKNOWN_TITLE:
new_title = None new_title = None
if new_description is None or len(new_description) == 0: if new_description is None or len(new_description) == 0:
new_description = None new_description = None
@ -156,12 +140,12 @@ class Window(QtWidgets.QMainWindow):
"path": self.curr_art_path, "path": self.curr_art_path,
"tags": self.curr_tags, "tags": self.curr_tags,
"link": self.curr_link, "link": self.curr_link,
"md5_hash": self.__main.get_md5_of_image(self.curr_art_path), "md5_hash": self.main.get_md5_of_image(self.curr_art_path),
"description": new_description, "description": new_description,
} }
for presence in self.curr_presences: for presence in self.curr_presences:
if presence[-1] == Window.UNKNOWN_PRESENCE: if presence[-1] == ImporterWindow.UNKNOWN_PRESENCE:
msg = QtWidgets.QMessageBox() msg = QtWidgets.QMessageBox()
msg.setWindowTitle("Invalid Presence Domain") msg.setWindowTitle("Invalid Presence Domain")
msg.setInformativeText("You've tried to save with a not working presence entry! " + msg.setInformativeText("You've tried to save with a not working presence entry! " +
@ -170,7 +154,7 @@ class Window(QtWidgets.QMainWindow):
msg.exec_() msg.exec_()
return False return False
self.__main.db_connection.save_image(ID=image_data["ID"], title=image_data["title"], self.main.db_connection.save_image(ID=image_data["ID"], title=image_data["title"],
authors=image_data["authors"], path=image_data["path"], authors=image_data["authors"], path=image_data["path"],
tags=image_data["tags"], link=image_data["link"], tags=image_data["tags"], link=image_data["link"],
md5_hash=image_data["md5_hash"], desc=image_data["description"]) md5_hash=image_data["md5_hash"], desc=image_data["description"])
@ -201,7 +185,7 @@ class Window(QtWidgets.QMainWindow):
""" """
if len(name) == 0 or len(domain) == 0 or artist is None: if len(name) == 0 or len(domain) == 0 or artist is None:
return return
self.__main.db_connection.save_presence(name=name, domain=domain, artist_ID=artist[0], link=link) self.main.db_connection.save_presence(name=name, domain=domain, artist_ID=artist[0], link=link)
def get_authors(self, presence_name: str, presence_domain: str) -> list: def get_authors(self, presence_name: str, presence_domain: str) -> list:
""" """
@ -210,7 +194,7 @@ class Window(QtWidgets.QMainWindow):
:param presence_domain: :param presence_domain:
:return: a list of tuples of (presence_name, presence_domain) :return: a list of tuples of (presence_name, presence_domain)
""" """
return self.__main.db_connection.search_fuzzy_presence(presence_name, presence_domain, all_if_empty=True) return self.main.db_connection.search_fuzzy_presence(presence_name, presence_domain, all_if_empty=True)
def create_artist(self, ID: int, description: str): def create_artist(self, ID: int, description: str):
""" """
@ -219,7 +203,7 @@ class Window(QtWidgets.QMainWindow):
:param description: :param description:
:return: :return:
""" """
self.__main.db_connection.save_artist(ID, description) self.main.db_connection.save_artist(ID, description)
self.set_temporary_status_message("Created Artist {0}!".format(description), 3000) self.set_temporary_status_message("Created Artist {0}!".format(description), 3000)
def get_artists(self, search: str) -> list: def get_artists(self, search: str) -> list:
@ -235,7 +219,7 @@ class Window(QtWidgets.QMainWindow):
ID_int = None ID_int = None
description = search description = search
return self.__main.db_connection.search_fuzzy_artists(ID_int, description) return self.main.db_connection.search_fuzzy_artists(ID_int, description)
def get_artist(self, id: int) -> list: def get_artist(self, id: int) -> list:
""" """
@ -243,7 +227,7 @@ class Window(QtWidgets.QMainWindow):
:param id: :param id:
:return: :return:
""" """
return self.__main.db_connection.get_artist(id) return self.main.db_connection.get_artist(id)
def remove_artist(self, id: int): def remove_artist(self, id: int):
""" """
@ -251,7 +235,7 @@ class Window(QtWidgets.QMainWindow):
:param id: :param id:
:return: :return:
""" """
self.__main.db_connection.remove_artist(id) self.main.db_connection.remove_artist(id)
def get_artist_presences(self, id: int) -> list: def get_artist_presences(self, id: int) -> list:
""" """
@ -259,14 +243,14 @@ class Window(QtWidgets.QMainWindow):
:param id: :param id:
:return: :return:
""" """
return self.__main.db_connection.get_artist_presences(id) return self.main.db_connection.get_artist_presences(id)
def get_all_artists(self) -> list: def get_all_artists(self) -> list:
""" """
Queries the database for a list of all available arists (not presences). Queries the database for a list of all available arists (not presences).
:return: :return:
""" """
return self.__main.db_connection.get_all_artists() return self.main.db_connection.get_all_artists()
def get_presence(self, name: str, domain: str): def get_presence(self, name: str, domain: str):
""" """
@ -275,7 +259,7 @@ class Window(QtWidgets.QMainWindow):
:param domain: :param domain:
:return: :return:
""" """
result = self.__main.db_connection.get_presence(name, domain) result = self.main.db_connection.get_presence(name, domain)
return result if len(result) != 0 else None return result if len(result) != 0 else None
@ -286,7 +270,7 @@ class Window(QtWidgets.QMainWindow):
:param domain: :param domain:
:return: :return:
""" """
self.__main.db_connection.remove_presence(name, domain) self.main.db_connection.remove_presence(name, domain)
def get_presences_art(self, name: str, domain: str): def get_presences_art(self, name: str, domain: str):
""" """
@ -295,7 +279,7 @@ class Window(QtWidgets.QMainWindow):
:param domain: :param domain:
:return: :return:
""" """
return self.__main.db_connection.get_presences_art(name, domain) return self.main.db_connection.get_presences_art(name, domain)
def get_current_presences(self) -> list: def get_current_presences(self) -> list:
""" """
@ -311,10 +295,10 @@ class Window(QtWidgets.QMainWindow):
""" """
if len(presences) > 1: if len(presences) > 1:
for name, domain in presences: for name, domain in presences:
if domain == Window.UNKNOWN_PRESENCE: if domain == ImporterWindow.UNKNOWN_PRESENCE:
presences.remove((name, domain)) presences.remove((name, domain))
elif len(presences) == 0: elif len(presences) == 0:
presences = [(self.curr_art_path.split("/")[0], Window.UNKNOWN_PRESENCE)] presences = [(self.curr_art_path.split("/")[0], ImporterWindow.UNKNOWN_PRESENCE)]
self.curr_presences = presences self.curr_presences = presences
if self.curr_presences is not None: if self.curr_presences is not None:
@ -332,9 +316,9 @@ class Window(QtWidgets.QMainWindow):
:return: :return:
""" """
if all_if_empty and len(search) == 0: if all_if_empty and len(search) == 0:
return self.__main.db_connection.get_all_categories() return self.main.db_connection.get_all_categories()
return self.__main.db_connection.search_fuzzy_categories(search) return self.main.db_connection.search_fuzzy_categories(search)
def get_image_link_from_line(self) -> str: def get_image_link_from_line(self) -> str:
""" """
@ -398,7 +382,7 @@ class Window(QtWidgets.QMainWindow):
:param name: :param name:
:return: :return:
""" """
return self.__main.db_connection.get_tag_by_name(name) return self.main.db_connection.get_tag_by_name(name)
def get_tag_aliases(self, name: str) -> list: def get_tag_aliases(self, name: str) -> list:
""" """
@ -408,7 +392,7 @@ class Window(QtWidgets.QMainWindow):
:param name: :param name:
:return: :return:
""" """
return self.__main.db_connection.get_tag_aliases_by_name(name) return self.main.db_connection.get_tag_aliases_by_name(name)
def get_tag_implications(self, name: str) -> list: def get_tag_implications(self, name: str) -> list:
""" """
@ -416,14 +400,14 @@ class Window(QtWidgets.QMainWindow):
:param name: :param name:
:return: :return:
""" """
return self.__main.db_connection.get_tag_implications(name) return self.main.db_connection.get_tag_implications(name)
def get_tag_search_result(self, name: str) -> list: def get_tag_search_result(self, name: str) -> list:
""" """
Query a search for tags to the DB that are like name Query a search for tags to the DB that are like name
:return: :return:
""" """
return self.__main.db_connection.search_fuzzy_tag(name, all_if_empty=True) return self.main.db_connection.search_fuzzy_tag(name, all_if_empty=True)
def set_tag_search_result_list(self, tags: list): def set_tag_search_result_list(self, tags: list):
""" """
@ -484,12 +468,12 @@ class Window(QtWidgets.QMainWindow):
implied_tags = [] implied_tags = []
for x in self.curr_tags: for x in self.curr_tags:
# collect all implied tags into a list # collect all implied tags into a list
implied_tags += self.__main.db_connection.get_all_tag_implications_by_name(x) implied_tags += self.main.db_connection.get_all_tag_implications_by_name(x)
self.set_implied_list(implied_tags) self.set_implied_list(implied_tags)
self.curr_tag_aliases = list() self.curr_tag_aliases = list()
for tag in tags+implied_tags: for tag in tags+implied_tags:
self.curr_tag_aliases += self.__main.db_connection.get_tag_aliases_by_name(tag) self.curr_tag_aliases += self.main.db_connection.get_tag_aliases_by_name(tag)
self.data_changed = True self.data_changed = True
@ -607,7 +591,7 @@ class Window(QtWidgets.QMainWindow):
""" """
image_title = self.ui.image_title_line.text() image_title = self.ui.image_title_line.text()
self.setWindowTitle(self.main_title + " - " + image_title self.setWindowTitle(self.main_title + " - " + image_title
+ f" ({round(self.__main.known_image_amount/len(self.__main.all_images), 5)}%)") + f" ({round(self.main.known_image_amount/len(self.main.all_images), 5)}%)")
def set_image_id_spinbox(self): def set_image_id_spinbox(self):
""" """
@ -615,8 +599,8 @@ class Window(QtWidgets.QMainWindow):
:return: :return:
""" """
self.ui.imageNumberSpinBox.setMinimum(0) self.ui.imageNumberSpinBox.setMinimum(0)
self.ui.imageNumberSpinBox.setMaximum(len(self.__main.all_images)-1) self.ui.imageNumberSpinBox.setMaximum(len(self.main.all_images)-1)
self.ui.imageNumberSpinBox.setValue(self.__main.curr_image_index) self.ui.imageNumberSpinBox.setValue(self.main.curr_image_index)
def __image_resize(self): def __image_resize(self):
""" """
@ -645,7 +629,7 @@ class Window(QtWidgets.QMainWindow):
self.__image_resize() self.__image_resize()
def keyPressEvent(self, a0: QKeyEvent) -> None: def keyPressEvent(self, a0: QKeyEvent) -> None:
super(Window, self).keyPressEvent(a0) super(ImporterWindow, self).keyPressEvent(a0)
if a0.key() == Qt.Key_Left: if a0.key() == Qt.Key_Left:
self.on_previous_clicked() self.on_previous_clicked()
elif a0.key() == Qt.Key_Right: elif a0.key() == Qt.Key_Right:
@ -718,7 +702,7 @@ class Window(QtWidgets.QMainWindow):
else: else:
url = self.get_image_link_from_line() url = self.get_image_link_from_line()
r = self.__main.scrape_tags(self.curr_file_name, url=url, r = self.main.scrape_tags(self.curr_file_name, url=url,
art_ID=self.curr_art_id) art_ID=self.curr_art_id)
if r is None: if r is None:
@ -735,7 +719,7 @@ class Window(QtWidgets.QMainWindow):
i = 0 i = 0
while i < len(tags): # workaround for an issue with altering lists during iteration while i < len(tags): # workaround for an issue with altering lists during iteration
r = self.__main.db_connection.get_tag_by_name(tags[i]) r = self.main.db_connection.get_tag_by_name(tags[i])
if len(r) > 0: if len(r) > 0:
self.curr_tags.append(tags[i]) self.curr_tags.append(tags[i])
self.data_changed = True self.data_changed = True
@ -762,7 +746,7 @@ class Window(QtWidgets.QMainWindow):
self.set_tag_list(self.curr_tags) self.set_tag_list(self.curr_tags)
return return
self.__main.import_tags(result) self.main.import_tags(result)
self.set_tag_list(self.curr_tags) self.set_tag_list(self.curr_tags)
def on_next_clicked(self): def on_next_clicked(self):
@ -770,10 +754,10 @@ class Window(QtWidgets.QMainWindow):
if not self.check_save_changes(): if not self.check_save_changes():
return return
self.__main.curr_image_index += 1 self.main.curr_image_index += 1
if self.__main.curr_image_index >= len(self.__main.all_images): if self.main.curr_image_index >= len(self.main.all_images):
self.__main.curr_image_index = 0 self.main.curr_image_index = 0
self.__main.refresh_shown_image() self.main.refresh_shown_image()
if self.presence_docker_open: if self.presence_docker_open:
self.toggle_presence_docker() self.toggle_presence_docker()
@ -788,11 +772,11 @@ class Window(QtWidgets.QMainWindow):
if not self.check_save_changes(): if not self.check_save_changes():
return return
self.__main.curr_image_index -= 1 self.main.curr_image_index -= 1
if self.__main.curr_image_index < 0: if self.main.curr_image_index < 0:
self.__main.curr_image_index += len(self.__main.all_images) self.main.curr_image_index += len(self.main.all_images)
self.__main.refresh_shown_image() self.main.refresh_shown_image()
if self.presence_docker_open: if self.presence_docker_open:
self.toggle_presence_docker() self.toggle_presence_docker()
@ -822,12 +806,12 @@ class Window(QtWidgets.QMainWindow):
dialog.setOptions(QtWidgets.QFileDialog.ShowDirsOnly) dialog.setOptions(QtWidgets.QFileDialog.ShowDirsOnly)
directory = dialog.getExistingDirectory() directory = dialog.getExistingDirectory()
self.__main.change_root(directory) self.main.change_root(directory)
def on_db_connection_change_clicked(self): def on_db_connection_change_clicked(self):
logging.info("Clicked db connection change!") logging.info("Clicked db connection change!")
dialog = DBDialog(self) dialog = DBDialog(self)
prev_db_data = self.__main.get_db_connection_details() prev_db_data = self.main.get_db_connection_details()
dialog.ui.user_line_edit.setText(prev_db_data["user"]) dialog.ui.user_line_edit.setText(prev_db_data["user"])
dialog.ui.password_line_edit.setText(prev_db_data["password"]) dialog.ui.password_line_edit.setText(prev_db_data["password"])
dialog.ui.host_line_edit.setText(prev_db_data["host"]) dialog.ui.host_line_edit.setText(prev_db_data["host"])
@ -837,7 +821,7 @@ class Window(QtWidgets.QMainWindow):
db_data: dict = dialog.exec_() db_data: dict = dialog.exec_()
if len(db_data.keys()) == 0: if len(db_data.keys()) == 0:
return return
self.__main.change_db_connection(host=db_data["host"], port=db_data["port"], self.main.change_db_connection(host=db_data["host"], port=db_data["port"],
user=db_data["user"], password=db_data["password"], user=db_data["user"], password=db_data["password"],
database=db_data["database"]) database=db_data["database"])
@ -854,7 +838,7 @@ class Window(QtWidgets.QMainWindow):
QtWidgets.QMessageBox.information(self, "Duplicate Tag", "The tag \"{0}\" already exists in the db!" QtWidgets.QMessageBox.information(self, "Duplicate Tag", "The tag \"{0}\" already exists in the db!"
.format(tag_data["name"])) .format(tag_data["name"]))
return return
self.__main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], self.main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"],
aliases=tag_data["aliases"], implications=tag_data["implications"], aliases=tag_data["aliases"], implications=tag_data["implications"],
category=tag_data["category"]) category=tag_data["category"])
self.on_tag_search_change() self.on_tag_search_change()
@ -875,7 +859,7 @@ class Window(QtWidgets.QMainWindow):
if confirmation_reply == QtWidgets.QMessageBox.No: if confirmation_reply == QtWidgets.QMessageBox.No:
return return
self.__main.db_connection.remove_tag_by_name(tag["name"]) self.main.db_connection.remove_tag_by_name(tag["name"])
self.on_tag_search_change() self.on_tag_search_change()
def force_edit_tag_dialog(self, name: str): def force_edit_tag_dialog(self, name: str):
@ -891,7 +875,7 @@ class Window(QtWidgets.QMainWindow):
edit_dialog.set_all_categories() edit_dialog.set_all_categories()
tag_data = edit_dialog.exec_() tag_data = edit_dialog.exec_()
logging.debug("Got Tag data", tag_data) logging.debug(f"Got Tag data: {tag_data}")
if tag_data is None or len(tag_data.keys()) == 0: if tag_data is None or len(tag_data.keys()) == 0:
return None return None
if len(tag_data["category"]) == 0: if len(tag_data["category"]) == 0:
@ -904,7 +888,7 @@ class Window(QtWidgets.QMainWindow):
QtWidgets.QMessageBox.information(self, "Tag already exists", QtWidgets.QMessageBox.information(self, "Tag already exists",
"The Tag \"{0}\" you wanted to create already exists! Skipping...") "The Tag \"{0}\" you wanted to create already exists! Skipping...")
else: else:
self.__main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], self.main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"],
aliases=tag_data["aliases"], implications=tag_data["implications"], aliases=tag_data["aliases"], implications=tag_data["implications"],
category=tag_data["category"]) category=tag_data["category"])
self.on_tag_search_change() self.on_tag_search_change()
@ -918,8 +902,8 @@ class Window(QtWidgets.QMainWindow):
if tag is None or len(tag) == 0: if tag is None or len(tag) == 0:
return return
tag['aliases'] = self.__main.db_connection.get_tag_aliases_by_name(tag["name"]) tag['aliases'] = self.main.db_connection.get_tag_aliases_by_name(tag["name"])
tag['implications'] = self.__main.db_connection.get_tag_implications(tag["name"]) tag['implications'] = self.main.db_connection.get_tag_implications(tag["name"])
edit_dialog = TagModifyDialog(self, create_tag=False) edit_dialog = TagModifyDialog(self, create_tag=False)
edit_dialog.ui.tag_name_line.setText(tag["name"]) edit_dialog.ui.tag_name_line.setText(tag["name"])
@ -928,7 +912,7 @@ class Window(QtWidgets.QMainWindow):
edit_dialog.alias_selection = tag["aliases"] edit_dialog.alias_selection = tag["aliases"]
edit_dialog.set_selected_implicated_tags(tag["implications"], set_checked=True) edit_dialog.set_selected_implicated_tags(tag["implications"], set_checked=True)
edit_dialog.implication_selection = tag["implications"] edit_dialog.implication_selection = tag["implications"]
edit_dialog.category_selection = self.__main.db_connection.get_category_by_ID(tag["category_id"])[1] edit_dialog.category_selection = self.main.db_connection.get_category_by_ID(tag["category_id"])[1]
edit_dialog.set_all_categories() edit_dialog.set_all_categories()
tag_data = edit_dialog.exec_() tag_data = edit_dialog.exec_()
@ -939,10 +923,10 @@ class Window(QtWidgets.QMainWindow):
if "old_tag_name" not in tag_data.keys(): if "old_tag_name" not in tag_data.keys():
tag_data["old_tag_name"] = None tag_data["old_tag_name"] = None
self.__main.db_connection.edit_tag(tag_id=tag["ID"], self.main.db_connection.edit_tag(tag_id=tag["ID"],
name=tag_data["name"], description=tag_data["description"], name=tag_data["name"], description=tag_data["description"],
aliases=tag_data["aliases"], implications=tag_data["implications"], aliases=tag_data["aliases"], implications=tag_data["implications"],
category_id=self.__main.db_connection.get_category_by_name(tag_data["category"])[0]) category_id=self.main.db_connection.get_category_by_name(tag_data["category"])[0])
self.on_tag_search_change() self.on_tag_search_change()
def on_tag_search_item_changed(self, item: QStandardItem): def on_tag_search_item_changed(self, item: QStandardItem):
@ -966,7 +950,7 @@ class Window(QtWidgets.QMainWindow):
raise Exception("Something went terribly wrong!") raise Exception("Something went terribly wrong!")
def on_tag_search_change(self): def on_tag_search_change(self):
tags = self.__main.db_connection.search_fuzzy_tag(self.ui.tag_search_bar.text(), all_if_empty=True) tags = self.main.db_connection.search_fuzzy_tag(self.ui.tag_search_bar.text(), all_if_empty=True)
result = [] result = []
for tag_name, tag_desc, tag_category in tags: for tag_name, tag_desc, tag_category in tags:
@ -981,7 +965,7 @@ class Window(QtWidgets.QMainWindow):
if data is None: if data is None:
return return
self.__main.db_connection.save_category(data["name"]) self.main.db_connection.save_category(data["name"])
def on_category_deletion_clicked(self): def on_category_deletion_clicked(self):
dialog = CategoryModDialog(self, delete_category=True) dialog = CategoryModDialog(self, delete_category=True)
@ -990,34 +974,34 @@ class Window(QtWidgets.QMainWindow):
if data is None: if data is None:
return return
self.__main.db_connection.remove_category(data["name"]) self.main.db_connection.remove_category(data["name"])
def on_link_line_change(self): def on_link_line_change(self):
self.data_changed = True self.data_changed = True
def on_prev_unknown_image_clicked(self): def on_prev_unknown_image_clicked(self):
unknown_image_index = self.__main.get_prev_unknown_image() unknown_image_index = self.main.get_prev_unknown_image()
logging.info("Previous unknown image clicked!") logging.info("Previous unknown image clicked!")
result = QtWidgets.QMessageBox.question(self, "Switch Image?", result = QtWidgets.QMessageBox.question(self, "Switch Image?",
"Do you really want to skip to image #{1} \"{0}\"?" "Do you really want to skip to image #{1} \"{0}\"?"
.format(self.__main.all_images[unknown_image_index], .format(self.main.all_images[unknown_image_index],
unknown_image_index)) unknown_image_index))
if result == QtWidgets.QMessageBox.Yes: if result == QtWidgets.QMessageBox.Yes:
self.__main.curr_image_index = unknown_image_index self.main.curr_image_index = unknown_image_index
self.__main.refresh_shown_image() self.main.refresh_shown_image()
def on_next_unknown_image_clicked(self): def on_next_unknown_image_clicked(self):
unknown_image_index = self.__main.get_next_unknown_image() unknown_image_index = self.main.get_next_unknown_image()
logging.info("Next unknown image clicked!") logging.info("Next unknown image clicked!")
result = QtWidgets.QMessageBox.question(self, "Switch Image?", result = QtWidgets.QMessageBox.question(self, "Switch Image?",
"Do you really want to skip to image #{1} \"{0}\"?" "Do you really want to skip to image #{1} \"{0}\"?"
.format(self.__main.all_images[unknown_image_index], .format(self.main.all_images[unknown_image_index],
unknown_image_index)) unknown_image_index))
if result == QtWidgets.QMessageBox.Yes: if result == QtWidgets.QMessageBox.Yes:
self.__main.curr_image_index = unknown_image_index self.main.curr_image_index = unknown_image_index
self.__main.refresh_shown_image() self.main.refresh_shown_image()
def on_image_id_spinbox_changed(self, v: int): def on_image_id_spinbox_changed(self, v: int):
if self.__tmp_imageid_spinbox == v: if self.__tmp_imageid_spinbox == v:
@ -1027,22 +1011,22 @@ class Window(QtWidgets.QMainWindow):
.format(self.__main.all_images[v], .format(self.__main.all_images[v],
v)) v))
if result == QtWidgets.QMessageBox.Yes: if result == QtWidgets.QMessageBox.Yes:
self.__main.curr_image_index = v self.main.curr_image_index = v
self.__main.refresh_shown_image() self.main.refresh_shown_image()
self.__tmp_imageid_spinbox: int = v self.__tmp_imageid_spinbox: int = v
def on_delete_image_clicked(self): def on_delete_image_clicked(self):
logging.info("Delete clicked!") logging.info("Delete clicked!")
art_hash = self.__main.get_md5_of_image(self.curr_art_path) art_hash = self.main.get_md5_of_image(self.curr_art_path)
if self.__main.db_connection.get_art_by_hash(art_hash) is not None: if self.main.db_connection.get_art_by_hash(art_hash) is not None:
logging.debug("Delete on known image") logging.debug("Delete on known image")
confirm_result = QtWidgets.QMessageBox.question(self, "Delete data?", "Do you really wish to delete all " confirm_result = QtWidgets.QMessageBox.question(self, "Delete data?", "Do you really wish to delete all "
"data from the DB about this image?") "data from the DB about this image?")
if confirm_result == QtWidgets.QMessageBox.Yes: if confirm_result == QtWidgets.QMessageBox.Yes:
logging.info(f"deleting image data of \"{self.curr_image_title}\"") logging.info(f"deleting image data of \"{self.curr_image_title}\"")
self.__main.db_connection.remove_image(art_hash) self.main.db_connection.remove_image(art_hash)
else: else:
return return
@ -1053,19 +1037,23 @@ class Window(QtWidgets.QMainWindow):
if confirm_result == QtWidgets.QMessageBox.Yes: if confirm_result == QtWidgets.QMessageBox.Yes:
logging.info(f"deleting image file {self.curr_art_path}") logging.info(f"deleting image file {self.curr_art_path}")
self.__main.delete_image(self.curr_art_path) self.main.delete_image(self.curr_art_path)
else: else:
return return
self.__main.refresh_shown_image() self.main.refresh_shown_image()
def on_link_label_activated(self, link: str): def on_link_label_activated(self, link: str):
logging.debug("Source link activated!", link) logging.debug(f"Source link activated! {link}")
QDesktopServices.openUrl(QUrl(link)) QDesktopServices.openUrl(QUrl(link))
def on_image_author_label_activated(self, link: str): def on_image_author_label_activated(self, link: str):
logging.debug("Image author link activated!", link) logging.debug(f"Image author link activated! {link}")
QDesktopServices.openUrl(QUrl(link)) QDesktopServices.openUrl(QUrl(link))
def on_description_change(self): def on_description_change(self):
self.data_changed = True self.data_changed = True
def on_browser_clicked(self):
logging.debug("Clicked on open ArtNet browser!")
self.main.switch_to_browser()

@ -1,104 +0,0 @@
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QDesktopWidget, QToolBar, QPushButton, QGroupBox, QGridLayout
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
class PictureImporter(QMainWindow):
def __init__(self, parent=None, max_relative_resize_width: float = 0.8, max_relative_resize_height: float = 0.8,):
super().__init__(parent)
# Menubar
self.__menu_bar = self.menuBar()
self.__menu_bar.addAction("Action1")
self.__menu_bar.addAction("Action2")
# Toolbar
open = QToolBar()
open.addAction("Open")
self.addToolBar(open)
close = QToolBar()
close.addAction("Close")
self.addToolBar(close)
# layout
self.__layout = QGridLayout()
# Central Component Settings
self.__window = QWidget()
self.setCentralWidget(self.__window)
# Statusbar Settings
self.__status_bar = self.statusBar()
self.__status_bar.showMessage("Welcome to ArtNet! :)", 5000)
label = QLabel("ArtNet - v0.1")
self.__status_bar.addPermanentWidget(label)
self.resize(800, 600)
self.setWindowTitle("ArtNet - Picture Importer")
self.center()
def center(self):
"""
Centers the window in the middle of the screen
:return:
"""
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
@DeprecationWarning
def display_geometry(self):
x = self.x()
y = self.y()
print("x: {0}, y: {1}".format(x, y))
x = self.pos().x()
y = self.pos().y()
print("x: {0}, y: {1}".format(x, y))
x = self.frameGeometry().x()
y = self.frameGeometry().y()
print("x: {0}, y: {1}".format(x, y))
x = self.geometry().x()
y = self.geometry().y()
print("x: {0}, y: {1}".format(x, y))
print("geometry: ", self.geometry())
print("frameGeometry: ", self.frameGeometry())
def set_temporary_status_message(self, text: str, duration: int):
"""
Set a temporary status message (bottom left) for the given duration in milliseconds.
:param text:
:param duration:
:return:
"""
self.__status_bar.showMessage("Welcome to ArtNet! :)", 5000)
def display_image(self, full_path: str):
"""
Display an image in the central widget
:param full_path:
:return:
"""
label = QLabel(self)
pixmap = self.__image_resize(QPixmap(full_path))
label.setPixmap(pixmap)
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
self.center()
def __image_resize(self, pixmap: QPixmap) -> QPixmap:
"""
Resize the given pixmap so that we're not out of the desktop.
:return: new scaled QPixmap
"""
return pixmap
screen_rect = QDesktopWidget().screenGeometry()
print("Resizing pixmap to", int(screen_rect.width()*0.4), int(screen_rect.height()*0.6))
return pixmap.scaled(int(screen_rect.width()*0.6), int(screen_rect.height()*0.7), Qt.KeepAspectRatio)

@ -0,0 +1,57 @@
from PyQt5 import QtWidgets
class ArtnetMainWindow(QtWidgets.QMainWindow):
def __init__(self, main):
super(ArtnetMainWindow, self).__init__()
self.main = main
self.curr_image_title: str = ""
self.setting_up_data: bool = True
self.__data_changed: bool = False
@property
def data_changed(self):
return self.__data_changed
@data_changed.setter
def data_changed(self, v: bool):
self.__data_changed = v
if self.curr_image_title is None:
return
if " (Not in Database)" in self.curr_image_title and v and not self.setting_up_data:
self.curr_image_title = self.curr_image_title.replace(" (Not in Database)", "")
self.setting_up_data = True
self.ui.image_title_line.setText(self.curr_image_title)
self.setting_up_data = False
def display_image(self, image_title: str, image_authors: list, full_path: str, relative_path: str, art_ID: int,
link: str, file_name: str, description: str):
"""
Display an image in the central widget
:param image_authors:
:param image_title:
:param full_path:
:param relative_path:
:param art_ID:
:param link:
:param file_name:
:param description:
:return:
"""
raise NotImplementedError
def set_tag_list(self, tags: list, set_checked: bool = True, no_implication: bool = False):
"""
Set the tags in the tag list to this.
Also updates the tag implication list if no_implication is False
:param tags:
:param set_checked:
:param no_implication: bool indicating if the implication list should also be updated
:return:
"""
raise NotImplementedError
Loading…
Cancel
Save