Update pre-commit
This commit is contained in:
parent
5e86605a46
commit
4eb9e008ce
@ -14,21 +14,21 @@ repos:
|
||||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.10.1
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
args: [--af,--add-import, 'from __future__ import annotations']
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.2.2
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.10.0
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/PyCQA/autoflake
|
||||
rev: v1.7.7
|
||||
rev: v2.0.1
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args: [-i, --remove-all-unused-imports, --ignore-init-module-imports]
|
||||
|
@ -84,7 +84,6 @@ class RarArchiver(Archiver):
|
||||
return False
|
||||
|
||||
def read_file(self, archive_file: str) -> bytes:
|
||||
|
||||
rarc = self.get_rar_obj()
|
||||
if rarc is None:
|
||||
return b""
|
||||
|
@ -148,7 +148,6 @@ class ZipArchiver(Archiver):
|
||||
|
||||
try:
|
||||
with open(filename, mode="r+b") as file:
|
||||
|
||||
# the starting position, relative to EOF
|
||||
pos = -4
|
||||
found = False
|
||||
@ -167,7 +166,6 @@ class ZipArchiver(Archiver):
|
||||
pos = pos - 1
|
||||
|
||||
if found:
|
||||
|
||||
# now skip forward 20 bytes to the comment length word
|
||||
pos += 20
|
||||
file.seek(pos, 2)
|
||||
|
@ -26,7 +26,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CoMet:
|
||||
|
||||
writer_synonyms = ["writer", "plotter", "scripter"]
|
||||
penciller_synonyms = ["artist", "penciller", "penciler", "breakdowns"]
|
||||
inker_synonyms = ["inker", "artist", "finishes"]
|
||||
@ -44,7 +43,6 @@ class CoMet:
|
||||
return str(ET.tostring(tree.getroot(), encoding="utf-8", xml_declaration=True).decode("utf-8"))
|
||||
|
||||
def convert_metadata_to_xml(self, metadata: GenericMetadata) -> ET.ElementTree:
|
||||
|
||||
# shorthand for the metadata
|
||||
md = metadata
|
||||
|
||||
@ -97,7 +95,6 @@ class CoMet:
|
||||
|
||||
# loop thru credits, and build a list for each role that CoMet supports
|
||||
for credit in metadata.credits:
|
||||
|
||||
if credit["role"].casefold() in set(self.writer_synonyms):
|
||||
ET.SubElement(root, "writer").text = str(credit["person"])
|
||||
|
||||
|
@ -79,11 +79,7 @@ class MetaDataStyle:
|
||||
class ComicArchive:
|
||||
logo_data = b""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path: pathlib.Path | str,
|
||||
default_image_path: pathlib.Path | str | None = None,
|
||||
) -> None:
|
||||
def __init__(self, path: pathlib.Path | str, default_image_path: pathlib.Path | str | None = None) -> None:
|
||||
self.cbi_md: GenericMetadata | None = None
|
||||
self.cix_md: GenericMetadata | None = None
|
||||
self.comet_filename: str | None = None
|
||||
@ -166,7 +162,6 @@ class ComicArchive:
|
||||
return self.archiver.extension()
|
||||
|
||||
def read_metadata(self, style: int) -> GenericMetadata:
|
||||
|
||||
if style == MetaDataStyle.CIX:
|
||||
return self.read_cix()
|
||||
if style == MetaDataStyle.CBI:
|
||||
@ -416,7 +411,6 @@ class ComicArchive:
|
||||
|
||||
def has_cix(self) -> bool:
|
||||
if self._has_cix is None:
|
||||
|
||||
if not self.seems_to_be_a_comic_archive():
|
||||
self._has_cix = False
|
||||
elif self.ci_xml_filename in self.archiver.get_filename_list():
|
||||
@ -463,7 +457,6 @@ class ComicArchive:
|
||||
return raw_comet
|
||||
|
||||
def write_comet(self, metadata: GenericMetadata) -> bool:
|
||||
|
||||
if metadata is not None:
|
||||
if not self.has_comet():
|
||||
self.comet_filename = self.comet_default_filename
|
||||
@ -556,7 +549,6 @@ class ComicArchive:
|
||||
remove_publisher: bool = False,
|
||||
split_words: bool = False,
|
||||
) -> GenericMetadata:
|
||||
|
||||
metadata = GenericMetadata()
|
||||
|
||||
filename = self.path.name
|
||||
|
@ -75,7 +75,6 @@ CBIContainer = TypedDict("CBIContainer", {"appID": str, "lastModified": str, "Co
|
||||
|
||||
class ComicBookInfo:
|
||||
def metadata_from_string(self, string: str) -> GenericMetadata:
|
||||
|
||||
cbi_container = json.loads(string)
|
||||
|
||||
metadata = GenericMetadata()
|
||||
|
@ -28,7 +28,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ComicInfoXml:
|
||||
|
||||
writer_synonyms = ["writer", "plotter", "scripter"]
|
||||
penciller_synonyms = ["artist", "penciller", "penciler", "breakdowns"]
|
||||
inker_synonyms = ["inker", "artist", "finishes"]
|
||||
@ -49,7 +48,6 @@ class ComicInfoXml:
|
||||
return parsable_credits
|
||||
|
||||
def metadata_from_string(self, string: bytes) -> GenericMetadata:
|
||||
|
||||
tree = ET.ElementTree(ET.fromstring(string))
|
||||
return self.convert_xml_to_metadata(tree)
|
||||
|
||||
@ -59,7 +57,6 @@ class ComicInfoXml:
|
||||
return str(tree_str)
|
||||
|
||||
def convert_metadata_to_xml(self, metadata: GenericMetadata, xml: bytes = b"") -> ElementTree:
|
||||
|
||||
# shorthand for the metadata
|
||||
md = metadata
|
||||
|
||||
@ -113,7 +110,6 @@ class ComicInfoXml:
|
||||
# first, loop thru credits, and build a list for each role that CIX
|
||||
# supports
|
||||
for credit in metadata.credits:
|
||||
|
||||
if credit["role"].casefold() in set(self.writer_synonyms):
|
||||
credit_writer_list.append(credit["person"].replace(",", ""))
|
||||
|
||||
@ -178,7 +174,6 @@ class ComicInfoXml:
|
||||
return tree
|
||||
|
||||
def convert_xml_to_metadata(self, tree: ElementTree) -> GenericMetadata:
|
||||
|
||||
root = tree.getroot()
|
||||
|
||||
if root.tag != "ComicInfo":
|
||||
|
@ -65,7 +65,6 @@ class FileNameParser:
|
||||
return string
|
||||
|
||||
def get_issue_count(self, filename: str, issue_end: int) -> str:
|
||||
|
||||
count = ""
|
||||
filename = filename[issue_end:]
|
||||
|
||||
@ -237,7 +236,6 @@ class FileNameParser:
|
||||
return series.strip().strip("-_.").strip(), volume.strip()
|
||||
|
||||
def get_year(self, filename: str, issue_end: int) -> str:
|
||||
|
||||
filename = filename[issue_end:]
|
||||
|
||||
year = ""
|
||||
@ -275,7 +273,6 @@ class FileNameParser:
|
||||
return remainder.strip()
|
||||
|
||||
def parse_filename(self, filename: str) -> None:
|
||||
|
||||
# remove the path
|
||||
filename = os.path.basename(filename)
|
||||
|
||||
@ -1043,7 +1040,6 @@ def parse_info_specifier(p: Parser) -> Callable[[Parser], Callable | None] | Non
|
||||
if p.peek().typ == filenamelexer.ItemType.Number or (
|
||||
p.peek().typ == filenamelexer.ItemType.Text and t2d.convert(p.peek().val).isnumeric()
|
||||
):
|
||||
|
||||
number = p.get()
|
||||
if item.val.casefold() in ["volume", "vol", "vol.", "v"]:
|
||||
p.filename_info["volume"] = t2do.convert(number.val)
|
||||
|
@ -253,7 +253,6 @@ class GenericMetadata:
|
||||
return coverlist
|
||||
|
||||
def add_credit(self, person: str, role: str, primary: bool = False) -> None:
|
||||
|
||||
credit = CreditMetadata(person=person, role=role, primary=primary)
|
||||
|
||||
# look to see if it's not already there...
|
||||
|
@ -27,7 +27,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class IssueString:
|
||||
def __init__(self, text: str | None) -> None:
|
||||
|
||||
# break up the issue number string into 2 parts: the numeric and suffix string.
|
||||
# (assumes that the numeric portion is always first)
|
||||
|
||||
|
@ -64,7 +64,6 @@ def get_recursive_filelist(pathlist: list[str]) -> list[str]:
|
||||
|
||||
filelist: list[str] = []
|
||||
for p in pathlist:
|
||||
|
||||
if os.path.isdir(p):
|
||||
filelist.extend(x for x in glob.glob(f"{p}{os.sep}/**", recursive=True) if not os.path.isdir(x))
|
||||
elif str(p) not in filelist:
|
||||
|
@ -91,7 +91,6 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
|
||||
self.update_data()
|
||||
|
||||
def update_data(self) -> None:
|
||||
|
||||
self.current_match_set = self.match_set_list[self.current_match_set_idx]
|
||||
|
||||
if self.current_match_set_idx + 1 == len(self.match_set_list):
|
||||
@ -174,7 +173,6 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
|
||||
self.accept()
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex, prev: QtCore.QModelIndex) -> None:
|
||||
|
||||
if curr is None:
|
||||
return None
|
||||
if prev is not None and prev.row() == curr.row():
|
||||
@ -199,7 +197,6 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
|
||||
return match
|
||||
|
||||
def accept(self) -> None:
|
||||
|
||||
self.save_match()
|
||||
self.current_match_set_idx += 1
|
||||
|
||||
@ -233,7 +230,6 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
|
||||
QtWidgets.QDialog.reject(self)
|
||||
|
||||
def save_match(self) -> None:
|
||||
|
||||
match = self.current_match()
|
||||
ca = self.current_match_set.ca
|
||||
|
||||
|
@ -42,7 +42,6 @@ class CBLTransformer:
|
||||
append_to_tags_if_unique(item)
|
||||
|
||||
if self.config.cbl_assume_lone_credit_is_primary:
|
||||
|
||||
# helper
|
||||
def set_lone_primary(role_list: list[str]) -> tuple[CreditMetadata | None, int]:
|
||||
lone_credit: CreditMetadata | None = None
|
||||
|
@ -90,7 +90,7 @@ class CLI:
|
||||
# sort match list by year
|
||||
match_set.matches.sort(key=lambda k: k["year"] or 0)
|
||||
|
||||
for (counter, m) in enumerate(match_set.matches):
|
||||
for counter, m in enumerate(match_set.matches):
|
||||
counter += 1
|
||||
print(
|
||||
" {}. {} #{} [{}] ({}/{}) - {}".format(
|
||||
|
@ -40,7 +40,6 @@ def clickable(widget: QtWidgets.QWidget) -> QtCore.pyqtBoundSignal:
|
||||
"""Allow a label to be clickable"""
|
||||
|
||||
class Filter(QtCore.QObject):
|
||||
|
||||
dblclicked = QtCore.pyqtSignal()
|
||||
|
||||
def eventFilter(self, obj: QtCore.QObject, event: QtCore.QEvent) -> bool:
|
||||
|
@ -39,13 +39,7 @@ def initial_commandline_parser() -> argparse.ArgumentParser:
|
||||
type=ComicTaggerPaths,
|
||||
default=ComicTaggerPaths(),
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="count",
|
||||
default=0,
|
||||
help="Be noisy when doing what it does.",
|
||||
)
|
||||
parser.add_argument("-v", "--verbose", action="count", default=0, help="Be noisy when doing what it does.")
|
||||
return parser
|
||||
|
||||
|
||||
@ -162,26 +156,9 @@ def register_settings(parser: settngs.Manager) -> None:
|
||||
help="Don't actually modify file (only relevant for -d, -s, or -r).\n\n",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting(
|
||||
"--darkmode",
|
||||
action="store_true",
|
||||
help="Windows only. Force a dark pallet",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting(
|
||||
"-g",
|
||||
"--glob",
|
||||
action="store_true",
|
||||
help="Windows only. Enable globbing",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting(
|
||||
"--quiet",
|
||||
"-q",
|
||||
action="store_true",
|
||||
help="Don't say much (for print mode).",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting("--darkmode", action="store_true", help="Windows only. Force a dark pallet", file=False)
|
||||
parser.add_setting("-g", "--glob", action="store_true", help="Windows only. Enable globbing", file=False)
|
||||
parser.add_setting("--quiet", "-q", action="store_true", help="Don't say much (for print mode).", file=False)
|
||||
|
||||
parser.add_setting(
|
||||
"-t",
|
||||
@ -204,12 +181,7 @@ def register_settings(parser: settngs.Manager) -> None:
|
||||
|
||||
|
||||
def register_commands(parser: settngs.Manager) -> None:
|
||||
parser.add_setting(
|
||||
"--version",
|
||||
action="store_true",
|
||||
help="Display version.",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting("--version", action="store_true", help="Display version.", file=False)
|
||||
|
||||
parser.add_setting(
|
||||
"-p",
|
||||
|
@ -86,11 +86,7 @@ def filename(parser: settngs.Manager) -> None:
|
||||
def talker(parser: settngs.Manager) -> None:
|
||||
# General settings for talkers
|
||||
parser.add_setting("--source", default="comicvine", help="Use a specified source by source ID")
|
||||
parser.add_setting(
|
||||
"--series-match-search-thresh",
|
||||
default=90,
|
||||
type=int,
|
||||
)
|
||||
parser.add_setting("--series-match-search-thresh", default=90, type=int)
|
||||
parser.add_setting(
|
||||
"--clear-metadata",
|
||||
default=True,
|
||||
@ -178,11 +174,7 @@ def rename(parser: settngs.Manager) -> None:
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Ensures that filenames are valid for all OSs",
|
||||
)
|
||||
parser.add_setting(
|
||||
"replacements",
|
||||
default=DEFAULT_REPLACEMENTS,
|
||||
cmdline=False,
|
||||
)
|
||||
parser.add_setting("replacements", default=DEFAULT_REPLACEMENTS, cmdline=False)
|
||||
|
||||
|
||||
def autotag(parser: settngs.Manager) -> None:
|
||||
|
@ -105,7 +105,6 @@ class MetadataFormatter(string.Formatter):
|
||||
result = []
|
||||
lstrip = False
|
||||
for literal_text, field_name, format_spec, conversion in self.parse(format_string):
|
||||
|
||||
# output the literal text
|
||||
if literal_text:
|
||||
if lstrip:
|
||||
|
@ -180,7 +180,6 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
self.listCleared.emit()
|
||||
|
||||
def add_path_list(self, pathlist: list[str]) -> None:
|
||||
|
||||
filelist = utils.get_recursive_filelist(pathlist)
|
||||
# we now have a list of files to add
|
||||
|
||||
|
@ -46,11 +46,9 @@ def fetch_complete(image_data: bytes | QtCore.QByteArray) -> None:
|
||||
|
||||
|
||||
class ImageFetcher:
|
||||
|
||||
image_fetch_complete = fetch_complete
|
||||
|
||||
def __init__(self, cache_folder: pathlib.Path) -> None:
|
||||
|
||||
self.db_file = cache_folder / "image_url_cache.db"
|
||||
self.cache_folder = cache_folder / "image_cache"
|
||||
|
||||
@ -117,7 +115,6 @@ class ImageFetcher:
|
||||
ImageFetcher.image_fetch_complete(image_data)
|
||||
|
||||
def create_image_db(self) -> None:
|
||||
|
||||
# this will wipe out any existing version
|
||||
open(self.db_file, "wb").close()
|
||||
|
||||
@ -135,7 +132,6 @@ class ImageFetcher:
|
||||
cur.execute("CREATE TABLE Images(url TEXT,filename TEXT,timestamp TEXT,PRIMARY KEY (url))")
|
||||
|
||||
def add_image_to_cache(self, url: str, image_data: bytes | QtCore.QByteArray) -> None:
|
||||
|
||||
con = lite.connect(self.db_file)
|
||||
|
||||
with con:
|
||||
@ -150,7 +146,6 @@ class ImageFetcher:
|
||||
cur.execute("INSERT or REPLACE INTO Images VALUES(?, ?, ?)", (url, filename, timestamp))
|
||||
|
||||
def get_image_from_cache(self, url: str) -> bytes:
|
||||
|
||||
con = lite.connect(self.db_file)
|
||||
with con:
|
||||
cur = con.cursor()
|
||||
|
@ -149,7 +149,6 @@ class IssueIdentifier:
|
||||
return 1.5
|
||||
|
||||
def crop_cover(self, image_data: bytes) -> bytes:
|
||||
|
||||
im = Image.open(io.BytesIO(image_data))
|
||||
w, h = im.size
|
||||
|
||||
@ -215,7 +214,6 @@ class IssueIdentifier:
|
||||
self.cover_url_callback = cb_func
|
||||
|
||||
def get_search_keys(self) -> SearchKeys:
|
||||
|
||||
ca = self.comic_archive
|
||||
|
||||
search_keys: SearchKeys
|
||||
|
@ -115,7 +115,6 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
break
|
||||
|
||||
def perform_query(self) -> None:
|
||||
|
||||
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CursorShape.WaitCursor))
|
||||
|
||||
try:
|
||||
@ -179,7 +178,6 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
self.accept()
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex | None, prev: QtCore.QModelIndex | None) -> None:
|
||||
|
||||
if curr is None:
|
||||
return
|
||||
if prev is not None and prev.row() == curr.row():
|
||||
|
@ -76,7 +76,6 @@ class MatchSelectionWindow(QtWidgets.QDialog):
|
||||
self.update_data()
|
||||
|
||||
def update_data(self) -> None:
|
||||
|
||||
self.set_cover_image()
|
||||
self.populate_table()
|
||||
self.twList.resizeColumnsToContents()
|
||||
@ -86,7 +85,6 @@ class MatchSelectionWindow(QtWidgets.QDialog):
|
||||
self.setWindowTitle(f"Select correct match: {os.path.split(path)[1]}")
|
||||
|
||||
def populate_table(self) -> None:
|
||||
|
||||
self.twList.setRowCount(0)
|
||||
|
||||
self.twList.setSortingEnabled(False)
|
||||
@ -145,7 +143,6 @@ class MatchSelectionWindow(QtWidgets.QDialog):
|
||||
self.accept()
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex, prev: QtCore.QModelIndex) -> None:
|
||||
|
||||
if curr is None:
|
||||
return
|
||||
if prev is not None and prev.row() == curr.row():
|
||||
|
@ -93,7 +93,6 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
|
||||
@staticmethod
|
||||
def msg(parent: QtWidgets.QWidget, title: str, msg: str, checked: bool = False, check_text: str = "") -> bool:
|
||||
|
||||
d = OptionalMessageDialog(parent, StyleMessage, title, msg, checked=checked, check_text=check_text)
|
||||
|
||||
d.exec()
|
||||
@ -103,7 +102,6 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
def question(
|
||||
parent: QtWidgets.QWidget, title: str, msg: str, checked: bool = False, check_text: str = ""
|
||||
) -> tuple[bool, bool]:
|
||||
|
||||
d = OptionalMessageDialog(parent, StyleQuestion, title, msg, checked=checked, check_text=check_text)
|
||||
|
||||
d.exec()
|
||||
@ -114,7 +112,6 @@ class OptionalMessageDialog(QtWidgets.QDialog):
|
||||
def msg_no_checkbox(
|
||||
parent: QtWidgets.QWidget, title: str, msg: str, checked: bool = False, check_text: str = ""
|
||||
) -> bool:
|
||||
|
||||
d = OptionalMessageDialog(parent, StyleMessage, title, msg, checked=checked, check_text=check_text)
|
||||
d.theCheckBox.hide()
|
||||
|
||||
|
@ -80,7 +80,6 @@ class PageBrowserWindow(QtWidgets.QDialog):
|
||||
self.pageWidget.clear()
|
||||
|
||||
def set_comic_archive(self, ca: ComicArchive) -> None:
|
||||
|
||||
self.comic_archive = ca
|
||||
self.page_count = ca.get_number_of_pages()
|
||||
self.current_page_num = 0
|
||||
@ -92,7 +91,6 @@ class PageBrowserWindow(QtWidgets.QDialog):
|
||||
self.btnPrev.setEnabled(True)
|
||||
|
||||
def next_page(self) -> None:
|
||||
|
||||
if self.current_page_num + 1 < self.page_count:
|
||||
self.current_page_num += 1
|
||||
else:
|
||||
@ -100,7 +98,6 @@ class PageBrowserWindow(QtWidgets.QDialog):
|
||||
self.set_page()
|
||||
|
||||
def prev_page(self) -> None:
|
||||
|
||||
if self.current_page_num - 1 >= 0:
|
||||
self.current_page_num -= 1
|
||||
else:
|
||||
|
@ -29,11 +29,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
def item_move_events(widget: QtWidgets.QWidget) -> QtCore.pyqtBoundSignal:
|
||||
class Filter(QtCore.QObject):
|
||||
|
||||
mysignal = QtCore.pyqtSignal(str)
|
||||
|
||||
def eventFilter(self, obj: QtCore.QObject, event: QtCore.QEvent) -> bool:
|
||||
|
||||
if obj == widget:
|
||||
if event.type() == QtCore.QEvent.Type.ChildRemoved:
|
||||
self.mysignal.emit("finish")
|
||||
|
@ -113,9 +113,7 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
return
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
"Formatter failure: %s metadata: %s",
|
||||
self.config[0].rename_template,
|
||||
self.renamer.metadata,
|
||||
"Formatter failure: %s metadata: %s", self.config[0].rename_template, self.renamer.metadata
|
||||
)
|
||||
QtWidgets.QMessageBox.critical(
|
||||
self,
|
||||
@ -170,7 +168,6 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
self.do_preview()
|
||||
|
||||
def accept(self) -> None:
|
||||
|
||||
prog_dialog = QtWidgets.QProgressDialog("", "Cancel", 0, len(self.rename_list), self)
|
||||
prog_dialog.setWindowTitle("Renaming Archives")
|
||||
prog_dialog.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
||||
@ -180,7 +177,6 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
|
||||
try:
|
||||
for idx, comic in enumerate(zip(self.comic_archive_list, self.rename_list)):
|
||||
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
if prog_dialog.wasCanceled():
|
||||
break
|
||||
|
@ -44,12 +44,7 @@ class SearchThread(QtCore.QThread):
|
||||
progressUpdate = pyqtSignal(int, int)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
talker: ComicTalker,
|
||||
series_name: str,
|
||||
refresh: bool,
|
||||
literal: bool = False,
|
||||
series_match_thresh: int = 90,
|
||||
self, talker: ComicTalker, series_name: str, refresh: bool, literal: bool = False, series_match_thresh: int = 90
|
||||
) -> None:
|
||||
QtCore.QThread.__init__(self)
|
||||
self.talker = talker
|
||||
@ -210,7 +205,6 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
self.perform_query(refresh=False)
|
||||
|
||||
def auto_select(self) -> None:
|
||||
|
||||
if self.comic_archive is None:
|
||||
QtWidgets.QMessageBox.information(self, "Auto-Select", "You need to load a comic first!")
|
||||
return
|
||||
@ -263,7 +257,6 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
|
||||
def identify_complete(self) -> None:
|
||||
if self.ii is not None and self.iddialog is not None and self.comic_archive is not None:
|
||||
|
||||
matches = self.ii.match_list
|
||||
result = self.ii.search_result
|
||||
|
||||
@ -341,7 +334,6 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
break
|
||||
|
||||
def perform_query(self, refresh: bool = False) -> None:
|
||||
|
||||
self.search_thread = SearchThread(
|
||||
self.talker, self.series_name, refresh, self.literal, self.config.talker_series_match_search_thresh
|
||||
)
|
||||
@ -525,7 +517,6 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
self.show_issues()
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex | None, prev: QtCore.QModelIndex | None) -> None:
|
||||
|
||||
if curr is None:
|
||||
return
|
||||
if prev is not None and prev.row() == curr.row():
|
||||
|
@ -495,7 +495,6 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
QtWidgets.QMessageBox.information(self, self.name, self.name + " have been returned to default values.")
|
||||
|
||||
def select_file(self, control: QtWidgets.QLineEdit, name: str) -> None:
|
||||
|
||||
dialog = QtWidgets.QFileDialog(self)
|
||||
dialog.setFileMode(QtWidgets.QFileDialog.FileMode.ExistingFile)
|
||||
|
||||
|
@ -293,7 +293,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
return qapplogwindow
|
||||
|
||||
def reset_app(self) -> None:
|
||||
|
||||
self.archiveCoverWidget.clear()
|
||||
self.comic_archive = None
|
||||
self.dirty_flag = False
|
||||
@ -309,7 +308,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.page_loader = None
|
||||
|
||||
def update_app_title(self) -> None:
|
||||
|
||||
self.setWindowIcon(QtGui.QIcon(str(graphics_path / "app.png")))
|
||||
|
||||
if self.comic_archive is None:
|
||||
@ -327,7 +325,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.setWindowTitle(f"{self.appName} - {self.comic_archive.path}{mod_str}{ro_str}")
|
||||
|
||||
def config_menus(self) -> None:
|
||||
|
||||
# File Menu
|
||||
self.actionExit.setShortcut("Ctrl+Q")
|
||||
self.actionExit.setStatusTip("Exit application")
|
||||
@ -570,7 +567,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
dlg.exec()
|
||||
|
||||
def about_app(self) -> None:
|
||||
|
||||
website = "https://github.com/comictagger/comictagger"
|
||||
email = "comictagger@gmail.com"
|
||||
license_link = "http://www.apache.org/licenses/LICENSE-2.0"
|
||||
@ -597,7 +593,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
def dragEnterEvent(self, event: QtGui.QDragEnterEvent) -> None:
|
||||
self.droppedFiles = []
|
||||
if event.mimeData().hasUrls():
|
||||
|
||||
# walk through the URL list and build a file list
|
||||
for url in event.mimeData().urls():
|
||||
if url.isValid() and url.scheme() == "file":
|
||||
@ -641,7 +636,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.archiveCoverWidget.set_archive(self.comic_archive, cover_idx)
|
||||
|
||||
def update_menus(self) -> None:
|
||||
|
||||
# First just disable all the questionable items
|
||||
self.actionAutoTag.setEnabled(False)
|
||||
self.actionCopyTags.setEnabled(False)
|
||||
@ -686,7 +680,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.actionWrite_Tags.setEnabled(True)
|
||||
|
||||
def update_info_box(self) -> None:
|
||||
|
||||
ca = self.comic_archive
|
||||
|
||||
if ca is None:
|
||||
@ -734,7 +727,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.connect_child_dirty_flag_signals(self.tabWidget)
|
||||
|
||||
def connect_child_dirty_flag_signals(self, widget: QtCore.QObject) -> None:
|
||||
|
||||
if isinstance(widget, QtWidgets.QLineEdit):
|
||||
widget.textEdited.connect(self.set_dirty_flag)
|
||||
if isinstance(widget, QtWidgets.QTextEdit):
|
||||
@ -763,7 +755,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.clear_dirty_flag()
|
||||
|
||||
def clear_children(self, widget: QtCore.QObject) -> None:
|
||||
|
||||
if isinstance(widget, (QtWidgets.QLineEdit, QtWidgets.QTextEdit)):
|
||||
widget.setText("")
|
||||
if isinstance(widget, QtWidgets.QComboBox):
|
||||
@ -992,7 +983,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.select_file(folder_mode=True)
|
||||
|
||||
def select_file(self, folder_mode: bool = False) -> None:
|
||||
|
||||
dialog = QtWidgets.QFileDialog(self)
|
||||
if folder_mode:
|
||||
dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory)
|
||||
@ -1286,7 +1276,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.twCredits.item(row, 0).setText("Yes")
|
||||
|
||||
def modify_credits(self, edit: bool) -> None:
|
||||
|
||||
if edit:
|
||||
row = self.twCredits.currentRow()
|
||||
role = self.twCredits.item(row, 1).text()
|
||||
@ -1365,7 +1354,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
QtWidgets.QMessageBox.warning(self, self.tr("Web Link"), self.tr("Web Link is invalid."))
|
||||
|
||||
def show_settings(self) -> None:
|
||||
|
||||
settingswin = SettingsWindow(self, self.config, self.current_talker())
|
||||
settingswin.setModal(True)
|
||||
settingswin.exec()
|
||||
@ -1396,7 +1384,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
self.update_style_tweaks()
|
||||
|
||||
def populate_combo_boxes(self) -> None:
|
||||
|
||||
# Add the entries to the tag style combobox
|
||||
self.cbLoadDataStyle.addItem("ComicBookLover", MetaDataStyle.CBI)
|
||||
self.cbLoadDataStyle.addItem("ComicRack", MetaDataStyle.CIX)
|
||||
@ -1669,7 +1656,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
dlg.exec()
|
||||
|
||||
def actual_issue_data_fetch(self, match: IssueResult) -> GenericMetadata:
|
||||
|
||||
# now get the particular issue data OR series data
|
||||
ct_md = GenericMetadata()
|
||||
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CursorShape.WaitCursor))
|
||||
@ -2061,7 +2047,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
if self.dirty_flag_verification(
|
||||
"File Rename", "If you rename files now, unsaved data in the form will be lost. Are you sure?"
|
||||
):
|
||||
|
||||
dlg = RenameWindow(self, ca_list, self.load_data_style, self.config, self.current_talker())
|
||||
dlg.setModal(True)
|
||||
if dlg.exec() and self.comic_archive is not None:
|
||||
|
@ -47,7 +47,6 @@ if qt_available:
|
||||
window.move(hpos, vpos)
|
||||
|
||||
def center_window_on_parent(window: QtWidgets.QWidget) -> None:
|
||||
|
||||
top_level = window
|
||||
while top_level.parent() is not None:
|
||||
parent = top_level.parent()
|
||||
|
@ -26,7 +26,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class VersionChecker:
|
||||
def get_request_url(self, uuid: str) -> tuple[str, dict[str, str]]:
|
||||
|
||||
base_url = "https://api.github.com/repos/comictagger/comictagger/releases/latest"
|
||||
params: dict[str, str] = {}
|
||||
|
||||
|
@ -61,7 +61,6 @@ class ComicCacher:
|
||||
pass
|
||||
|
||||
def create_cache_db(self) -> None:
|
||||
|
||||
# create the version file
|
||||
with open(self.version_file, "w", encoding="utf-8") as f:
|
||||
f.write(self.version)
|
||||
@ -139,11 +138,7 @@ class ComicCacher:
|
||||
for record in ct_search_results:
|
||||
cur.execute(
|
||||
"INSERT INTO SeriesSearchCache " + "(source_name, search_term, id) " + "VALUES(?, ?, ?)",
|
||||
(
|
||||
source_name,
|
||||
search_term.casefold(),
|
||||
record.id,
|
||||
),
|
||||
(source_name, search_term.casefold(), record.id),
|
||||
)
|
||||
|
||||
data = {
|
||||
@ -196,7 +191,6 @@ class ComicCacher:
|
||||
con = lite.connect(self.db_file)
|
||||
|
||||
with con:
|
||||
|
||||
cur = con.cursor()
|
||||
|
||||
timestamp = datetime.datetime.now()
|
||||
@ -262,10 +256,7 @@ class ComicCacher:
|
||||
cur.execute("DELETE FROM Series WHERE timestamp < ?", [str(a_week_ago)])
|
||||
|
||||
# fetch
|
||||
cur.execute(
|
||||
"SELECT * FROM Series" " WHERE id=? AND source_name=?",
|
||||
[series_id, source_name],
|
||||
)
|
||||
cur.execute("SELECT * FROM Series" " WHERE id=? AND source_name=?", [series_id, source_name])
|
||||
|
||||
row = cur.fetchone()
|
||||
|
||||
|
@ -181,6 +181,8 @@ class ComicVineTalker(ComicTalker):
|
||||
self.wait_on_ratelimit_time: int = 20
|
||||
|
||||
def register_settings(self, parser: settngs.Manager) -> None:
|
||||
parser.add_setting("--cv-api-key", help="Use the given Comic Vine API Key.")
|
||||
parser.add_setting("--cv-url", help="Use the given Comic Vine URL.")
|
||||
parser.add_setting("--cv-use-series-start-as-volume", default=False, action=argparse.BooleanOptionalAction)
|
||||
parser.add_setting("--cv-wait-on-ratelimit", default=False, action=argparse.BooleanOptionalAction)
|
||||
parser.add_setting(
|
||||
@ -189,14 +191,6 @@ class ComicVineTalker(ComicTalker):
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Removes html tables instead of converting them to text.",
|
||||
)
|
||||
parser.add_setting(
|
||||
"--cv-api-key",
|
||||
help="Use the given Comic Vine API Key.",
|
||||
)
|
||||
parser.add_setting(
|
||||
"--cv-url",
|
||||
help="Use the given Comic Vine URL.",
|
||||
)
|
||||
|
||||
def parse_settings(self, settings: dict[str, Any]) -> dict[str, Any]:
|
||||
if settings["cv_api_key"]:
|
||||
@ -296,7 +290,6 @@ class ComicVineTalker(ComicTalker):
|
||||
|
||||
# see if we need to keep asking for more pages...
|
||||
while current_result_count < total_result_count:
|
||||
|
||||
if not literal:
|
||||
# Stop searching once any entry falls below the threshold
|
||||
stop_searching = any(
|
||||
|
8
setup.py
8
setup.py
@ -55,15 +55,11 @@ setup(
|
||||
author="ComicTagger team",
|
||||
author_email="comictagger@gmail.com",
|
||||
url="https://github.com/comictagger/comictagger",
|
||||
packages=find_packages(
|
||||
exclude=["tests", "testing"],
|
||||
),
|
||||
packages=find_packages(exclude=["tests", "testing"]),
|
||||
package_data={"comictaggerlib": ["ui/*", "graphics/*"], "comicapi": ["data/*"]},
|
||||
entry_points={
|
||||
"console_scripts": ["comictagger=comictaggerlib.main:main"],
|
||||
"pyinstaller40": [
|
||||
"hook-dirs = comictaggerlib.__pyinstaller:get_hook_dirs",
|
||||
],
|
||||
"pyinstaller40": ["hook-dirs = comictaggerlib.__pyinstaller:get_hook_dirs"],
|
||||
"comicapi.archiver": [
|
||||
"zip = comicapi.archivers.zip:ZipArchiver",
|
||||
"sevenzip = comicapi.archivers.sevenzip:SevenZipArchiver",
|
||||
|
@ -125,13 +125,7 @@ additional_imprints = [
|
||||
all_imprints = imprints + additional_imprints
|
||||
|
||||
seed_imprints = {
|
||||
"Marvel": utils.ImprintDict(
|
||||
"Marvel",
|
||||
{
|
||||
"marvel comics": "",
|
||||
"aircel": "Aircel Comics",
|
||||
},
|
||||
)
|
||||
"Marvel": utils.ImprintDict("Marvel", {"marvel comics": "", "aircel": "Aircel Comics"}),
|
||||
}
|
||||
|
||||
additional_seed_imprints = {
|
||||
|
@ -13,11 +13,7 @@ def test_create_cache(config, mock_version):
|
||||
|
||||
|
||||
def test_search_results(comic_cache):
|
||||
comic_cache.add_search_results(
|
||||
"test",
|
||||
"test search",
|
||||
search_results,
|
||||
)
|
||||
comic_cache.add_search_results("test", "test search", search_results)
|
||||
assert search_results == comic_cache.get_search_results("test", "test search")
|
||||
|
||||
|
||||
|
@ -36,7 +36,6 @@ def tmp_comic(tmp_path):
|
||||
|
||||
@pytest.fixture
|
||||
def cbz_double_cover(tmp_path, tmp_comic):
|
||||
|
||||
cover = Image.open(io.BytesIO(tmp_comic.get_page(0)))
|
||||
|
||||
other_page = Image.open(io.BytesIO(tmp_comic.get_page(tmp_comic.get_number_of_pages() - 1)))
|
||||
@ -67,7 +66,6 @@ def comicvine_api(monkeypatch, cbz, comic_cache, mock_version, config) -> comict
|
||||
return cv_list
|
||||
|
||||
def mock_get(*args, **kwargs):
|
||||
|
||||
if args:
|
||||
if args[0].startswith("https://comicvine.gamespot.com/api/volume/4050-23437"):
|
||||
cv_result = copy.deepcopy(comicvine.cv_volume_result)
|
||||
@ -157,7 +155,6 @@ def seed_all_publishers(monkeypatch):
|
||||
|
||||
@pytest.fixture
|
||||
def config(settings_manager, tmp_path):
|
||||
|
||||
comictaggerlib.ctsettings.register_commandline_settings(settings_manager)
|
||||
comictaggerlib.ctsettings.register_file_settings(settings_manager)
|
||||
defaults = settings_manager.get_namespace(settings_manager.defaults())
|
||||
|
Loading…
Reference in New Issue
Block a user