mirror of
https://github.com/beetbox/beets.git
synced 2026-01-09 17:33:51 +01:00
Fix mb_artistid, mb_albumartistid, albumtype diff issue
This commit is contained in:
parent
22163d70a7
commit
550a9a82b1
3 changed files with 85 additions and 1 deletions
|
|
@ -146,6 +146,43 @@ def apply_album_metadata(album_info: AlbumInfo, album: Album):
|
|||
_apply_metadata(album_info, album)
|
||||
|
||||
|
||||
def ensure_consistent_list_fields(i: Item) -> None:
|
||||
"""Synchronise single and list values for the list fields that we use.
|
||||
|
||||
That is, ensure the same value in the single field and the first element
|
||||
in the list.
|
||||
|
||||
For context, the value we set as, say, ``mb_artistid`` is simply ignored:
|
||||
Under the current :class:`MediaFile` implementation, fields ``albumtype``,
|
||||
``mb_artistid`` and ``mb_albumartistid`` are mapped to the first element of
|
||||
``albumtypes``, ``mb_artistids`` and ``mb_albumartistids`` respectively.
|
||||
|
||||
This means setting ``mb_artistid`` has no effect. However, beets
|
||||
functionality still assumes that ``mb_artistid`` is independent and stores
|
||||
its value in the database. If ``mb_artistid`` != ``mb_artistids[0]``,
|
||||
``beet write`` command thinks that ``mb_artistid`` is modified and tries to
|
||||
update the field in the file. Of course nothing happens, so the same diff
|
||||
is shown every time the command is run.
|
||||
|
||||
We can avoid this issue by ensuring that ``mb_artistid`` has the same value
|
||||
as ``mb_artistids[0]``, and that's what this function does.
|
||||
"""
|
||||
if aid := i.mb_artistid:
|
||||
i.mb_artistids = list(dict.fromkeys([aid, *i.mb_artistids]))
|
||||
elif aids := i.mb_artistids:
|
||||
i.mb_artistid = aids[0]
|
||||
|
||||
if aaid := i.mb_albumartistid:
|
||||
i.mb_albumartistids = list(dict.fromkeys([aaid, *i.mb_albumartistids]))
|
||||
elif aaids := i.mb_albumartistids:
|
||||
i.mb_albumartistid = aaids[0]
|
||||
|
||||
if atype := i.albumtype:
|
||||
i.albumtypes = list(dict.fromkeys([atype, *i.albumtypes]))
|
||||
elif atypes := i.albumtypes:
|
||||
i.albumtype = atypes[0]
|
||||
|
||||
|
||||
def apply_metadata(album_info: AlbumInfo, mapping: Mapping[Item, TrackInfo]):
|
||||
"""Set the items' metadata to match an AlbumInfo object using a
|
||||
mapping from Items to TrackInfo objects.
|
||||
|
|
@ -250,6 +287,8 @@ def apply_metadata(album_info: AlbumInfo, mapping: Mapping[Item, TrackInfo]):
|
|||
item.mb_albumartistids = album_info.artists_ids
|
||||
item.mb_releasegroupid = album_info.releasegroup_id
|
||||
|
||||
ensure_consistent_list_fields(item)
|
||||
|
||||
# Compilation flag.
|
||||
item.comp = album_info.va
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@ Bug fixes:
|
|||
have before the introduction of Poetry.
|
||||
:bug:`5531`
|
||||
:bug:`5526`
|
||||
* :ref:`write-cmd`: Fix the issue where for certain files differences in
|
||||
``mb_artistid``, ``mb_albumartistid`` and ``albumtype`` fields are shown on
|
||||
every attempt to write tags. Note: your music needs to be reimported with
|
||||
``beet import -LI`` or synchronised with ``beet mbsync`` in order to fix
|
||||
this!
|
||||
:bug:`5265`
|
||||
:bug:`5371`
|
||||
:bug:`4715`
|
||||
|
||||
For packagers:
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ import unittest
|
|||
import pytest
|
||||
|
||||
from beets import autotag, config
|
||||
from beets.autotag import AlbumInfo, TrackInfo, match
|
||||
from beets.autotag import (
|
||||
AlbumInfo,
|
||||
TrackInfo,
|
||||
ensure_consistent_list_fields,
|
||||
match,
|
||||
)
|
||||
from beets.autotag.hooks import Distance, string_dist
|
||||
from beets.library import Item
|
||||
from beets.test.helper import BeetsTestCase
|
||||
|
|
@ -1040,3 +1045,35 @@ class StringDistanceTest(unittest.TestCase):
|
|||
def test_accented_characters(self):
|
||||
dist = string_dist("\xe9\xe1\xf1", "ean")
|
||||
assert dist == 0.0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"single_field,list_field",
|
||||
[
|
||||
("mb_artistid", "mb_artistids"),
|
||||
("mb_albumartistid", "mb_albumartistids"),
|
||||
("albumtype", "albumtypes"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"single_value,list_value",
|
||||
[
|
||||
(None, []),
|
||||
(None, ["1"]),
|
||||
(None, ["1", "2"]),
|
||||
("1", []),
|
||||
("1", ["1"]),
|
||||
("1", ["1", "2"]),
|
||||
("1", ["2", "1"]),
|
||||
],
|
||||
)
|
||||
def test_ensure_consistent_list_fields(
|
||||
single_field, list_field, single_value, list_value
|
||||
):
|
||||
data = {single_field: single_value, list_field: list_value}
|
||||
item = Item(**data)
|
||||
|
||||
ensure_consistent_list_fields(item)
|
||||
|
||||
single_val, list_val = item[single_field], item[list_field]
|
||||
assert (not single_val and not list_val) or single_val == list_val[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue