mirror of
https://github.com/beetbox/beets.git
synced 2026-01-20 15:14:13 +01:00
Document ArtistState
This commit is contained in:
parent
7d83a68bdd
commit
5523ca94a2
1 changed files with 54 additions and 7 deletions
|
|
@ -127,7 +127,23 @@ class TracklistInfo(TypedDict):
|
|||
|
||||
@dataclass
|
||||
class ArtistState:
|
||||
"""Represent Discogs artist credits.
|
||||
|
||||
This object centralizes the plugin's policy for which Discogs artist fields
|
||||
to prefer (name vs. ANV), how to treat 'Various', how to format join
|
||||
phrases, and how to separate featured artists. It exposes both per-artist
|
||||
components and fully joined strings for common tag targets like 'artist' and
|
||||
'artist_credit'.
|
||||
"""
|
||||
|
||||
class ValidArtist(NamedTuple):
|
||||
"""A normalized, render-ready artist entry extracted from Discogs data.
|
||||
|
||||
Instances represent the subset of Discogs artist information needed for
|
||||
tagging, including the join token following the artist and whether the
|
||||
entry is considered a featured appearance.
|
||||
"""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
credit: str
|
||||
|
|
@ -135,9 +151,14 @@ class ArtistState:
|
|||
is_feat: bool
|
||||
|
||||
def get_artist(self, property_name: str) -> str:
|
||||
return getattr(self, property_name) + (
|
||||
{",": ", ", "": ""}.get(self.join, f" {self.join} ")
|
||||
)
|
||||
"""Return the requested display field with its trailing join token.
|
||||
|
||||
The join token is normalized so commas become ', ' and other join
|
||||
phrases are surrounded with spaces, producing a single fragment that
|
||||
can be concatenated to form a full artist string.
|
||||
"""
|
||||
join = {",": ", ", "": ""}.get(self.join, f" {self.join} ")
|
||||
return f"{getattr(self, property_name)}{join}"
|
||||
|
||||
raw_artists: list[Artist]
|
||||
use_anv: bool
|
||||
|
|
@ -147,25 +168,38 @@ class ArtistState:
|
|||
|
||||
@property
|
||||
def info(self) -> ArtistInfo:
|
||||
"""Expose the state in the shape expected by downstream tag mapping."""
|
||||
return {k: getattr(self, k) for k in ArtistInfo.__annotations__} # type: ignore[return-value]
|
||||
|
||||
def strip_disambiguation(self, text: str) -> str:
|
||||
"""Removes discogs specific disambiguations from a string.
|
||||
Turns 'Label Name (5)' to 'Label Name' or 'Artist (1) & Another Artist (2)'
|
||||
to 'Artist & Another Artist'. Does nothing if strip_disambiguation is False."""
|
||||
"""Strip Discogs disambiguation suffixes from an artist or label string.
|
||||
|
||||
This removes Discogs-specific numeric suffixes like 'Name (5)' and can
|
||||
be applied to multi-artist strings as well (e.g., 'A (1) & B (2)'). When
|
||||
the feature is disabled, the input is returned unchanged.
|
||||
"""
|
||||
if self.should_strip_disambiguation:
|
||||
return DISAMBIGUATION_RE.sub("", text)
|
||||
return text
|
||||
|
||||
@cached_property
|
||||
def valid_artists(self) -> list[ValidArtist]:
|
||||
"""Build the ordered, filtered list of artists used for rendering.
|
||||
|
||||
The resulting list normalizes Discogs entries by:
|
||||
- substituting the configured 'Various Artists' name when Discogs uses
|
||||
'Various'
|
||||
- choosing between name and ANV according to plugin settings
|
||||
- excluding non-empty roles unless they indicate a featured appearance
|
||||
- capturing join tokens so the original credit formatting is preserved
|
||||
"""
|
||||
va_name = config["va_name"].as_str()
|
||||
return [
|
||||
self.ValidArtist(
|
||||
str(a["id"]),
|
||||
self.strip_disambiguation(anv if self.use_anv else name),
|
||||
self.strip_disambiguation(anv if self.use_credit_anv else name),
|
||||
a["join"],
|
||||
a["join"].strip(),
|
||||
is_feat,
|
||||
)
|
||||
for a in self.raw_artists
|
||||
|
|
@ -181,29 +215,42 @@ class ArtistState:
|
|||
|
||||
@property
|
||||
def artists_ids(self) -> list[str]:
|
||||
"""Return Discogs artist IDs for all valid artists, preserving order."""
|
||||
return [a.id for a in self.valid_artists]
|
||||
|
||||
@property
|
||||
def artist_id(self) -> str:
|
||||
"""Return the primary Discogs artist ID."""
|
||||
return self.artists_ids[0]
|
||||
|
||||
@property
|
||||
def artists(self) -> list[str]:
|
||||
"""Return the per-artist display names used for the 'artist' field."""
|
||||
return [a.name for a in self.valid_artists]
|
||||
|
||||
@property
|
||||
def artists_credit(self) -> list[str]:
|
||||
"""Return the per-artist display names used for the credit field."""
|
||||
return [a.credit for a in self.valid_artists]
|
||||
|
||||
@property
|
||||
def artist(self) -> str:
|
||||
"""Return the fully rendered artist string using display names."""
|
||||
return self.join_artists("name")
|
||||
|
||||
@property
|
||||
def artist_credit(self) -> str:
|
||||
"""Return the fully rendered artist credit string."""
|
||||
return self.join_artists("credit")
|
||||
|
||||
def join_artists(self, property_name: str) -> str:
|
||||
"""Render a single artist string with join phrases and featured artists.
|
||||
|
||||
Non-featured artists are concatenated using their join tokens. Featured
|
||||
artists are appended after the configured 'featured' marker, preserving
|
||||
Discogs order while keeping featured credits separate from the main
|
||||
artist string.
|
||||
"""
|
||||
non_featured = [a for a in self.valid_artists if not a.is_feat]
|
||||
featured = [a for a in self.valid_artists if a.is_feat]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue