ftintitle: New customization option to keep feature in artist field (#5356)

This commit is contained in:
J0J0 Todos 2024-09-06 13:41:15 +02:00 committed by GitHub
commit 98f4a88923
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 8 deletions

View file

@ -78,6 +78,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
"auto": True, "auto": True,
"drop": False, "drop": False,
"format": "feat. {0}", "format": "feat. {0}",
"keep_in_artist": False,
} }
) )
@ -101,10 +102,11 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
def func(lib, opts, args): def func(lib, opts, args):
self.config.set_args(opts) self.config.set_args(opts)
drop_feat = self.config["drop"].get(bool) drop_feat = self.config["drop"].get(bool)
keep_in_artist_field = self.config["keep_in_artist"].get(bool)
write = ui.should_write() write = ui.should_write()
for item in lib.items(ui.decargs(args)): for item in lib.items(ui.decargs(args)):
self.ft_in_title(item, drop_feat) self.ft_in_title(item, drop_feat, keep_in_artist_field)
item.store() item.store()
if write: if write:
item.try_write() item.try_write()
@ -120,15 +122,21 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
self.ft_in_title(item, drop_feat) self.ft_in_title(item, drop_feat)
item.store() item.store()
def update_metadata(self, item, feat_part, drop_feat): def update_metadata(self, item, feat_part, drop_feat, keep_in_artist_field):
"""Choose how to add new artists to the title and set the new """Choose how to add new artists to the title and set the new
metadata. Also, print out messages about any changes that are made. metadata. Also, print out messages about any changes that are made.
If `drop_feat` is set, then do not add the artist to the title; just If `drop_feat` is set, then do not add the artist to the title; just
remove it from the artist field. remove it from the artist field.
""" """
# In all cases, update the artist fields. # In case the artist is kept, do not update the artist fields.
if keep_in_artist_field:
self._log.info(
"artist: {0} (Not changing due to keep_in_artist)", item.artist
)
else:
self._log.info("artist: {0} -> {1}", item.artist, item.albumartist) self._log.info("artist: {0} -> {1}", item.artist, item.albumartist)
item.artist = item.albumartist item.artist = item.albumartist
if item.artist_sort: if item.artist_sort:
# Just strip the featured artist from the sort name. # Just strip the featured artist from the sort name.
item.artist_sort, _ = split_on_feat(item.artist_sort) item.artist_sort, _ = split_on_feat(item.artist_sort)
@ -142,7 +150,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
self._log.info("title: {0} -> {1}", item.title, new_title) self._log.info("title: {0} -> {1}", item.title, new_title)
item.title = new_title item.title = new_title
def ft_in_title(self, item, drop_feat): def ft_in_title(self, item, drop_feat, keep_in_artist_field):
"""Look for featured artists in the item's artist fields and move """Look for featured artists in the item's artist fields and move
them to the title. them to the title.
""" """
@ -163,6 +171,8 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
# If we have a featuring artist, move it to the title. # If we have a featuring artist, move it to the title.
if feat_part: if feat_part:
self.update_metadata(item, feat_part, drop_feat) self.update_metadata(
item, feat_part, drop_feat, keep_in_artist_field
)
else: else:
self._log.info("no featuring artists found") self._log.info("no featuring artists found")

View file

@ -14,6 +14,9 @@ New features:
`beet list -a title:something` or `beet list artpath:cover`. Consequently `beet list -a title:something` or `beet list artpath:cover`. Consequently
album queries involving `path` field have been sped up, like `beet list -a album queries involving `path` field have been sped up, like `beet list -a
path:/path/`. path:/path/`.
* New `keep_in_artist` option for the :doc:`plugins/ftintitle` plugin, which
allows keeping the "feat." part in the artist metadata while still changing
the title.
* :doc:`plugins/autobpm`: Add new configuration option ``beat_track_kwargs`` * :doc:`plugins/autobpm`: Add new configuration option ``beat_track_kwargs``
which enables adjusting keyword arguments supplied to librosa's which enables adjusting keyword arguments supplied to librosa's
``beat_track`` function call. ``beat_track`` function call.

View file

@ -27,6 +27,10 @@ file. The available options are:
- **format**: Defines the format for the featuring X part of the new title field. - **format**: Defines the format for the featuring X part of the new title field.
In this format the ``{0}`` is used to define where the featured artists are placed. In this format the ``{0}`` is used to define where the featured artists are placed.
Default: ``feat. {0}`` Default: ``feat. {0}``
- **keep_in_artist**: Keep the featuring X part in the artist field. This can
be useful if you still want to be able to search for features in the artist
field.
Default: ``no``.
Running Manually Running Manually
---------------- ----------------

View file

@ -33,10 +33,13 @@ class FtInTitlePluginFunctional(PluginTestCase):
albumartist=aartist, albumartist=aartist,
) )
def _ft_set_config(self, ftformat, drop=False, auto=True): def _ft_set_config(
self, ftformat, drop=False, auto=True, keep_in_artist=False
):
self.config["ftintitle"]["format"] = ftformat self.config["ftintitle"]["format"] = ftformat
self.config["ftintitle"]["drop"] = drop self.config["ftintitle"]["drop"] = drop
self.config["ftintitle"]["auto"] = auto self.config["ftintitle"]["auto"] = auto
self.config["ftintitle"]["keep_in_artist"] = keep_in_artist
def test_functional_drop(self): def test_functional_drop(self):
item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice") item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
@ -75,6 +78,20 @@ class FtInTitlePluginFunctional(PluginTestCase):
assert item["artist"] == "Alice" assert item["artist"] == "Alice"
assert item["title"] == "Song 1 with Bob" assert item["title"] == "Song 1 with Bob"
def test_functional_keep_in_artist(self):
self._ft_set_config("feat. {0}", keep_in_artist=True)
item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle")
item.load()
self.assertEqual(item["artist"], "Alice ft Bob")
self.assertEqual(item["title"], "Song 1 feat. Bob")
item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle", "-d")
item.load()
self.assertEqual(item["artist"], "Alice ft Bob")
self.assertEqual(item["title"], "Song 1")
class FtInTitlePluginTest(unittest.TestCase): class FtInTitlePluginTest(unittest.TestCase):
def setUp(self): def setUp(self):