Fixed Crashes related to recent DB Changes

Fixed a few bugs/crashes that were caused by code still expecting tag name lists being returned by the DB API instead of the new dictionaries.

I should really automate tests or do something to catch these better in the future ...
dev
Peery 2 years ago
parent 1596faee7f
commit 24feb63e5e

@ -165,7 +165,7 @@ class ArtNetManager:
already_applied_tags = self.db_connection.get_art_tags_by_ID(art_ID)
for i in range(len(already_applied_tags)): # converting the list to List[str]
already_applied_tags[i] = self.db_connection.get_tag_by_ID(already_applied_tags[i])[0][1].strip()
already_applied_tags[i] = self.db_connection.get_tag_by_ID(already_applied_tags[i])
importable_tags = []
importable_artists = []
@ -173,23 +173,29 @@ class ArtNetManager:
for i in tags.values():
scraped_tags += i
for tag in scraped_tags:
result = self.db_connection.get_tag_by_name(tag)
if len(result) == 0: # tag does not exist yet
if tag in tags['artists']:
importable_artists.append(tag)
for tag_name in scraped_tags:
result = self.db_connection.get_tag_by_name(tag_name)
if result is None: # tag does not exist yet
if tag_name in tags['artists']:
importable_artists.append(tag_name)
continue
importable_tags.append(tag)
importable_tags.append(tag_name)
continue
if tag in already_applied_tags: # tag is already applied
is_in_applied_tags = False
for t in already_applied_tags:
if t["name"] == tag_name:
is_in_applied_tags = True
if is_in_applied_tags: # tag is already applied
continue
result = self.db_connection.get_tag_impliers_by_name(tag)
result = self.db_connection.get_tag_impliers_by_name(tag_name)
if len(result) != 0: # tag is implied by some other tag
skip = False
for implier_tag_id in result:
implier_tag_id, implier_tag_name, _, _ = self.db_connection.get_tag_by_ID(implier_tag_id)[0]
data = self.db_connection.get_tag_by_ID(implier_tag_id)
implier_tag_id = data["id"]
implier_tag_name = data["name"]
if implier_tag_name.strip() in scraped_tags:
skip = True
@ -197,14 +203,14 @@ class ArtNetManager:
if skip: # skipping the current tag as it is implied by another tag
continue
result = self.db_connection.get_tag_aliases_by_name(tag)
result = self.db_connection.get_tag_aliases_by_name(tag_name)
if len(result) != 0: # tag is already tagged by an alias
continue
if tag in tags['artists']:
importable_artists.append(tag)
if tag_name in tags['artists']:
importable_artists.append(tag_name)
continue
importable_tags.append(tag) # tag must be known and not tagged yet
importable_tags.append(tag_name) # tag must be known and not tagged yet
return importable_tags, importable_artists
@ -216,7 +222,7 @@ class ArtNetManager:
"""
for tag in tags:
if len(self.db_connection.get_tag_by_name(tag)) == 0: # tag doesn't exist yet
if self.db_connection.get_tag_by_name(tag) is None: # tag doesn't exist yet
result = self.import_window.force_edit_tag_dialog(name=tag)
if result is None: # tag creation was aborted
@ -224,8 +230,8 @@ class ArtNetManager:
tag = result['name'] # overwrite with possibly new tag name
tag = self.db_connection.get_tag_by_name(tag)[0][0]
self.import_window.curr_tags.append(tag)
tag_data = self.db_connection.get_tag_by_name(tag)
self.import_window.curr_tags.append(tag_data)
self.import_window.data_changed = True
def get_md5_of_image(self, path: str):
@ -416,8 +422,7 @@ class ArtNetManager:
self.all_images[self.curr_image_index],
art_ID, image_link, file_name=s[-1], description=image_description,
collections=collections)
tmp = [self.db_connection.get_tag_by_ID(x) for x in self.db_connection.get_art_tags_by_ID(art_ID)]
tags = [{"id": int(t[0][0]), "name": t[0][1].strip(), "description": t[0][2].strip(), "category": t[0][3]} for t in tmp]
tags = [self.db_connection.get_tag_by_ID(x) for x in self.db_connection.get_art_tags_by_ID(art_ID)]
self.curr_active_window.set_tag_list(tags)
self.curr_active_window.data_changed = False

@ -73,7 +73,7 @@ class DBAdapter:
:return:
"""
logging.debug("Saving Image {0}:{1} authors: {2} path: {3} tags: {4} link: {5} hash:{6} desc:{7}"
.format(ID, title, authors, path, tags, link, md5_hash, desc))
.format(ID, title, authors, path, [t["name"] for t in tags], link, md5_hash, desc))
d = {"title": title, "path": path, "id": ID, "link": link, "hash": md5_hash, "desc": desc} # TODO implement try/except for database errors and rollback!
if self.get_art_by_path(path) is None:
if ID is None:
@ -98,11 +98,11 @@ class DBAdapter:
ID = self.get_art_by_path(path)["ID"]
assert (ID != None) # was checked before, should never fail
old_tags = [self.get_tag_by_ID(x)[0][1].strip() for x in self.get_art_tags_by_ID(ID)]
old_tags = [self.get_tag_by_ID(x)["name"].strip() for x in self.get_art_tags_by_ID(ID)]
for tag in tags:
if tag in old_tags: # already present
continue
d = {"id": ID, "tag": self.get_tag_ID(tag)}
d = {"id": ID, "tag": tag["id"]}
try:
self.db_cursor.execute("INSERT INTO art_to_tag (art_id, tag_ID) VALUES (%(id)s, %(tag)s)", d)
self.db.commit()
@ -115,7 +115,11 @@ class DBAdapter:
raise e
for old_tag in old_tags:
if old_tag not in tags: # need to remove old tag
is_in_tags = False
for t in tags:
if t["name"] == old_tag:
is_in_tags = True
if not is_in_tags: # need to remove old tag
self.remove_tag_from_image(art_ID=ID, tag_ID=self.get_tag_ID(old_tag))
old_authors = self.get_authors_of_art_by_ID(ID)
@ -831,7 +835,7 @@ class DBAdapter:
return rows[0]
def get_tag_by_name(self, name: str) -> list:
def get_tag_by_name(self, name: str) -> dict:
"""
Search the tag in the DB via its name.
@ -843,9 +847,11 @@ class DBAdapter:
self.db_cursor.execute(
"SELECT name, description, category_id, ID FROM tag where LOWER(name) = LOWER(%(name)s)", d)
rows = []
for row in self.db_cursor.fetchall():
new_row = []
row = self.db_cursor.fetchall()
if len(row) == 0:
return None
row = row[0]
for value in row:
if value is None:
new_row.append("")
@ -853,10 +859,9 @@ class DBAdapter:
new_row.append(value.strip())
else:
new_row.append(value)
rows.append(new_row)
return rows
return {"name": new_row[0], "description": new_row[1], "category": new_row[2], "id": new_row[3]}
def get_tag_by_ID(self, ID: int) -> list:
def get_tag_by_ID(self, ID: int) -> dict:
"""
Search the tag in the DB via its ID.
@ -867,9 +872,21 @@ class DBAdapter:
d = {"ID": ID}
self.db_cursor.execute("SELECT ID, name, description, category_id FROM tag where ID = %(ID)s", d)
return self.db_cursor.fetchall()
new_row = []
rows = self.db_cursor.fetchall()
if len(rows) != 1:
raise Exception("Something went terribly wrong!")
row = rows[0]
for value in row:
if value is None:
new_row.append("")
elif type(value) == str:
new_row.append(value.strip())
else:
new_row.append(value)
return {"name": new_row[1], "description": new_row[2], "category": new_row[3], "id": new_row[0]}
def get_tag_aliases_by_name(self, name: str) -> list:
def get_tag_aliases_by_name(self, name: str) -> List[dict]:
"""
Search for the tag's aliases and the alias's aliases
:param name:
@ -880,7 +897,7 @@ class DBAdapter:
for alias in aliases:
tag_data = self.get_tag_by_ID(alias)
if len(tag_data) > 0: # tag exists
result.append(tag_data[0][1].strip())
result.append(tag_data)
return result
def get_tag_aliases_by_ID(self, tag_ID: int) -> list:
@ -931,8 +948,7 @@ class DBAdapter:
for tag_ID in collected_tags:
tag_data = self.get_tag_by_ID(tag_ID)
if len(tag_data) != 0:
result.append({"name": tag_data[0][1].strip(), "id": int(tag_data[0][0]),
"description": tag_data[0][2].strip(), "category": int(tag_data[0][3])})
result.append(tag_data)
return result
def get_all_tag_impliers_by_ID(self, ID: int) -> list:

@ -1,7 +1,10 @@
from typing import List
import validators
import os
import logging
import re
import json
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QSize, QUrl
@ -493,7 +496,7 @@ class ImporterWindow(ArtnetMainWindow):
"""
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[dict]):
"""
Set the tags in the search result list to tags
:param tags:
@ -510,9 +513,21 @@ class ImporterWindow(ArtnetMainWindow):
if tag_name not in self.curr_implied_tags:
# new tag and not implied yet
item.setData(Qt.Unchecked, Qt.CheckStateRole)
item.setToolTip(f"Tag ID: {tag['id']}\n\n"+tag["description"]+f"\nCategory: {tag['category']}")
if 'id' in tag.keys() and 'description' in tag.keys() and 'category' in tag.keys():
s = f"Tag ID: {tag['id']}\n\n"
if len(tag["description"]) != 0:
s += tag["description"]+"\n\n"
s += f"Category: {tag['category']}"
item.setToolTip(s)
item.setData(json.dumps(tag), Qt.UserRole)
flags |= Qt.ItemIsUserCheckable
if self.curr_tags is not None and tag_name in (self.curr_tags + self.curr_implied_tags + self.curr_tag_aliases):
is_in_tags = False
for i in range(len((self.curr_tags + self.curr_implied_tags + self.curr_tag_aliases))):
if item.text() == (self.curr_tags + self.curr_implied_tags + self.curr_tag_aliases)[i]["name"]:
is_in_tags = True
if self.curr_tags is not None and is_in_tags:
# already selected, implied or aliased tags
item.setCheckState(Qt.Checked)
item.setFlags(flags)
@ -555,7 +570,12 @@ class ImporterWindow(ArtnetMainWindow):
if tag_name not in self.curr_implied_tags:
# new tag and not implied yet
item.setData(Qt.Unchecked, Qt.CheckStateRole)
item.setToolTip(f"Tag ID: {tag['id']}\n\n" + tag["description"] + f"\nCategory: {tag['category']}")
if 'id' in tag.keys() and 'description' in tag.keys() and 'category' in tag.keys():
s = f"Tag ID: {tag['id']}\n\n"
if len(tag["description"]) != 0:
s += tag["description"] + "\n\n"
s += f"Category: {tag['category']}"
item.setToolTip(s)
flags |= Qt.ItemIsUserCheckable
if set_checked:
@ -588,7 +608,12 @@ class ImporterWindow(ArtnetMainWindow):
else:
done.append(tag_name)
item = QStandardItem(tag_name)
item.setToolTip(f"Tag ID: {tag['id']}\n\n"+tag["description"]+f"\nCategory: {tag['category']}")
if 'id' in tag.keys() and 'description' in tag.keys() and 'category' in tag.keys():
s = f"Tag ID: {tag['id']}\n\n"
if len(tag["description"]) != 0:
s += tag["description"] + "\n\n"
s += f"Category: {tag['category']}"
item.setToolTip(s)
item_model.appendRow(item)
self.ui.implied_tag_list.setModel(item_model)
@ -764,15 +789,15 @@ class ImporterWindow(ArtnetMainWindow):
if self.ui.search_result_list.model().rowCount() == 1: # only 1 search result left
model_index = self.ui.search_result_list.model().index(0, 0)
item_data = self.ui.search_result_list.model().itemData(model_index)
item_data = json.loads(self.ui.search_result_list.model().itemData(model_index)[Qt.UserRole])
if item_data[0] not in self.curr_tags: # add/remove new selected tag to the lists
self.curr_tags.append(item_data[0])
if item_data not in self.curr_tags: # add/remove new selected tag to the lists
self.curr_tags.append(item_data)
else:
self.curr_tags.remove(item_data[0])
self.curr_tags.remove(item_data)
self.set_tag_list(self.curr_tags) # update relevant lists
self.set_tag_search_result_list([item_data[0]])
self.set_tag_search_result_list([item_data])
logging.debug(item_data)
def on_movie_player_state_changed(self, state: int):
@ -823,8 +848,8 @@ class ImporterWindow(ArtnetMainWindow):
i = 0
while i < len(tags): # workaround for an issue with altering lists during iteration
r = self.main.db_connection.get_tag_by_name(tags[i])
if len(r) > 0:
self.curr_tags.append(tags[i])
if r is not None:
self.curr_tags.append(r)
self.data_changed = True
tags.remove(tags[i])
continue
@ -995,9 +1020,10 @@ class ImporterWindow(ArtnetMainWindow):
"No tag is allowed without a category!")
return None
if len(self.get_tag(tag_data['name'])) > 0:
if self.get_tag(tag_data['name']) is not None:
QtWidgets.QMessageBox.information(self, "Tag already exists",
"The Tag \"{0}\" you wanted to create already exists! Skipping...")
f"The Tag \"{tag_data['name']}\" you wanted to create already exists! Skipping...")
return None
else:
self.main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"],
aliases=tag_data["aliases"], implications=tag_data["implications"],
@ -1043,7 +1069,8 @@ class ImporterWindow(ArtnetMainWindow):
def on_tag_search_item_changed(self, item: QStandardItem):
if item.checkState() == Qt.Checked:
self.curr_tags.append(item.text())
tag_data = self.main.db_connection.get_tag_by_name(item.text())
self.curr_tags.append(tag_data)
aliases = self.main.db_connection.get_tag_aliases_by_name(item.text())
for alias in aliases:
@ -1052,15 +1079,20 @@ class ImporterWindow(ArtnetMainWindow):
for implication in implications:
self.curr_tags.append(implication)
if item.checkState() == Qt.Unchecked:
if item.text() in self.curr_tags:
self.curr_tags.remove(item.text())
is_in_tags = False
for i in range(len(self.curr_tags)):
if item.text() == self.curr_tags[i]["name"]:
tags_index = i
is_in_tags = True
if is_in_tags:
self.curr_tags.pop(tags_index)
aliases = self.main.db_connection.get_tag_aliases_by_name(item.text())
for alias in aliases:
if alias in self.curr_tags:
self.curr_tags.remove(alias)
implications = self.main.db_connection.get_all_tag_implications_by_name(item.text())
for implication in implications:
self.curr_tags.remove(implication)
self.curr_tags.remove({"name": implication})
else:
raise Exception("Something went terribly wrong!")
@ -1070,13 +1102,22 @@ class ImporterWindow(ArtnetMainWindow):
def on_tag_item_changed(self, item: QStandardItem):
logging.debug("Item {0} has changed!".format(item.text()))
if item.checkState() == Qt.Unchecked:
if item.text() in self.curr_tags:
is_in_tags = False
for i in range(len(self.curr_tags)):
if item.text() == self.curr_tags[i]["name"]:
tags_index = i
is_in_tags = True
if is_in_tags:
aliases = self.main.db_connection.get_tag_aliases_by_name(item.text())
if len(aliases) > 0: # tag has aliases, might need to also remove them
for alias in aliases:
self.curr_tags.remove(alias)
self.curr_tags.remove(item.text())
for i in range(len(self.curr_tags)):
if item.text() == self.curr_tags[i]["name"]:
tags_index = i
self.curr_tags.pop(tags_index)
self.set_tag_list(self.curr_tags)
self.on_tag_search_change()
else:

Loading…
Cancel
Save