move and split fetchart valid_image

This commit is contained in:
Ali Graham 2016-02-25 12:44:09 +10:30
parent 59e54d1792
commit e58e04f0ab
2 changed files with 72 additions and 61 deletions

View file

@ -173,6 +173,46 @@ class ArtResizer(object):
log.debug(u"artresizer: method is {0}", self.method)
self.can_compare = self._can_compare()
def valid_size(self, size, enforce_ratio = False, minwidth = None):
"""If size constraints exist, check whether the provided image size
matches them.
"""
# Check minimum size.
if minwidth and size[0] < minwidth:
log.debug('image too small ({} < {})',
size[0], minwidth)
return False
# Check aspect ratio.
if enforce_ratio and size[0] != size[1]:
log.debug('image is not square ({} != {})',
size[0], size[1])
return False
return True
def must_resize(self, size, maxwidth = None):
"""Determine whether the provided image size means that the image
will need to be scaled to fit the maximum width.
"""
if not maxwidth:
return False
if not size:
log.warning(u'Could not get size of image (please see '
u'documentation for dependencies).')
return False
if size[0] <= maxwidth:
log.debug('dump values ({} > {})',
size[0], maxwidth)
log.debug(u'Image does not need to be resized.')
return False
log.debug('Image needs resizing ({} > {})',
size[0], maxwidth)
return True
def resize(self, maxwidth, path_in, path_out=None):
"""Manipulate an image file according to the method, returning a
new path. For PIL or IMAGEMAGIC methods, resizes the image to a

View file

@ -42,10 +42,6 @@ IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg']
CONTENT_TYPES = ('image/jpeg', 'image/png')
DOWNLOAD_EXTENSION = '.jpg'
CANDIDATE_BAD = 0
CANDIDATE_EXACT = 1
CANDIDATE_DOWNSCALE = 2
def _logged_get(log, *args, **kwargs):
"""Like `requests.get`, but logs the effective URL to the specified
@ -535,51 +531,6 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
self._log.debug('error fetching art: {}', exc)
return None
def _is_valid_image_candidate(self, candidate):
"""Determine whether the given candidate artwork is valid based on
its dimensions (width and ratio).
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 resized.
"""
if not candidate:
return CANDIDATE_BAD
if not (self.enforce_ratio or self.minwidth or self.maxwidth):
return CANDIDATE_EXACT
# get_size returns None if no local imaging backend is available
size = ArtResizer.shared.get_size(candidate)
self._log.debug('image size: {}', size)
if not size:
self._log.warning(u'Could not get size of image (please see '
u'documentation for dependencies). '
u'The configuration options `minwidth` and '
u'`enforce_ratio` may be violated.')
return CANDIDATE_EXACT
# Check minimum size.
if self.minwidth and size[0] < self.minwidth:
self._log.debug('image too small ({} < {})',
size[0], self.minwidth)
return CANDIDATE_BAD
# Check aspect ratio.
if self.enforce_ratio and size[0] != size[1]:
self._log.debug('image is not square ({} != {})',
size[0], size[1])
return CANDIDATE_BAD
# Check maximum size.
if self.maxwidth and size[0] > self.maxwidth:
self._log.debug('image needs resizing ({} > {})',
size[0], self.maxwidth)
return CANDIDATE_DOWNSCALE
return CANDIDATE_EXACT
def art_for_album(self, album, paths, local_only=False):
"""Given an Album object, returns a path to downloaded art for the
album (or None if no art is found). If `maxwidth`, then images are
@ -588,7 +539,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
are made.
"""
out = None
check = None
size = None
# Local art.
cover_names = self.config['cover_names'].as_str_seq()
@ -597,11 +548,21 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
if paths:
for path in paths:
candidate = self.fs_source.get(path, cover_names, cautious)
check = self._is_valid_image_candidate(candidate)
if check:
out = candidate
self._log.debug('found local image {}', out)
break
if not candidate:
continue
# get_size returns None if no local imaging backend is available
size = ArtResizer.shared.get_size(candidate)
self._log.debug('image size: {}', size)
if size:
valid = ArtResizer.shared.valid_size(size,
self.enforce_ratio, self.minwidth)
if not valid:
continue
out = candidate
self._log.debug('found local image {}', out)
break
# Web art sources.
remote_priority = self.config['remote_priority'].get(bool)
@ -610,13 +571,23 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
if self.maxwidth:
url = ArtResizer.shared.proxy_url(self.maxwidth, url)
candidate = self._fetch_image(url)
check = self._is_valid_image_candidate(candidate)
if check:
out = candidate
self._log.debug('using remote image {}', out)
break
if not candidate:
continue
if self.maxwidth and out and check == CANDIDATE_DOWNSCALE:
# get_size returns None if no local imaging backend is available
size = ArtResizer.shared.get_size(candidate)
self._log.debug('image size: {}', size)
if size:
valid = ArtResizer.shared.valid_size(size,
self.enforce_ratio, self.minwidth)
if not valid:
continue
out = candidate
self._log.debug('using remote image {}', out)
break
if self.maxwidth and out and ArtResizer.shared.must_resize(size, self.maxwidth):
out = ArtResizer.shared.resize(self.maxwidth, out)
return out