diff --git a/beetsplug/missing.py b/beetsplug/missing.py index 2e37fde788..d34fc10f87 100644 --- a/beetsplug/missing.py +++ b/beetsplug/missing.py @@ -171,6 +171,8 @@ def _missing_albums(self, lib, query): matching query. """ total = self.config["total"].get() + show_years = self.config["albums"]["years"].get(bool) + recent_albums_only = self.config["albums"]["recent"].get(bool) albums = lib.albums(query) # build dict mapping artist to list of their albums in library @@ -207,9 +209,16 @@ def _missing_albums(self, lib, query): missing = [] present = [] + + most_recent_album_year = None + if recent_albums_only: + most_recent_album_year = 0 + for rg in release_groups: missing.append(rg) for alb in albums: + if recent_albums_only and "year" in alb and alb["year"] > most_recent_album_year: + most_recent_album_year = alb["year"] if alb["mb_releasegroupid"] == rg["id"]: missing.remove(rg) present.append(rg) @@ -219,10 +228,14 @@ def _missing_albums(self, lib, query): if total: continue - missing_titles = {rg["title"] for rg in missing} - - for release_title in missing_titles: - print_("{} - {}".format(artist[0], release_title)) + if show_years: + missing_releases = self._missing_releases(missing, most_recent_album_year) + # print out missing albums for artist sorted by release year + for entry in list(sorted(missing_releases, key=lambda item: item[1])): + print_("{} - [{}] {} ({})".format(artist[0], entry[1], entry[2], entry[3])) + else: + for release_group in missing: + print_("{} - {} ({})".format(artist[0], release_group["title"], release_group["type"])) if total: print(total_missing) @@ -243,3 +256,61 @@ def _missing(self, album): album_info.album_id, ) yield item + + def _missing_releases(self, release_groups, _most_recent_album_year=None): + """Get the releases for the passed release groups. + Returns releases not before _most_recent_album_year if passed. + Returns releases as list of (release_group_id, release_year, title, release_type) + """ + missing_releases = [] + + for missing_release_group in release_groups: + # Get releases (e.g. album editions) for release-group + try: + resp = musicbrainzngs.browse_releases(release_group=missing_release_group["id"]) + releases = resp["release-list"] + except MusicBrainzError as err: + self._log.info( + "Couldn't fetch info for release-group '{}' ({}) - '{}'", + missing_release_group["title"], + missing_release_group["id"], + err, + ) + continue + + release_year = self._year_of_oldest_release(releases) + + # skip if only recent albums are searched for and it is not one + if _most_recent_album_year is not None and release_year < _most_recent_album_year: + continue + + release_type = "No Type" + + if "type" in missing_release_group: + release_type = missing_release_group["type"] + + missing_release = (missing_release_group["id"], + release_year, missing_release_group["title"], release_type) + + missing_releases.append(missing_release) + + return missing_releases + + def _year_of_oldest_release(self, releases): + """Returns the year of the oldest release out of the releases passed""" + oldest_year = 3000 + for release in releases: + if "date" in release: + # Get year from date, convert it and add it to list of years + year = int(release["date"][:4]) + if year < oldest_year: + oldest_year = year + self._log.debug( + "year {0} in release {1}", + year, + release["title"] + ) + + # return oldest year as first release year of the group + # return default-value for the rare case there are no years found + return oldest_year diff --git a/docs/changelog.rst b/docs/changelog.rst index d13d53527a..8b9f273431 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,10 @@ Changelog Changelog goes here! Please add your entry to the bottom of one of the lists below! +New features: + +* :doc:`/plugins/missing`: Add config options to show release years for missing albums and to show only releases not older than the latest in the library. + 2.0.0 (May 30, 2024) -------------------- diff --git a/docs/plugins/missing.rst b/docs/plugins/missing.rst index 38a0d5a088..4c3f6f68af 100644 --- a/docs/plugins/missing.rst +++ b/docs/plugins/missing.rst @@ -43,6 +43,12 @@ configuration file. The available options are: Default: :ref:`format_item`. - **total**: Print a single count of missing tracks in all albums. Default: ``no``. +- albums: Configuration options for displaying missing albums. + - **years**: Show release years of missing albums (see note below). + - **recent**: Show only releases of an artist not older than those already in the library. + +**Note:** Fetching the release year of missing releases results in additional data fetched from MusicBrainz, which +makes this process rather slow. So make sure to grab a coffee while waiting for the results ;-). Here's an example :: @@ -50,6 +56,9 @@ Here's an example :: format: $albumartist - $album - $title count: no total: no + albums: + years: no + recent: no Template Fields ---------------