mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
ftintitle: New customization option to keep feature in artist field (#5356)
This commit is contained in:
commit
98f4a88923
4 changed files with 42 additions and 8 deletions
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
----------------
|
----------------
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue