mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
missing: clarify that only musicbrainz backend supports missing albums for artist
And give this functionality a small refactor.
This commit is contained in:
parent
4c1f217ce0
commit
441cd36e8a
2 changed files with 48 additions and 56 deletions
|
|
@ -24,10 +24,12 @@ from musicbrainzngs.musicbrainz import MusicBrainzError
|
|||
from beets import config
|
||||
from beets.autotag import hooks
|
||||
from beets.dbcore import types
|
||||
from beets.library import Album, Item
|
||||
from beets.library import Album, Item, Library
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.ui import Subcommand, decargs, print_
|
||||
|
||||
MB_ARTIST_QUERY = r"mb_albumartistid::^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$"
|
||||
|
||||
|
||||
def _missing_count(album):
|
||||
"""Return number of missing items in `album`."""
|
||||
|
|
@ -166,65 +168,51 @@ class MissingPlugin(BeetsPlugin):
|
|||
for item in self._missing(album):
|
||||
print_(format(item, fmt))
|
||||
|
||||
def _missing_albums(self, lib, query):
|
||||
def _missing_albums(self, lib: Library, query: list[str]) -> None:
|
||||
"""Print a listing of albums missing from each artist in the library
|
||||
matching query.
|
||||
"""
|
||||
total = self.config["total"].get()
|
||||
query.append(MB_ARTIST_QUERY)
|
||||
|
||||
albums = lib.albums(query)
|
||||
# build dict mapping artist to list of their albums in library
|
||||
albums_by_artist = defaultdict(list)
|
||||
for alb in albums:
|
||||
artist = (alb["albumartist"], alb["mb_albumartistid"])
|
||||
albums_by_artist[artist].append(alb)
|
||||
# build dict mapping artist to set of their album ids in library
|
||||
album_ids_by_artist = defaultdict(set)
|
||||
for album in lib.albums(query):
|
||||
# TODO(@snejus): Some releases have different `albumartist` for the
|
||||
# same `mb_albumartistid`. Since we're grouping by the combination
|
||||
# of these two fields, we end up processing the same
|
||||
# `mb_albumartistid` multiple times: calling MusicBrainz API and
|
||||
# reporting the same set of missing albums. Instead, we should
|
||||
# group by `mb_albumartistid` field only.
|
||||
artist = (album["albumartist"], album["mb_albumartistid"])
|
||||
album_ids_by_artist[artist].add(album)
|
||||
|
||||
total_missing = 0
|
||||
|
||||
# build dict mapping artist to list of all albums
|
||||
for artist, albums in albums_by_artist.items():
|
||||
if artist[1] is None or artist[1] == "":
|
||||
albs_no_mbid = ["'" + a["album"] + "'" for a in albums]
|
||||
self._log.info(
|
||||
"No musicbrainz ID for artist '{}' found in album(s) {}; "
|
||||
"skipping",
|
||||
artist[0],
|
||||
", ".join(albs_no_mbid),
|
||||
)
|
||||
continue
|
||||
|
||||
calculating_total = self.config["total"].get()
|
||||
for (artist, artist_id), album_ids in album_ids_by_artist.items():
|
||||
try:
|
||||
resp = musicbrainzngs.browse_release_groups(artist=artist[1])
|
||||
release_groups = resp["release-group-list"]
|
||||
resp = musicbrainzngs.browse_release_groups(artist=artist_id)
|
||||
except MusicBrainzError as err:
|
||||
self._log.info(
|
||||
"Couldn't fetch info for artist '{}' ({}) - '{}'",
|
||||
artist[0],
|
||||
artist[1],
|
||||
artist,
|
||||
artist_id,
|
||||
err,
|
||||
)
|
||||
continue
|
||||
|
||||
missing = []
|
||||
present = []
|
||||
for rg in release_groups:
|
||||
missing.append(rg)
|
||||
for alb in albums:
|
||||
if alb["mb_releasegroupid"] == rg["id"]:
|
||||
missing.remove(rg)
|
||||
present.append(rg)
|
||||
break
|
||||
missing_titles = [
|
||||
f"{artist} - {rg['title']}"
|
||||
for rg in resp["release-group-list"]
|
||||
if rg["id"] not in album_ids
|
||||
]
|
||||
|
||||
total_missing += len(missing)
|
||||
if total:
|
||||
continue
|
||||
if calculating_total:
|
||||
total_missing += len(missing_titles)
|
||||
else:
|
||||
for title in missing_titles:
|
||||
print(title)
|
||||
|
||||
missing_titles = {rg["title"] for rg in missing}
|
||||
|
||||
for release_title in missing_titles:
|
||||
print_("{} - {}".format(artist[0], release_title))
|
||||
|
||||
if total:
|
||||
if calculating_total:
|
||||
print(total_missing)
|
||||
|
||||
def _missing(self, album: Album) -> Iterator[Item]:
|
||||
|
|
|
|||
|
|
@ -8,24 +8,28 @@ call to album data source.
|
|||
Usage
|
||||
-----
|
||||
|
||||
Add the ``missing`` plugin to your configuration (see :ref:`using-plugins`). By
|
||||
default, the ``beet missing`` command fetches album information from the origin
|
||||
data source and lists names of the **tracks** that are missing from your
|
||||
library. It can also list the names of albums that
|
||||
your library is missing from each artist.
|
||||
You can customize the output format, count
|
||||
the number of missing tracks per album, or total up the number of missing
|
||||
tracks over your whole library, using command-line switches::
|
||||
Add the ``missing`` plugin to your configuration (see :ref:`using-plugins`).
|
||||
The ``beet missing`` command fetches album information from the origin data
|
||||
source and lists names of the **tracks** that are missing from your library.
|
||||
|
||||
It can also list the names of missing **albums** for each artist, although this
|
||||
is limited to albums from the MusicBrainz data source only.
|
||||
|
||||
You can customize the output format, show missing counts instead of track
|
||||
titles, or display the total number of missing entities across your entire
|
||||
library::
|
||||
|
||||
-f FORMAT, --format=FORMAT
|
||||
print with custom FORMAT
|
||||
-c, --count count missing tracks per album
|
||||
-t, --total count total of missing tracks or albums
|
||||
-a, --album show missing albums for artist instead of tracks
|
||||
-t, --total count totals across the entire library
|
||||
-a, --album show missing albums for artist instead of tracks for album
|
||||
|
||||
…or by editing corresponding options.
|
||||
…or by editing the corresponding configuration options.
|
||||
|
||||
Note that ``-c`` is ignored when used with ``-a``.
|
||||
.. warning::
|
||||
|
||||
Option ``-c`` is ignored when used with ``-a``.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue