mirror of
https://github.com/beetbox/beets.git
synced 2026-02-20 06:14:22 +01:00
Merge branch 'master' into discogs-disambiguation-fix
This commit is contained in:
commit
e577df0f25
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