Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

beet write: false positive for changes in fields with multiple values #5371

Open
celynw opened this issue Jul 28, 2024 · 2 comments
Open

beet write: false positive for changes in fields with multiple values #5371

celynw opened this issue Jul 28, 2024 · 2 comments

Comments

@celynw
Copy link

celynw commented Jul 28, 2024

Problem

It seems that for fields which allow multiple tags, the write command might incorrectly say there are changes to be made.

Backstory

I am using the albumtypes plugin to set the 'soundtrack' album type.

My relevant config looks like this:

albumtypes:
  types:
    - soundtrack: "OST"
    - ep: "EP"
    - single: "Single"
    - live: "Live"
    - compilation: "Anthology"
    - remix: "Remix"
  ignore_va: compilation
paths:
  default: $albumartist/$year - $album%aunique{}/%if{$multidisc,$paddisc-}$padtrack $title
  albumtype:soundtrack: Soundtracks/$album/%if{$multidisc,$paddisc-}$padtrack $title
  albumtypes:soundtrack: Soundtracks/$album/%if{$multidisc,$paddisc-}$padtrack $title
musicbrainz:

(I opened a related discussion, which was solved.)

Basically, if 'soundtrack' appears at all in MusicBrainz's albumtypes list, I'll set the main albumtype to soundtrack. This is because I prefer soundtrack to be the highest priority when something belongs to multiple types.

This does work; I checked the database manually, and the types are set correctly:

albumtype albumtypes
soundtrack album; soundtrack

I also checked the files themselves and found the data to also be correct.

RELEASETYPE     : album;soundtrack
MUSICBRAINZ_ALBUMTYPE: album;soundtrack

My issue is that when I run beet write, it tells me there are many changes to be made like:

albumtype: album -> soundtrack

This never clears; if I run the command again, it tries to do this again.

The issue seems to related to this part in mediafile:

    albumtypes = ListMediaField(
        MP3ListDescStorageStyle('MusicBrainz Album Type', split_v23=True),
        MP4ListStorageStyle('----:com.apple.iTunes:MusicBrainz Album Type'),
        ListStorageStyle('RELEASETYPE'),
        ListStorageStyle('MUSICBRAINZ_ALBUMTYPE'),
        ASFStorageStyle('MusicBrainz/Album Type'),
    )
    albumtype = albumtypes.single_field()

ListMediaField.single_field returns the first item in albumtypes.

This comes up in the write command, write_items(), where a 'clean_item` is created from the file on disk:

clean_item = library.Item.from_path(item.path)

It's a bit tricky, because both the file and the database are already correct, but because the write command thought there is a difference, it will attempt to write the corrections anyway.

  • Beets' database holds both multiple (albumtypes) and single fields (albumtype) for that entry, and the single field can be configured by the user to choose which one from the multiple field
  • Beets reads a field with multiple values and returns the first one to the write command
  • Beets writes (only) the multiple values tag to the file
    • I haven't investigated with other media file types - this one is an FLAC

If the above is always true, a workaround which works for me is to add

        if item.albumtype in clean_item.albumtypes:
            clean_item.albumtype = item.albumtype

before checking for the changes here:

changed = ui.show_model_changes(

I'm not sure if this is the most robust though.

Also, I guess it could apply to other 'multiple' fields too:

  • genres
  • catalognums
  • languages
  • mb_artistids
  • mb_albumartistids

Setup

  • OS: Ubuntu 22.04
  • Python version: 3.10.12
  • beets version: 2.0.0
  • Turning off plugins made problem go away (yes/no): N/A
@celynw
Copy link
Author

celynw commented Jul 28, 2024

And similarly for beet update: adding

            old_item = lib.get_item(item.id)
            if old_item.albumtype in item.albumtypes:
                item.albumtype = old_item.albumtype

before checking for the changes here:

changed = ui.show_model_changes(item, fields=item_fields)

@snejus
Copy link
Member

snejus commented Aug 12, 2024

Thank you, this is an amazing investigation! Linking this to the issue where this problem has been reported first: #5265

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants