diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index c00124623..5c005656a 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -660,9 +660,9 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): def __init__(self): super(FetchArtPlugin, self).__init__() - # Holds paths to downloaded images between fetching them and - # placing them in the filesystem. - self.art_paths = {} + # Holds candidates corresponding to downloaded images between + # fetching them and placing them in the filesystem. + self.art_candidates = {} self.config.add({ 'auto': True, @@ -675,7 +675,8 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): 'coverart', 'itunes', 'amazon', 'albumart'], 'google_key': None, 'google_engine': u'001442825323518660753:hrh5ch1gjzm', - 'fanarttv_key': None + 'fanarttv_key': None, + 'store_origin': False }) self.config['google_key'].redact = True self.config['fanarttv_key'].redact = True @@ -703,6 +704,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): cover_names = self.config['cover_names'].as_str_seq() self.cover_names = map(util.bytestring_path, cover_names) self.cautious = self.config['cautious'].get(bool) + self.store_origin = self.config['store_origin'].get(bool) self.src_removed = (config['import']['delete'].get(bool) or config['import']['move'].get(bool)) @@ -753,19 +755,28 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): candidate = self.art_for_album(task.album, task.paths, local) if candidate: - self.art_paths[task] = candidate.path + self.art_candidates[task] = candidate + + def _set_art(self, album, candidate, delete=False): + album.set_art(candidate.path, delete) + if self.store_origin: + # store the origin of the chosen artwork in a flexible field + self._log.debug( + u"Storing artorigin for {0.albumartist} - {0.album}", + album) + album.artorigin = candidate.source + album.store() # Synchronous; after music files are put in place. def assign_art(self, session, task): """Place the discovered art in the filesystem.""" - if task in self.art_paths: - path = self.art_paths.pop(task) + if task in self.art_candidates: + candidate = self.art_candidates.pop(task) + + self._set_art(task.album, candidate, not self.src_removed) - album = task.album - album.set_art(path, not self.src_removed) - album.store() if self.src_removed: - task.prune(path) + task.prune(candidate.path) # Manual album art fetching. def commands(self): @@ -842,8 +853,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): candidate = self.art_for_album(album, local_paths) if candidate: - album.set_art(candidate.path, False) - album.store() + self._set_art(album, candidate) message = ui.colorize('text_success', u'found album art') else: message = ui.colorize('text_error', u'no art found') diff --git a/docs/plugins/fetchart.rst b/docs/plugins/fetchart.rst index 591dbc4b4..72745e73a 100644 --- a/docs/plugins/fetchart.rst +++ b/docs/plugins/fetchart.rst @@ -62,6 +62,9 @@ file. The available options are: Default: The `beets custom search engine`_, which searches the entire web. **fanarttv_key**: The personal API key for requesting art from fanart.tv. See below. + **store_origin**: If enabled, fetchart store the artwork's source in a + flexible tag. See below for the rationale behind this. + Default: ``no``. Note: ``minwidth`` and ``enforce_ratio`` options require either `ImageMagick`_ or `Pillow`_. @@ -182,6 +185,16 @@ personal key will give you earlier access to new art. .. _on their blog: https://fanart.tv/2015/01/personal-api-keys/ +Storing the artwork's origin +---------------------------- + +Storing the current artwork's source gives the opportunity to selectively +search for new art. For example, if some albums have artwork placed manually in +their directories that should not be replaced by a forced album art fetch, you +could do + +``beet fetchart -f ^artorigin:filesystem`` + Embedding Album Art -------------------