Refactor Candidate class in fetchart.py to improve

validation and resizing logic
This commit is contained in:
Dr-Blank 2024-03-18 08:57:32 -04:00
parent b09806e0df
commit 66b459b8d0
No known key found for this signature in database
GPG key ID: 7452CC63F210A266

View file

@ -67,10 +67,15 @@ class Candidate:
self.match = match
self.size = size
def _validate(self, plugin):
def _validate(self, plugin, skip_check_for=None):
"""Determine whether the candidate artwork is valid based on
its dimensions (width and ratio).
`skip_check_for` is a check or list of checks to skip. This is used to
avoid redundant checks when the candidate has already been
validated for a particular operation without changing
plugin configuration.
Return `CANDIDATE_BAD` if the file is unusable.
Return `CANDIDATE_EXACT` if the file is usable as-is.
Return `CANDIDATE_DOWNSCALE` if the file must be rescaled.
@ -82,6 +87,11 @@ class Candidate:
if not self.path:
return self.CANDIDATE_BAD
if skip_check_for is None:
skip_check_for = []
if isinstance(skip_check_for, int):
skip_check_for = [skip_check_for]
if not (
plugin.enforce_ratio
or plugin.minwidth
@ -180,30 +190,51 @@ class Candidate:
plugin.cover_format,
)
if downscale:
if downscale and (not self.CANDIDATE_DOWNSCALE in skip_check_for):
return self.CANDIDATE_DOWNSCALE
elif downsize:
return self.CANDIDATE_DOWNSIZE
elif plugin.deinterlace:
return self.CANDIDATE_DEINTERLACE
elif reformat:
if reformat and (not self.CANDIDATE_REFORMAT in skip_check_for):
return self.CANDIDATE_REFORMAT
else:
if plugin.deinterlace and (
not self.CANDIDATE_DEINTERLACE in skip_check_for
):
return self.CANDIDATE_DEINTERLACE
if downsize and (not self.CANDIDATE_DOWNSIZE in skip_check_for):
return self.CANDIDATE_DOWNSIZE
return self.CANDIDATE_EXACT
def validate(self, plugin):
self.check = self._validate(plugin)
def validate(self, plugin, skip_check_for=None):
self.check = self._validate(plugin, skip_check_for)
return self.check
def resize(self, plugin):
if self.check == self.CANDIDATE_DOWNSCALE:
"""Resize the candidate artwork according to the plugin's
configuration until it is valid or no further resizing is
possible.
"""
# validate the candidate in case it hasn't been done yet
current_check = self.validate(plugin)
checks_performed = []
# we don't want to resize the image if it's valid or bad
while current_check not in [self.CANDIDATE_BAD, self.CANDIDATE_EXACT]:
self._resize(plugin, current_check)
checks_performed.append(current_check)
current_check = self.validate(
plugin, skip_check_for=checks_performed
)
def _resize(self, plugin, check=None):
"""Resize the candidate artwork according to the plugin's
configuration and the specified check.
"""
if check == self.CANDIDATE_DOWNSCALE:
self.path = ArtResizer.shared.resize(
plugin.maxwidth,
self.path,
quality=plugin.quality,
max_filesize=plugin.max_filesize,
)
elif self.check == self.CANDIDATE_DOWNSIZE:
elif check == self.CANDIDATE_DOWNSIZE:
# dimensions are correct, so maxwidth is set to maximum dimension
self.path = ArtResizer.shared.resize(
max(self.size),
@ -211,9 +242,9 @@ class Candidate:
quality=plugin.quality,
max_filesize=plugin.max_filesize,
)
elif self.check == self.CANDIDATE_DEINTERLACE:
elif check == self.CANDIDATE_DEINTERLACE:
self.path = ArtResizer.shared.deinterlace(self.path)
elif self.check == self.CANDIDATE_REFORMAT:
elif check == self.CANDIDATE_REFORMAT:
self.path = ArtResizer.shared.reformat(
self.path,
plugin.cover_format,