Replace old cover art instead of creating suffixed new entries / fetchart#6554
Replace old cover art instead of creating suffixed new entries / fetchart#6554
Conversation
|
Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry. |
a3bd5e5 to
1c27999
Compare
ce00a0b to
89e83a6
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6554 +/- ##
==========================================
+ Coverage 71.76% 71.77% +0.01%
==========================================
Files 159 159
Lines 20515 20531 +16
Branches 3262 3266 +4
==========================================
+ Hits 14722 14737 +15
Misses 5105 5105
- Partials 688 689 +1
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
PR try stop cover.2.jpg / cover.3.jpg pile-up when re-import with fetchart. PR make old art get removed instead of making suffixed new file.
Changes:
- Change
Album.set_artto always remove old art and any existing destination file (nounique_path). - Change
ImportTask.remove_duplicatesto work per-album and also delete album art file on disk when removing duplicate albums. - Add/adjust tests + add changelog entry for duplicate art fix.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
beets/library/models.py |
Make set_art actually replace art at destination (no suffixed duplicates). |
beets/importer/tasks.py |
Remove duplicate albums at album level; delete album art file + prune dirs. |
test/test_importer.py |
Add test for “remove duplicate album also deletes art”. |
test/test_files.py |
Update/add tests for replacing conflicting art + replacing old art with different extension. |
docs/changelog.rst |
Document bug fix for duplicate cover files on re-import with fetchart. |
Comments suppressed due to low confidence (1)
test/test_importer.py:1019
- grug see @pytest.mark.xfail still here, but PR say bug fixed. if test now pass, remove xfail so CI catch future break.
def album_candidates_mock(*args, **kwargs):
"""Create an AlbumInfo object for testing."""
yield AlbumInfo(
|
What do you think of removing any file matching art_filename in |
I think that's what the new logic does? Now it removes both |
89e83a6 to
9a1ec75
Compare
|
On the other hand, I think it will be up to the users to clean up their album directories. Presumably, many users have a similar situation to mine: $ fd 'cover.[0-9]' $MUSIC_DIR | head -20
/mnt/music/Music/delsin/randomxs_giveyourbody/cover.1.jpg
/mnt/music/Music/gaurasange/cutyourhair_cryoutloud/cover.1.jpg
/mnt/music/Music/underzone/variosartistasviii/cover.1.jpg
/mnt/music/Music/tsa/irrevocable/cover.1.jpg
/mnt/music/Music/hproductions/hpx49_tonyrohr_oddlantikavenue/cover.1.jpg
/mnt/music/Music/warnerbros/pendulum_immersion/cover.1.jpg
/mnt/music/Music/spektator/spektator5_djvalentimes_descent/cover.1.jpg
/mnt/music/Music/greenfetish/benzeenvol3/cover.1.jpg
/mnt/music/Music/takemetothehospital/hospcds02_theprodigy_omen/cover.1.jpg
/mnt/music/Music/d_vision/benassibros_pumphonia/cover.2.jpg
/mnt/music/Music/diffusereality/te0047_simonhalsberghe_beginnersmindsignalfunk/cover.1.jpg
/mnt/music/Music/gaul/90seditsseries/cover.1.jpg
/mnt/music/Music/diffusereality/smforma_smforma/cover.1.jpg
/mnt/music/Music/diffusereality/drss345_tkg_buster/cover.1.jpg
/mnt/music/Music/rnd/rndr036_sydneyvalette_gorodbolit/cover.1.jpg
/mnt/music/Music/weirdnxcr/weirdnxcract6/cover.1.jpg
/mnt/music/Music/mord/charlton_inplainsight/cover.1.jpg
/mnt/music/Music/sweatitout/sweatds041w_parachuteyouth_cantgetbetterthanthisep/cover.1.jpg
/mnt/music/Music/trip/romazuckerman_stageofloyalty/cover.1.jpg
/mnt/music/Music/concreteberlin/crva02_concretev_avol2/cover.1.jpgI would like to add an automatic cleanup to this PR (another migration subclass), but we should probably not risk making a mess in users' album directories in case they've added images there manually. |
This works if the old file has the same name as the new file, or is known to beets. This can happen when using the convert feature of fetchart:
|
cleanup can be achieved in a single command for people on unix: |
This is precisely why I'm not very comfortable about the idea of removing such files - see my previous comment. In this specific use case, I imagine this should have an opt-in configuration specific to fetchart? |
9a1ec75 to
4445830
Compare
Summary
cover.2.jpg,cover.3.jpg, ...) accumulating when re-importing albums with the fetchart plugin enabled.ImportTask.remove_duplicatesnow operates at the album level and explicitly deletes album art files from disk when removing duplicate albums during import.Album.set_artnow unconditionally removes old art and any existing file at the destination, instead of appending a numeric suffix viaunique_path. This matches the method's documented behavior of "replacing any existing art".SingletonImportTaskgets its ownremove_duplicatesoverride preserving the original item-level behavior, sincefind_duplicatesreturns items (not albums) for singletons.Root cause
Two issues contributed to the bug:
1.
remove_duplicatesnever deleted album art files.When a user imports a duplicate album and chooses "Remove old",
remove_duplicatesiterated over items and calleditem.remove(). When the last item was removed, this cascaded toAlbum.remove(delete=False), which skipped art deletion due todelete=False. The oldcover.jpgremained on disk as an orphan.2.
set_artcreated unique paths instead of replacing.set_artonly removed the old art file whenoldart == artdest(exact byte equality). WhenoldartwasNone(new album, no inherited artpath) or pointed to a different path (e.g. different extension), the existing file was left in place andunique_pathgeneratedcover.2.jpg.Fixes #6205