Path help: merge "Artist feat. Guest" entries into "Artist/"

So… I’m using beets to try to wrangle a decades-old jumble of mp3s from every source under the sun into something resembling a library. It’s an interesting challenge! So far, I have chroma, discogs, and fromfilename working, and with the help of $albumartist_sort, $artist_sort, asciify_paths: yes and languages: en , I’m no longer creating folders on my computer with names in scripts I can’t read. We’re getting there!

My current problem is albums and singletons from “Artist feat. Guest” and all its variations. I do not want to remove this information from the files’ metadata fields, but I do want the Path format to sort all entries credited to “Artist feat. Guest” and “Artist & Collaborator” and so forth into the “Artist” folder. Given the amount of pattern-matching logic available in Path’s fields and functions and so forth, I expect this is possible, but I’d love some pointers on how to actually write it. I’m picturing something along the lines of:
%if{$artist_sort contains <any member of $feat_words_list>,%first{,1,,<whichever word matched>,},$artist_sort}

…but as you can see, there are some gaps:

  • how (where) do I define $feat_words_list?
  • how do I pass the individual word that matched to %first?
  • will this leave me with a trailing space?

Am I even on the right track here? Has somebody already written a plugin for this that I just haven’t found? Do I need to use the Inline plugin and see if I can cobble together a little Python function of my own?

Also, Adrian, would there be any interest in adding a built-in Path function like %strip_feat{} that would take a string as input and return the same string, but truncated right before the first occurrence of any one of a list of join-words? (Assuming I haven’t overlooked this functionality somewhere, of course.)

This post brought to you by:

  • Apocalyptica feat. Jandova, Marta,
  • Apocalyptica feat. Lombardo, Dave,
  • Apocalyptica feat. Sundblad, Linda,
  • Apocalyptica feat. Ylonen, Lauri, and
  • Apocalyptica & Hagen, Nina

…all of whom have top-level folders containing one singleton each in my practice-sandbox beets collection. :smirk:

Hi! FWIW, the “true” solution to this might be this unimplemented feature:

But for the time being, I’d recommend the inline plugin. That lets you write a little Python snippet that could do the exact string manipulation you want.

The idea to add a path function—which would be provided by the ftintitle plugin, I think—sounds pretty cool. Please feel free to file a feature request with a full description of how that would work if you’re interested.

Thanks for the prompt and helpful reply! You really raise the bar for developer responsiveness.

In a comment on the issue you linked to, ESaller has posted an Inline snippet that actually queries MusicBrainz for the mb_albumartistid and pulls the sort-name from the reply. If I understand this correctly, the sort_name will always be only the primary artist, because MB stores this type of collaboration info as a relationship, not combined into one artist name…?

This seems like a really smart approach (and much less fraught than regexes and string mangling), but I did run into some difficulties. The most obvious one is that as-is it won’t work for singletons, because they don’t have an mb_albumartistid, which makes sense. Also, when the lookup fails for any reason it causes the main beet process to crash, which strikes me as undesirable.

So… I expanded his snippet into two, one for album tracks and one for singletons. I also used a try/except to catch any failure of the lookup and fall back on the appropriate local sortname if available, and local name if all else fails. I’ve posted the result as a comment in that thread.

A feature request will follow!

1 Like