Clear art on import

This commit is contained in:
Eric Masseran 2025-11-10 22:38:37 +01:00
parent 85168ba7fc
commit 8889c4ab47
4 changed files with 53 additions and 8 deletions

View file

@ -364,15 +364,17 @@ class TestHelper(ConfigMixin):
items.append(item)
return self.lib.add_album(items)
def create_mediafile_fixture(self, ext="mp3", images=[]):
def create_mediafile_fixture(self, ext="mp3", images=[], target_dir=None):
"""Copy a fixture mediafile with the extension to `temp_dir`.
`images` is a subset of 'png', 'jpg', and 'tiff'. For each
specified extension a cover art image is added to the media
file.
"""
if not target_dir:
target_dir = self.temp_dir
src = os.path.join(_common.RSRC, util.bytestring_path(f"full.{ext}"))
handle, path = mkstemp(dir=self.temp_dir)
handle, path = mkstemp(dir=target_dir)
path = bytestring_path(path)
os.close(handle)
shutil.copyfile(syspath(src), syspath(path))

View file

@ -206,12 +206,16 @@ def extract_first(log, outpath, items):
return real_path
def clear_item(item, log):
if mediafile.MediaFile(syspath(item.path)).images:
log.debug("Clearing art for {}", item)
item.try_write(tags={"images": None})
else:
log.debug("No art to clean for {}", item)
def clear(log, lib, query):
items = lib.items(query)
log.info("Clearing album art from {} items", len(items))
for item in items:
if mediafile.MediaFile(syspath(item.path)).images:
log.debug("Clearing art for {}", item)
item.try_write(tags={"images": None})
else:
log.debug("No art to clean for {}", item)
clear_item(item, log)

View file

@ -62,6 +62,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
"ifempty": False,
"remove_art_file": False,
"quality": 0,
"clearart_on_import": False,
}
)
@ -82,6 +83,9 @@ class EmbedCoverArtPlugin(BeetsPlugin):
self.register_listener("art_set", self.process_album)
if self.config["clearart_on_import"].get(bool):
self.register_listener("import_task_files", self.import_task_files)
def commands(self):
# Embed command.
embed_cmd = ui.Subcommand(
@ -278,3 +282,9 @@ class EmbedCoverArtPlugin(BeetsPlugin):
os.remove(syspath(album.artpath))
album.artpath = None
album.store()
def import_task_files(self, session, task):
"""Automatically clearart of imported files."""
for item in task.imported_items():
self._log.debug("clearart-on-import {.filepath}", item)
art.clear_item(item, self._log)

View file

@ -27,6 +27,7 @@ from mediafile import MediaFile
from beets import config, logging, ui
from beets.test import _common
from beets.test.helper import (
ImportHelper,
BeetsTestCase,
FetchImageHelper,
IOMixin,
@ -76,7 +77,9 @@ def require_artresizer_compare(test):
return wrapper
class EmbedartCliTest(IOMixin, PluginMixin, FetchImageHelper, BeetsTestCase):
class EmbedartCliTest(
ImportHelper, IOMixin, PluginMixin, FetchImageHelper, BeetsTestCase
):
plugin = "embedart"
small_artpath = os.path.join(_common.RSRC, b"image-2x3.jpg")
abbey_artpath = os.path.join(_common.RSRC, b"abbey.jpg")
@ -286,6 +289,32 @@ class EmbedartCliTest(IOMixin, PluginMixin, FetchImageHelper, BeetsTestCase):
mediafile = MediaFile(syspath(item.path))
assert not mediafile.images
def test_clearart_on_import_disabled(self):
file_path = self.create_mediafile_fixture(
images=["jpg"], target_dir=self.import_path
)
self.import_media.append(file_path)
with self.configure_plugin({"clearart_on_import": False}):
importer = self.setup_importer(autotag=False, write=True)
importer.run()
item = self.lib.items()[0]
assert MediaFile(os.path.join(item.path)).images
def test_clearart_on_import_enabled(self):
file_path = self.create_mediafile_fixture(
images=["jpg"], target_dir=self.import_path
)
self.import_media.append(file_path)
# Force re-init the plugin to register the listener
self.unload_plugins()
with self.configure_plugin({"clearart_on_import": True}):
importer = self.setup_importer(autotag=False, write=True)
importer.run()
item = self.lib.items()[0]
assert not MediaFile(os.path.join(item.path)).images
class DummyArtResizer(ArtResizer):
"""An `ArtResizer` which pretends that ImageMagick is available, and has