Fix ftintitle plugin to prioritize explicit featuring tokens

- Prioritize explicit featuring tokens (feat, ft, featuring) over generic
  separators (&, and) when splitting artist names
- Prevents incorrect splits like 'Alice & Bob feat Charlie' from splitting
  on '&' instead of 'feat'
- Add test cases to verify the fix
This commit is contained in:
Matthew Kay 2025-12-10 20:52:37 +00:00
parent ffede9d4e6
commit 9ba3e12e8f
3 changed files with 23 additions and 4 deletions

View file

@ -36,11 +36,23 @@ def split_on_feat(
artist, which is always a string, and the featuring artist, which
may be a string or None if none is present.
"""
# split on the first "feat".
regex = re.compile(
plugins.feat_tokens(for_artist, custom_words), re.IGNORECASE
# Try explicit featuring tokens first (ft, feat, featuring, etc.)
# to avoid splitting on generic separators like "&" when both are present
regex_explicit = re.compile(
plugins.feat_tokens(for_artist=False, custom_words=custom_words),
re.IGNORECASE,
)
parts = tuple(s.strip() for s in regex.split(artist, 1))
parts = tuple(s.strip() for s in regex_explicit.split(artist, 1))
if len(parts) == 2:
return parts
# Fall back to all tokens including generic separators if no explicit match
if for_artist:
regex = re.compile(
plugins.feat_tokens(for_artist, custom_words), re.IGNORECASE
)
parts = tuple(s.strip() for s in regex.split(artist, 1))
if len(parts) == 1:
return parts[0], None
else:

View file

@ -62,6 +62,9 @@ Bug fixes:
"albumartist" instead of a list of unique album artists.
- Sanitize log messages by removing control characters preventing terminal
rendering issues.
- :doc:`/plugins/ftintitle`: Fixed artist name splitting to prioritize explicit
featuring tokens (feat, ft, featuring) over generic separators (&, and),
preventing incorrect splits when both are present.
For plugin developers:

View file

@ -303,6 +303,10 @@ def test_find_feat_part(
("Alice and Bob", ("Alice", "Bob")),
("Alice With Bob", ("Alice", "Bob")),
("Alice defeat Bob", ("Alice defeat Bob", None)),
("Alice & Bob feat Charlie", ("Alice & Bob", "Charlie")),
("Alice & Bob ft. Charlie", ("Alice & Bob", "Charlie")),
("Alice & Bob featuring Charlie", ("Alice & Bob", "Charlie")),
("Alice and Bob feat Charlie", ("Alice and Bob", "Charlie")),
],
)
def test_split_on_feat(