Skip to content

Commit d6a0b74

Browse files
committed
import: simplify tagging item
1 parent 4c7df4b commit d6a0b74

File tree

7 files changed

+260
-342
lines changed

7 files changed

+260
-342
lines changed

beets/autotag/__init__.py

Lines changed: 0 additions & 289 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,13 @@
1414

1515
"""Facilities for automatically determining files' correct metadata."""
1616

17-
from __future__ import annotations
18-
1917
import warnings
2018
from importlib import import_module
21-
from typing import TYPE_CHECKING
22-
23-
from beets import config, logging
24-
25-
# Parts of external interface.
26-
from beets.util import unique_list
2719

2820
from ..util import deprecate_imports
2921
from .hooks import AlbumInfo, AlbumMatch, TrackInfo, TrackMatch
3022
from .match import Proposal, Recommendation, tag_album, tag_item
3123

32-
if TYPE_CHECKING:
33-
from collections.abc import Sequence
34-
35-
from beets.library import Album, Item, LibModel
36-
3724

3825
def __getattr__(name: str):
3926
if name == "current_metadata":
@@ -59,282 +46,6 @@ def __getattr__(name: str):
5946
"Recommendation",
6047
"TrackInfo",
6148
"TrackMatch",
62-
"apply_album_metadata",
63-
"apply_item_metadata",
64-
"apply_metadata",
6549
"tag_album",
6650
"tag_item",
6751
]
68-
69-
# Global logger.
70-
log = logging.getLogger("beets")
71-
72-
# Metadata fields that are already hardcoded, or where the tag name changes.
73-
SPECIAL_FIELDS = {
74-
"album": (
75-
"va",
76-
"releasegroup_id",
77-
"artist_id",
78-
"artists_ids",
79-
"album_id",
80-
"mediums",
81-
"tracks",
82-
"year",
83-
"month",
84-
"day",
85-
"artist",
86-
"artists",
87-
"artist_credit",
88-
"artists_credit",
89-
"artist_sort",
90-
"artists_sort",
91-
"data_url",
92-
),
93-
"track": (
94-
"track_alt",
95-
"artist_id",
96-
"artists_ids",
97-
"release_track_id",
98-
"medium",
99-
"index",
100-
"medium_index",
101-
"title",
102-
"artist_credit",
103-
"artists_credit",
104-
"artist_sort",
105-
"artists_sort",
106-
"artist",
107-
"artists",
108-
"track_id",
109-
"medium_total",
110-
"data_url",
111-
"length",
112-
),
113-
}
114-
115-
116-
# Additional utilities for the main interface.
117-
118-
119-
def _apply_metadata(
120-
info: AlbumInfo | TrackInfo,
121-
db_obj: Album | Item,
122-
null_fields: bool = True,
123-
):
124-
"""Set the db_obj's metadata to match the info."""
125-
key = "album" if isinstance(info, AlbumInfo) else "track"
126-
special_fields = set(SPECIAL_FIELDS[key])
127-
nullable_fields = set(config["overwrite_null"][key].as_str_seq())
128-
129-
for field, value in info.items():
130-
# We only overwrite fields that are not already hardcoded.
131-
if field in special_fields:
132-
continue
133-
134-
# Don't overwrite fields with empty values unless the
135-
# field is explicitly allowed to be overwritten.
136-
if null_fields and value is None and field not in nullable_fields:
137-
continue
138-
139-
db_obj[field] = value
140-
141-
142-
def correct_list_fields(m: LibModel) -> None:
143-
"""Synchronise single and list values for the list fields that we use.
144-
145-
That is, ensure the same value in the single field and the first element
146-
in the list.
147-
148-
For context, the value we set as, say, ``mb_artistid`` is simply ignored:
149-
Under the current :class:`MediaFile` implementation, fields ``albumtype``,
150-
``mb_artistid`` and ``mb_albumartistid`` are mapped to the first element of
151-
``albumtypes``, ``mb_artistids`` and ``mb_albumartistids`` respectively.
152-
153-
This means setting ``mb_artistid`` has no effect. However, beets
154-
functionality still assumes that ``mb_artistid`` is independent and stores
155-
its value in the database. If ``mb_artistid`` != ``mb_artistids[0]``,
156-
``beet write`` command thinks that ``mb_artistid`` is modified and tries to
157-
update the field in the file. Of course nothing happens, so the same diff
158-
is shown every time the command is run.
159-
160-
We can avoid this issue by ensuring that ``mb_artistid`` has the same value
161-
as ``mb_artistids[0]``, and that's what this function does.
162-
163-
Note: :class:`Album` model does not have ``mb_artistids`` and
164-
``mb_albumartistids`` fields therefore we need to check for their presence.
165-
"""
166-
167-
def ensure_first_value(single_field: str, list_field: str) -> None:
168-
"""Ensure the first ``list_field`` item is equal to ``single_field``."""
169-
single_val, list_val = getattr(m, single_field), getattr(m, list_field)
170-
if single_val:
171-
setattr(m, list_field, unique_list([single_val, *list_val]))
172-
elif list_val:
173-
setattr(m, single_field, list_val[0])
174-
175-
ensure_first_value("albumtype", "albumtypes")
176-
177-
if hasattr(m, "mb_artistids"):
178-
ensure_first_value("mb_artistid", "mb_artistids")
179-
180-
if hasattr(m, "mb_albumartistids"):
181-
ensure_first_value("mb_albumartistid", "mb_albumartistids")
182-
183-
if hasattr(m, "artists_sort"):
184-
ensure_first_value("artist_sort", "artists_sort")
185-
186-
if hasattr(m, "artists_credit"):
187-
ensure_first_value("artist_credit", "artists_credit")
188-
189-
if hasattr(m, "albumartists_credit"):
190-
ensure_first_value("albumartist_credit", "albumartists_credit")
191-
192-
if hasattr(m, "artists"):
193-
ensure_first_value("artist", "artists")
194-
195-
if hasattr(m, "albumartists_sort"):
196-
ensure_first_value("albumartist_sort", "albumartists_sort")
197-
198-
199-
def apply_item_metadata(item: Item, track_info: TrackInfo):
200-
"""Set an item's metadata from its matched TrackInfo object."""
201-
item.artist = track_info.artist
202-
item.artists = track_info.artists
203-
item.artist_sort = track_info.artist_sort
204-
item.artists_sort = track_info.artists_sort
205-
item.artist_credit = track_info.artist_credit
206-
item.artists_credit = track_info.artists_credit
207-
item.title = track_info.title
208-
item.mb_trackid = track_info.track_id
209-
item.mb_releasetrackid = track_info.release_track_id
210-
if track_info.artist_id:
211-
item.mb_artistid = track_info.artist_id
212-
if track_info.artists_ids:
213-
item.mb_artistids = track_info.artists_ids
214-
215-
_apply_metadata(track_info, item)
216-
correct_list_fields(item)
217-
218-
# At the moment, the other metadata is left intact (including album
219-
# and track number). Perhaps these should be emptied?
220-
221-
222-
def apply_album_metadata(album_info: AlbumInfo, album: Album):
223-
"""Set the album's metadata to match the AlbumInfo object."""
224-
_apply_metadata(album_info, album, null_fields=False)
225-
correct_list_fields(album)
226-
227-
228-
def apply_metadata(
229-
album_info: AlbumInfo, item_info_pairs: list[tuple[Item, TrackInfo]]
230-
):
231-
"""Set items metadata to match corresponding tagged info."""
232-
for item, track_info in item_info_pairs:
233-
# Artist or artist credit.
234-
if config["artist_credit"]:
235-
item.artist = (
236-
track_info.artist_credit
237-
or track_info.artist
238-
or album_info.artist_credit
239-
or album_info.artist
240-
)
241-
item.artists = (
242-
track_info.artists_credit
243-
or track_info.artists
244-
or album_info.artists_credit
245-
or album_info.artists
246-
)
247-
item.albumartist = album_info.artist_credit or album_info.artist
248-
item.albumartists = album_info.artists_credit or album_info.artists
249-
else:
250-
item.artist = track_info.artist or album_info.artist
251-
item.artists = track_info.artists or album_info.artists
252-
item.albumartist = album_info.artist
253-
item.albumartists = album_info.artists
254-
255-
# Album.
256-
item.album = album_info.album
257-
258-
# Artist sort and credit names.
259-
item.artist_sort = track_info.artist_sort or album_info.artist_sort
260-
item.artists_sort = track_info.artists_sort or album_info.artists_sort
261-
item.artist_credit = (
262-
track_info.artist_credit or album_info.artist_credit
263-
)
264-
item.artists_credit = (
265-
track_info.artists_credit or album_info.artists_credit
266-
)
267-
item.albumartist_sort = album_info.artist_sort
268-
item.albumartists_sort = album_info.artists_sort
269-
item.albumartist_credit = album_info.artist_credit
270-
item.albumartists_credit = album_info.artists_credit
271-
272-
# Release date.
273-
for prefix in "", "original_":
274-
if config["original_date"] and not prefix:
275-
# Ignore specific release date.
276-
continue
277-
278-
for suffix in "year", "month", "day":
279-
key = f"{prefix}{suffix}"
280-
value = getattr(album_info, key) or 0
281-
282-
# If we don't even have a year, apply nothing.
283-
if suffix == "year" and not value:
284-
break
285-
286-
# Otherwise, set the fetched value (or 0 for the month
287-
# and day if not available).
288-
item[key] = value
289-
290-
# If we're using original release date for both fields,
291-
# also set item.year = info.original_year, etc.
292-
if config["original_date"]:
293-
item[suffix] = value
294-
295-
# Title.
296-
item.title = track_info.title
297-
298-
if config["per_disc_numbering"]:
299-
# We want to let the track number be zero, but if the medium index
300-
# is not provided we need to fall back to the overall index.
301-
if track_info.medium_index is not None:
302-
item.track = track_info.medium_index
303-
else:
304-
item.track = track_info.index
305-
item.tracktotal = track_info.medium_total or len(album_info.tracks)
306-
else:
307-
item.track = track_info.index
308-
item.tracktotal = len(album_info.tracks)
309-
310-
# Disc and disc count.
311-
item.disc = track_info.medium
312-
item.disctotal = album_info.mediums
313-
314-
# MusicBrainz IDs.
315-
item.mb_trackid = track_info.track_id
316-
item.mb_releasetrackid = track_info.release_track_id or item.mb_trackid
317-
318-
item.mb_albumid = album_info.album_id
319-
item.mb_releasegroupid = album_info.releasegroup_id
320-
321-
item.mb_albumartistid = album_info.artist_id
322-
item.mb_albumartistids = album_info.artists_ids or (
323-
[ai] if (ai := item.mb_albumartistid) else []
324-
)
325-
326-
item.mb_artistid = track_info.artist_id or item.mb_albumartistid
327-
item.mb_artistids = track_info.artists_ids or (
328-
[iai] if (iai := item.mb_artistid) else []
329-
)
330-
331-
# Compilation flag.
332-
item.comp = album_info.va
333-
334-
# Track alt.
335-
item.track_alt = track_info.track_alt
336-
337-
_apply_metadata(album_info, item)
338-
_apply_metadata(track_info, item)
339-
340-
correct_list_fields(item)

0 commit comments

Comments
 (0)