Compare commits
13 Commits
09490b8ebf
...
1.6.0-alph
Author | SHA1 | Date | |
---|---|---|---|
10a48634bd | |||
2492d96fb3 | |||
87248503b4 | |||
7705e7ea1f | |||
54b0630891 | |||
27e70b966f | |||
ad8b92743c | |||
22b44c87ca | |||
2eca743f20 | |||
bb4be306cc | |||
768ef0b6bc | |||
215587d9a4 | |||
7430e59b64 |
@ -14,12 +14,12 @@ repos:
|
||||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.15.0
|
||||
rev: v3.15.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
- repo: https://github.com/PyCQA/autoflake
|
||||
rev: v2.2.1
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args: [-i, --remove-all-unused-imports, --ignore-init-module-imports]
|
||||
@ -29,7 +29,7 @@ repos:
|
||||
- id: isort
|
||||
args: [--af,--add-import, 'from __future__ import annotations']
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.1.1
|
||||
rev: 24.2.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
|
@ -260,7 +260,21 @@ class RarArchiver(Archiver):
|
||||
return True
|
||||
|
||||
def is_writable(self) -> bool:
|
||||
return bool(self.exe and (os.path.exists(self.exe) or shutil.which(self.exe)))
|
||||
try:
|
||||
if bool(self.exe and (os.path.exists(self.exe) or shutil.which(self.exe))):
|
||||
return (
|
||||
subprocess.run(
|
||||
(self.exe,),
|
||||
startupinfo=self.startupinfo,
|
||||
capture_output=True,
|
||||
cwd=self.path.absolute().parent,
|
||||
)
|
||||
.stdout.strip()
|
||||
.startswith(b"RAR")
|
||||
)
|
||||
except OSError:
|
||||
...
|
||||
return False
|
||||
|
||||
def extension(self) -> str:
|
||||
return ".cbr"
|
||||
@ -271,7 +285,19 @@ class RarArchiver(Archiver):
|
||||
@classmethod
|
||||
def is_valid(cls, path: pathlib.Path) -> bool:
|
||||
if rar_support:
|
||||
return rarfile.is_rarfile(str(path))
|
||||
# Try using exe
|
||||
orig = rarfile.UNRAR_TOOL
|
||||
rarfile.UNRAR_TOOL = cls.exe
|
||||
try:
|
||||
return rarfile.is_rarfile(str(path)) and rarfile.tool_setup(sevenzip=False, sevenzip2=False, force=True)
|
||||
except rarfile.RarCannotExec:
|
||||
rarfile.UNRAR_TOOL = orig
|
||||
|
||||
# Fallback to standard
|
||||
try:
|
||||
return rarfile.is_rarfile(str(path)) and rarfile.tool_setup(force=True)
|
||||
except rarfile.RarCannotExec as e:
|
||||
logger.info(e)
|
||||
return False
|
||||
|
||||
def get_rar_obj(self) -> rarfile.RarFile | None:
|
||||
|
@ -101,7 +101,7 @@ class GenericMetadata:
|
||||
letterer_synonyms = ("letterer", "letters")
|
||||
cover_synonyms = ("cover", "covers", "coverartist", "cover artist")
|
||||
editor_synonyms = ("editor", "edits", "editing")
|
||||
_translator_synonyms = ("translator", "translation")
|
||||
translator_synonyms = ("translator", "translation")
|
||||
|
||||
is_empty: bool = True
|
||||
tag_origin: TagOrigin | None = None
|
||||
|
@ -236,6 +236,14 @@ def add_to_path(dirname: str) -> None:
|
||||
os.environ["PATH"] = os.pathsep.join(paths)
|
||||
|
||||
|
||||
def remove_from_path(dirname: str) -> None:
|
||||
if dirname:
|
||||
dirname = os.path.abspath(dirname)
|
||||
paths = [os.path.normpath(x) for x in split(os.environ["PATH"], os.pathsep) if dirname != os.path.normpath(x)]
|
||||
|
||||
os.environ["PATH"] = os.pathsep.join(paths)
|
||||
|
||||
|
||||
def xlate_int(data: Any) -> int | None:
|
||||
data = xlate_float(data)
|
||||
if data is None:
|
||||
|
@ -35,6 +35,8 @@ class AutoTagProgressWindow(QtWidgets.QDialog):
|
||||
with (ui_path / "autotagprogresswindow.ui").open(encoding="utf-8") as uifile:
|
||||
uic.loadUi(uifile, self)
|
||||
|
||||
self.lblSourceName.setText(talker.attribution)
|
||||
|
||||
self.archiveCoverWidget = CoverImageWidget(
|
||||
self.archiveCoverContainer, CoverImageWidget.DataMode, None, None, False
|
||||
)
|
||||
|
@ -62,16 +62,22 @@ def register_talker_settings(manager: settngs.Manager, talkers: dict[str, ComicT
|
||||
|
||||
|
||||
def validate_archive_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
if "archiver" not in config[1]:
|
||||
return config
|
||||
cfg = settngs.normalize_config(config, file=True, cmdline=True, default=False)
|
||||
for archiver in comicapi.comicarchive.archivers:
|
||||
group = group_for_plugin(archiver())
|
||||
exe_name = settngs.sanitize_name(archiver.exe)
|
||||
if exe_name in cfg[0][group_for_plugin(archiver())] and cfg[0][group_for_plugin(archiver())][exe_name]:
|
||||
if os.path.basename(cfg[0][group_for_plugin(archiver())][exe_name]) == archiver.exe:
|
||||
comicapi.utils.add_to_path(os.path.dirname(cfg[0][group_for_plugin(archiver())][exe_name]))
|
||||
else:
|
||||
archiver.exe = cfg[0][group_for_plugin(archiver())][exe_name]
|
||||
if not exe_name:
|
||||
continue
|
||||
|
||||
if exe_name in cfg[0][group] and cfg[0][group][exe_name]:
|
||||
path = cfg[0][group][exe_name]
|
||||
name = os.path.basename(path)
|
||||
# If the path is not the basename then this is a relative or absolute path.
|
||||
# Ensure it is absolute
|
||||
if path != name:
|
||||
path = os.path.abspath(path)
|
||||
|
||||
archiver.exe = path
|
||||
|
||||
return config
|
||||
|
||||
|
@ -45,11 +45,10 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
listCleared = QtCore.pyqtSignal()
|
||||
|
||||
fileColNum = 0
|
||||
CRFlagColNum = 1
|
||||
CBLFlagColNum = 2
|
||||
typeColNum = 3
|
||||
readonlyColNum = 4
|
||||
folderColNum = 5
|
||||
MDFlagColNum = 1
|
||||
typeColNum = 2
|
||||
readonlyColNum = 3
|
||||
folderColNum = 4
|
||||
dataColNum = fileColNum
|
||||
|
||||
def __init__(
|
||||
@ -225,8 +224,7 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
|
||||
# Adjust column size
|
||||
self.twList.resizeColumnsToContents()
|
||||
self.twList.setColumnWidth(FileSelectionList.CRFlagColNum, 35)
|
||||
self.twList.setColumnWidth(FileSelectionList.CBLFlagColNum, 35)
|
||||
self.twList.setColumnWidth(FileSelectionList.MDFlagColNum, 35)
|
||||
self.twList.setColumnWidth(FileSelectionList.readonlyColNum, 35)
|
||||
self.twList.setColumnWidth(FileSelectionList.typeColNum, 45)
|
||||
if self.twList.columnWidth(FileSelectionList.fileColNum) > 250:
|
||||
@ -281,7 +279,6 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
filename_item = QtWidgets.QTableWidgetItem()
|
||||
folder_item = QtWidgets.QTableWidgetItem()
|
||||
md_item = FileTableWidgetItem()
|
||||
cbi_item = FileTableWidgetItem()
|
||||
readonly_item = FileTableWidgetItem()
|
||||
type_item = QtWidgets.QTableWidgetItem()
|
||||
|
||||
@ -297,11 +294,7 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
|
||||
md_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled)
|
||||
md_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter)
|
||||
self.twList.setItem(row, FileSelectionList.CRFlagColNum, md_item)
|
||||
|
||||
cbi_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled)
|
||||
cbi_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter)
|
||||
self.twList.setItem(row, FileSelectionList.CBLFlagColNum, cbi_item)
|
||||
self.twList.setItem(row, FileSelectionList.MDFlagColNum, md_item)
|
||||
|
||||
readonly_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled)
|
||||
readonly_item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter)
|
||||
@ -318,7 +311,7 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
|
||||
filename_item = self.twList.item(row, FileSelectionList.fileColNum)
|
||||
folder_item = self.twList.item(row, FileSelectionList.folderColNum)
|
||||
md_item = self.twList.item(row, FileSelectionList.CRFlagColNum)
|
||||
md_item = self.twList.item(row, FileSelectionList.MDFlagColNum)
|
||||
type_item = self.twList.item(row, FileSelectionList.typeColNum)
|
||||
readonly_item = self.twList.item(row, FileSelectionList.readonlyColNum)
|
||||
|
||||
|
@ -7,9 +7,15 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>900</width>
|
||||
<height>413</height>
|
||||
<height>456</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
@ -20,7 +26,23 @@
|
||||
<string>Issue Identification Progress</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<item row="1" column="4">
|
||||
<widget class="QWidget" name="testCoverContainer" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>165</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>165</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QWidget" name="archiveCoverContainer" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
@ -42,43 +64,42 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QWidget" name="testCoverContainer" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>165</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>165</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
<item row="1" column="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0,0,0,0,0" columnstretch="1,0">
|
||||
<item row="5" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblSourceName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Metadata source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier</family>
|
||||
@ -89,16 +110,26 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel</set>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -668,7 +668,9 @@ class ComicVineTalker(ComicTalker):
|
||||
md.story_arcs.append(arc["name"])
|
||||
|
||||
for person in issue.get("person_credits", []):
|
||||
md.add_credit(person["name"], person["role"].title().strip(), False)
|
||||
roles = utils.split(person.get("role", ""), ",")
|
||||
for role in roles:
|
||||
md.add_credit(person["name"], role.title(), False)
|
||||
|
||||
md.volume = utils.xlate_int(issue.get("volume"))
|
||||
if self.use_series_start_as_volume:
|
||||
|
@ -87,7 +87,8 @@ all =
|
||||
PyQt5
|
||||
PyQtWebEngine
|
||||
comicinfoxml
|
||||
metron-talker>=0.1.1
|
||||
gcd-talker>=0.1.0
|
||||
metron-talker>=0.1.5
|
||||
pillow-avif-plugin>=1.4.1
|
||||
py7zr
|
||||
rarfile>=4.0
|
||||
@ -96,6 +97,8 @@ avif =
|
||||
pillow-avif-plugin>=1.4.1
|
||||
cix =
|
||||
comicinfoxml
|
||||
gcd =
|
||||
gcd-talker>=0.1.0
|
||||
metron =
|
||||
metron-talker>=0.1.3
|
||||
|
||||
|
@ -69,7 +69,7 @@ cv_issue_result: dict[str, Any] = {
|
||||
"id": 57222,
|
||||
"name": "Esteve Polls",
|
||||
"site_detail_url": "https://comicvine.gamespot.com/esteve-polls/4040-57222/",
|
||||
"role": "artist",
|
||||
"role": "artist, writer",
|
||||
},
|
||||
{
|
||||
"api_detail_url": "https://comicvine.gamespot.com/api/person/4040-48472/",
|
||||
@ -226,8 +226,12 @@ cv_md = comicapi.genericmetadata.GenericMetadata(
|
||||
teams=set(),
|
||||
locations=set(),
|
||||
credits=[
|
||||
comicapi.genericmetadata.Credit(person=x["name"], role=x["role"].title(), primary=False)
|
||||
for x in cv_issue_result["results"]["person_credits"]
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Dara Naraghi", role="Writer"),
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Esteve Polls", role="Artist"),
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Esteve Polls", role="Writer"),
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Neil Uyetake", role="Letterer"),
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Sam Kieth", role="Cover"),
|
||||
comicapi.genericmetadata.Credit(primary=False, person="Ted Adams", role="Editor"),
|
||||
],
|
||||
tags=set(),
|
||||
pages=[],
|
||||
|
@ -42,6 +42,7 @@ def test_fetch_issues_in_series(comicvine_api, comic_cache):
|
||||
def test_fetch_issue_data_by_issue_id(comicvine_api):
|
||||
result = comicvine_api.fetch_comic_data(140529)
|
||||
result.notes = None
|
||||
|
||||
assert result == testing.comicvine.cv_md
|
||||
|
||||
|
||||
|
@ -49,6 +49,17 @@ def test_save(
|
||||
# Read the CBZ
|
||||
md = tmp_comic.read_metadata("cr")
|
||||
|
||||
# This is inserted here because otherwise several other tests
|
||||
# unrelated to comicvine need to be re-worked
|
||||
md_saved.credits.insert(
|
||||
1,
|
||||
{
|
||||
"person": "Esteve Polls",
|
||||
"primary": False,
|
||||
"role": "Writer",
|
||||
},
|
||||
)
|
||||
|
||||
# Validate that we got the correct metadata back
|
||||
assert md == md_saved
|
||||
|
||||
|
Reference in New Issue
Block a user