Add multivalue genre tag support #2503
These changes allow beets to store multiple genre tags for multivalues, with the intent of fixing #505 . Note that this is not ready to be merged yet, but it's a beginning of discussion on how to properly fix the issue.
Note that these commits store lists in album.genre and item.genre properties, while storing them as text strings in the database using a separator. Also, I checked that if a user has something like this as path definition:
then $genre is formatted as a string correctly . In my test case, creating a directory called "Rock;Blues" .
This can break some complex configurations. For example, I had this as album_fields definition to add a album_genre_for_path tag that would contain the most used genre in an album:
When evaluating this tag, beet broke sine item.genre is no longer hashable. I think this is a step better than silently breaking the directory structure. I fixed it easily by replacing the code above with:
Then I also tested what happens when reading a file written by another application with multiple genre tags:
Which is what I would have expected.
I tested this with flac and mp3 files (that is, with APE tags, where multiple genre tags are written and ID3 tags, where
The remaining questions are:
sampsyo left a comment
Very cool! This is diff is surprisingly small—I expected this to be a far more disruptive change.
A couple of ideas come to mind for improving backwards compatibility, neither of which we necessarily have to use:
The only thing that makes me somewhat uncomfortable here is the age-old slippery slope question. How many other fields would it make sense to transform into lists? Should
Anyway, genre is clearly the best use case for this, so maybe it's not worth worrying too much about other tags.
Btw, I guess you'll doubt that getall('TIPL') can be replaced with get('TIPL') (mainly because I doubted about it too :) ). So here is the test I did with mutagen to check that it doesn't allow two TIPL frames:
Here, I checked with okteta (an hex editor) that the file included the added TIPL frame.
and here, I checked again with an hex editor that the frame wasn't just added, but it replaced the previous TIPL frame.
I just noticed I had this written in a browser tab but forgot to click comment. I'll post it for the records, even if it's probably old now.
Yes, I also was surprised, but most of the work was already implemented in ListMediaField, the *ListStorageStyle classes and mutagen.
Yes, I saw that, but the genres tag is (afaik) not used by any other application, but genre is.
Have a look at the test_write_genre_list_from_string test I added in test_mediafile.py to test fad5809 :). I think that's even better since it allows assigning a string but automatically converts it to a list.
Hmm, I don't think that would be too much work. I can give it a try if you want. (This is now done)
referenced this pull request
Aug 26, 2018
referenced this pull request
Apr 27, 2019
@antlarr thanks for your work on this PR. It's been a while since it's had any attention, but it seems that multi-valued tags are still a feature that people would like to see!
Just a heads up that we're planning on splitting MediaFile out into a standalone Python module & git repository during the current beets release cycle, and this is clearly going to affect this PR. Your branch is anyway conflicting with master already, but after the split it'll mean that the changes will also need to be split into two separate sets. Are you still interested in working on this? If so it might be sensible to start with the MediaFile changes at beetbox/mediafile.