mirror of
https://github.com/beetbox/beets.git
synced 2025-12-26 10:34:09 +01:00
lastgenre: Add --pretend option for previewing genre changes (#6008)
Introduce a `--pretend` option to the lastgenre plugin, allowing users to preview genre changes without making any modifications to their library. This feature enhances user control by showing potential changes before they are applied.
This commit is contained in:
commit
2c1aa27385
4 changed files with 84 additions and 15 deletions
|
|
@ -461,6 +461,12 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
|
||||
def commands(self):
|
||||
lastgenre_cmd = ui.Subcommand("lastgenre", help="fetch genres")
|
||||
lastgenre_cmd.parser.add_option(
|
||||
"-p",
|
||||
"--pretend",
|
||||
action="store_true",
|
||||
help="show actions but do nothing",
|
||||
)
|
||||
lastgenre_cmd.parser.add_option(
|
||||
"-f",
|
||||
"--force",
|
||||
|
|
@ -521,45 +527,64 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
|
||||
def lastgenre_func(lib, opts, args):
|
||||
write = ui.should_write()
|
||||
pretend = getattr(opts, "pretend", False)
|
||||
self.config.set_args(opts)
|
||||
|
||||
if opts.album:
|
||||
# Fetch genres for whole albums
|
||||
for album in lib.albums(args):
|
||||
album.genre, src = self._get_genre(album)
|
||||
album_genre, src = self._get_genre(album)
|
||||
prefix = "Pretend: " if pretend else ""
|
||||
self._log.info(
|
||||
'genre for album "{0.album}" ({1}): {0.genre}',
|
||||
'{}genre for album "{.album}" ({}): {}',
|
||||
prefix,
|
||||
album,
|
||||
src,
|
||||
album_genre,
|
||||
)
|
||||
if "track" in self.sources:
|
||||
album.store(inherit=False)
|
||||
else:
|
||||
album.store()
|
||||
if not pretend:
|
||||
album.genre = album_genre
|
||||
if "track" in self.sources:
|
||||
album.store(inherit=False)
|
||||
else:
|
||||
album.store()
|
||||
|
||||
for item in album.items():
|
||||
# If we're using track-level sources, also look up each
|
||||
# track on the album.
|
||||
if "track" in self.sources:
|
||||
item.genre, src = self._get_genre(item)
|
||||
item.store()
|
||||
item_genre, src = self._get_genre(item)
|
||||
self._log.info(
|
||||
'genre for track "{0.title}" ({1}): {0.genre}',
|
||||
'{}genre for track "{.title}" ({}): {}',
|
||||
prefix,
|
||||
item,
|
||||
src,
|
||||
item_genre,
|
||||
)
|
||||
if not pretend:
|
||||
item.genre = item_genre
|
||||
item.store()
|
||||
|
||||
if write:
|
||||
if write and not pretend:
|
||||
item.try_write()
|
||||
else:
|
||||
# Just query singletons, i.e. items that are not part of
|
||||
# an album
|
||||
for item in lib.items(args):
|
||||
item.genre, src = self._get_genre(item)
|
||||
item.store()
|
||||
item_genre, src = self._get_genre(item)
|
||||
prefix = "Pretend: " if pretend else ""
|
||||
self._log.info(
|
||||
"genre for track {0.title} ({1}): {0.genre}", item, src
|
||||
'{}genre for track "{0.title}" ({1}): {}',
|
||||
prefix,
|
||||
item,
|
||||
src,
|
||||
item_genre,
|
||||
)
|
||||
if not pretend:
|
||||
item.genre = item_genre
|
||||
item.store()
|
||||
if write and not pretend:
|
||||
item.try_write()
|
||||
|
||||
lastgenre_cmd.func = lastgenre_func
|
||||
return [lastgenre_cmd]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ Unreleased
|
|||
|
||||
New features:
|
||||
|
||||
- :doc:`plugins/lastgenre`: Add a ``--pretend`` option to preview genre changes
|
||||
without storing or writing them.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- :doc:`plugins/spotify` Fixed an issue where track matching and lookups could
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ tags** and will only **fetch new genres for empty tags**. When ``force`` is
|
|||
``yes`` the setting of the ``whitelist`` option (as documented in Usage_)
|
||||
applies to any existing or newly fetched genres.
|
||||
|
||||
The follwing configurations are possible:
|
||||
The following configurations are possible:
|
||||
|
||||
**Setup 1** (default)
|
||||
|
||||
|
|
@ -213,5 +213,9 @@ fetch genres for albums or items matching a certain query.
|
|||
By default, ``beet lastgenre`` matches albums. To match individual tracks or
|
||||
singletons, use the ``-A`` switch: ``beet lastgenre -A [QUERY]``.
|
||||
|
||||
To preview the changes that would be made without applying them, use the ``-p``
|
||||
or ``--pretend`` flag. This shows which genres would be set but does not write
|
||||
or store any changes.
|
||||
|
||||
To disable automatic genre fetching on import, set the ``auto`` config option to
|
||||
false.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
"""Tests for the 'lastgenre' plugin."""
|
||||
|
||||
from unittest.mock import Mock
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
|
@ -131,6 +131,43 @@ class LastGenrePluginTest(BeetsTestCase):
|
|||
"math rock",
|
||||
]
|
||||
|
||||
def test_pretend_option_skips_library_updates(self):
|
||||
item = self.create_item(
|
||||
album="Pretend Album",
|
||||
albumartist="Pretend Artist",
|
||||
artist="Pretend Artist",
|
||||
title="Pretend Track",
|
||||
genre="Original Genre",
|
||||
)
|
||||
album = self.lib.add_album([item])
|
||||
|
||||
command = self.plugin.commands()[0]
|
||||
opts, args = command.parser.parse_args(["--pretend"])
|
||||
|
||||
with patch.object(lastgenre.ui, "should_write", return_value=True):
|
||||
with patch.object(
|
||||
self.plugin,
|
||||
"_get_genre",
|
||||
return_value=("Mock Genre", "mock stage"),
|
||||
) as mock_get_genre:
|
||||
with patch.object(self.plugin._log, "info") as log_info:
|
||||
# Mock try_write to verify it's never called in pretend mode
|
||||
with patch.object(item, "try_write") as mock_try_write:
|
||||
command.func(self.lib, opts, args)
|
||||
|
||||
mock_get_genre.assert_called_once()
|
||||
|
||||
assert any(
|
||||
call.args[1] == "Pretend: " for call in log_info.call_args_list
|
||||
)
|
||||
|
||||
# Verify that try_write was never called (file operations skipped)
|
||||
mock_try_write.assert_not_called()
|
||||
|
||||
stored_album = self.lib.get_album(album.id)
|
||||
assert stored_album.genre == "Original Genre"
|
||||
assert stored_album.items()[0].genre == "Original Genre"
|
||||
|
||||
def test_no_duplicate(self):
|
||||
"""Remove duplicated genres."""
|
||||
self._setup_config(count=99)
|
||||
|
|
|
|||
Loading…
Reference in a new issue