From 15a5eec37735a0471c976300a097d63f43ac6e9e Mon Sep 17 00:00:00 2001 From: bob Date: Sat, 13 May 2023 10:13:34 -0600 Subject: [PATCH 1/2] Add "Additional Artists Details" plugin, including documentation. --- .../additional_artists_details/__init__.py | 549 ++++++++++++++++++ .../additional_artists_details/docs/README.md | 82 +++ .../docs/option_settings.png | Bin 0 -> 64644 bytes .../options_additional_artists_details.ui | 139 +++++ .../ui_options_additional_artists_details.py | 86 +++ 5 files changed, 856 insertions(+) create mode 100644 plugins/additional_artists_details/__init__.py create mode 100644 plugins/additional_artists_details/docs/README.md create mode 100644 plugins/additional_artists_details/docs/option_settings.png create mode 100644 plugins/additional_artists_details/options_additional_artists_details.ui create mode 100644 plugins/additional_artists_details/ui_options_additional_artists_details.py diff --git a/plugins/additional_artists_details/__init__.py b/plugins/additional_artists_details/__init__.py new file mode 100644 index 00000000..91653f07 --- /dev/null +++ b/plugins/additional_artists_details/__init__.py @@ -0,0 +1,549 @@ +# -*- coding: utf-8 -*- +"""Additional Artists Details +""" +# Copyright (C) 2023 Bob Swift (rdswift) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# pylint: disable=line-too-long +# pylint: disable=import-error +# pylint: disable=too-many-arguments +# pylint: disable=too-many-locals + +from collections import namedtuple +from functools import partial + +from picard import ( + config, + log, +) +from picard.album import register_album_post_removal_processor +from picard.metadata import ( + register_album_metadata_processor, + register_track_metadata_processor, +) +from picard.plugin import PluginPriority +from picard.plugins.additional_artists_details.ui_options_additional_artists_details import ( + Ui_AdditionalArtistsDetailsOptionsPage, +) +from picard.webservice.api_helpers import MBAPIHelper + +from picard.ui.options import ( + OptionsPage, + register_options_page, +) + + +PLUGIN_NAME = 'Additional Artists Details' +PLUGIN_AUTHOR = 'Bob Swift (rdswift)' +PLUGIN_DESCRIPTION = ''' +This plugin provides specialized album and track variables with artist details for use in tagging and naming scripts. Note that this creates +additional calls to the MusicBrainz API for the artist and area information, and this will slow down processing. This will be particularly +noticable when there are many different album or track artists, such as on a [Various Artists] release. There is an option to disable track +artist processing, which can significantly increase the processing speed if you are only interested in album artist details. +

+Please see the user +guide on GitHub for more information. +''' +PLUGIN_VERSION = '0.3' +PLUGIN_API_VERSIONS = ['2.0', '2.1', '2.2', '2.7', '2.8'] +PLUGIN_LICENSE = 'GPL-2.0-or-later' +PLUGIN_LICENSE_URL = 'https://www.gnu.org/licenses/gpl-2.0.html' + +PLUGIN_USER_GUIDE_URL = 'https://github.com/rdswift/picard-plugins/blob/2.0_RDS_Plugins/plugins/additional_artists_details/docs/README.md' + +# Named tuples for code clarity +Area = namedtuple('Area', ['parent', 'name', 'country', 'type', 'type_text']) +MetadataPair = namedtuple('MetadataPair', ['artists', 'target']) + +# MusicBrainz ID codes for relationship types +RELATIONSHIP_TYPE_PART_OF = 'de7cc874-8b1b-3a05-8272-f3834c968fb7' + +# MusicBrainz ID codes for area types +AREA_TYPE_COUNTRY = '06dd0ae4-8c74-30bb-b43d-95dcedf961de' +AREA_TYPE_COUNTY = 'bcecec27-8bdb-3e00-8254-d948dda502fa' +AREA_TYPE_MUNICIPALITY = '17246454-5ac4-36a1-b81a-4753eb2dab20' + +# Area types to exclude from the location string +EXCLUDE_AREA_TYPES = {AREA_TYPE_MUNICIPALITY, AREA_TYPE_COUNTY} + +# Standard text for arguments +ALBUM_ARTISTS = 'album_artists' +ARTIST = 'artist' +ARTIST_REQUESTS = 'artist_requests' +AREA = 'area' +AREA_REQUESTS = 'area_requests' +ISO_CODES = 'iso-3166-1-codes' +OPT_AREA_DETAILS = 'aad_area_details' +OPT_PROCESS_TRACKS = 'aad_process_tracks' +TRACKS = 'tracks' + + +def log_helper(text, *args): + """Logging helper to prepend the plugin name to the text. + + Args: + text (str): Text to log. + args (list): List of text replacement arguments. + + Returns: + tuple: updated text and replacement arguments. + """ + return "%s: " + text, PLUGIN_NAME, *args + + +class CustomHelper(MBAPIHelper): + """Custom MusicBrainz API helper to retrieve artist and area information. + """ + + def get_artist_by_id(self, _id, handler, inc=None, priority=False, important=False, + mblogin=False, refresh=False): + """Get information for the specified artist MBID. + + Args: + _id (str): Artist MBID to retrieve. + handler (object): Callback used to process the returned information. + inc (list, optional): List of includes to add to the API call. Defaults to None. + priority (bool, optional): Process the request at a high priority. Defaults to False. + important (bool, optional): Identify the request as important. Defaults to False. + mblogin (bool, optional): Request requires logging into MusicBrainz. Defaults to False. + refresh (bool, optional): Request triggers a refresh. Defaults to False. + + Returns: + RequestTask: Requested task object. + """ + return self._get_by_id(ARTIST, _id, handler, inc, priority=priority, important=important, mblogin=mblogin, refresh=refresh) + + def get_area_by_id(self, _id, handler, inc=None, priority=False, important=False, mblogin=False, refresh=False): + """Get information for the specified area MBID. + + Args: + _id (str): Area MBID to retrieve. + handler (object): Callback used to process the returned information. + inc (list, optional): List of includes to add to the API call. Defaults to None. + priority (bool, optional): Process the request at a high priority. Defaults to False. + important (bool, optional): Identify the request as important. Defaults to False. + mblogin (bool, optional): Request requires logging into MusicBrainz. Defaults to False. + refresh (bool, optional): Request triggers a refresh. Defaults to False. + + Returns: + RequestTask: Requested task object. + """ + if inc is None: + inc = ['area-rels'] + return self._get_by_id(AREA, _id, handler, inc, priority=priority, important=important, mblogin=mblogin, refresh=refresh) + + +class ArtistDetailsPlugin: + """Plugin to retrieve artist details, including area and country information. + """ + result_cache = { + ARTIST: {}, + ARTIST_REQUESTS: set(), + AREA: {}, + AREA_REQUESTS: set(), + } + album_processing_count = {} + albums = {} + + def _make_empty_target(self, album_id): + """Create an empty album target node if it doesn't exist. + + Args: + album_id (str): MBID of the album. + """ + if album_id not in self.albums: + self.albums[album_id] = {ALBUM_ARTISTS: set(), TRACKS: []} + + def _add_target(self, album_id, artists, target_metadata): + """Add a metadata target to update for an album. + + Args: + album_id (str): MBID of the album. + artists (set): Set of artists to include. + target_metadata (Metadata): Target metadata to update. + """ + self._make_empty_target(album_id) + self.albums[album_id][TRACKS].append(MetadataPair(artists, target_metadata)) + + def _remove_album(self, album_id): + """Removes an album from the metadata processing dictionary. + + Args: + album_id (str): MBID of the album to remove. + """ + log.debug(*log_helper("Removing album '%s'", album_id)) + self.albums.pop(album_id, None) + self.album_processing_count.pop(album_id, None) + + def _album_add_request(self, album): + """Increment the number of pending requests for an album. + + Args: + album (Album): The Album object to use for the processing. + """ + if album.id not in self.album_processing_count: + self.album_processing_count[album.id] = 0 + self.album_processing_count[album.id] += 1 + album._requests += 1 + + def _album_remove_request(self, album): + """Decrement the number of pending requests for an album. + + Args: + album (Album): The Album object to use for the processing. + """ + if album.id not in self.album_processing_count: + self.album_processing_count[album.id] = 1 + self.album_processing_count[album.id] -= 1 + album._requests -= 1 + album._finalize_loading(None) # pylint: disable=protected-access + + def remove_album(self, album): + """Remove the album from the albums processing dictionary. + + Args: + album (Album): The album object to remove. + """ + self._remove_album(album.id) + + def make_album_vars(self, album, album_metadata, _release_metadata): + """Process album artists. + + Args: + album (Album): The Album object to use for the processing. + album_metadata (Metadata): Metadata object for the album. + _release_metadata (dict): Dictionary of release data from MusicBrainz api. + """ + artists = set(artist.id for artist in album.get_album_artists()) + self._make_empty_target(album.id) + self.albums[album.id][ALBUM_ARTISTS] = artists + if not config.setting[OPT_PROCESS_TRACKS]: + log.info(*log_helper("Track artist processing is disabled.")) + self._artist_processing(artists, album, album_metadata, 'Album') + + def make_track_vars(self, album, album_metadata, track_metadata, _release_metadata): + """Process track artists. + + Args: + album (Album): The Album object to use for the processing. + album_metadata (Metadata): Metadata object for the album. + track_metadata (dict): Dictionary of track data from MusicBrainz api. + _release_metadata (dict): Dictionary of release data from MusicBrainz api. + """ + artists = set() + source_type = 'track' + # Test for valid metadata node. + # The 'artist-credit' key should always be there. + # This check is to avoid a runtime error if it doesn't exist for some reason. + if config.setting[OPT_PROCESS_TRACKS]: + if 'artist-credit' in track_metadata: + for artist_credit in track_metadata['artist-credit']: + if 'artist' in artist_credit: + if 'id' in artist_credit['artist']: + artists.add(artist_credit['artist']['id']) + else: + # No 'artist' specified. Log as an error. + self._metadata_error(album.id, 'artist-credit.artist', source_type) + else: + # No valid metadata found. Log as error. + self._metadata_error(album.id, 'artist-credit', source_type) + self._artist_processing(artists, album, album_metadata, 'Track') + + def _artist_processing(self, artists, album, destination_metadata, source_type): + """Retrieves the information for each artist not already processed. + + Args: + artists (set): Set of artist MBIDs to process. + album (Album): Album object to use for the processing. + destination_metadata (Metadata): Metadata object to update with the new variables. + source_type (str): Source type (album or track) for logging messages. + """ + for temp_id in artists: + if temp_id not in self.result_cache[ARTIST_REQUESTS]: + self.result_cache[ARTIST_REQUESTS].add(temp_id) + log.debug(*log_helper('Retrieving artist ID %s information from MusicBrainz.', temp_id)) + self._get_artist_info(temp_id, album) + else: + log.debug(*log_helper('%s artist ID %s information available from cache.', source_type, temp_id)) + self._add_target(album.id, artists, destination_metadata) + self._save_artist_metadata(album.id) + + def _save_artist_metadata(self, album_id): + """Saves the new artist details variables to the metadata targets for the specified album. + + Args: + album_id (str): MBID of the album to process. + """ + if album_id in self.album_processing_count and self.album_processing_count[album_id]: + return + if album_id not in self.albums or not self.albums[album_id][TRACKS]: + log.error(*log_helper("No metadata targets found for album '%s'", album_id)) + return + for item in self.albums[album_id][TRACKS]: + # Add album artists to track so they are available in the metadata + artists = self.albums[album_id][ALBUM_ARTISTS].copy().union(item.artists) + destination_metadata = item.target + for artist in artists: + if artist in self.result_cache[ARTIST]: + self._set_artist_metadata(destination_metadata, artist, self.result_cache[ARTIST][artist]) + + def _set_artist_metadata(self, destination_metadata, artist_id, artist_info): + """Adds the artist information to the destination metadata. + + Args: + destination_metadata (Metadata): Metadata object to update with new variables. + artist_id (str): MBID of the artist to update. + artist_info (dict): Dictionary of information for the artist. + """ + def _set_item(key, value): + destination_metadata[f"~artist_{artist_id}_{key.replace('-', '_')}"] = value + + for item in artist_info.keys(): + if item in {'area', 'begin-area', 'end-area'}: + country, location = self._drill_area(artist_info[item]) + if country: + _set_item(item.replace('area', 'country'), country) + if location: + _set_item(item.replace('area', 'location'), location) + else: + _set_item(item, artist_info[item]) + + def _get_artist_info(self, artist_id, album): + """Gets the artist information from the MusicBrainz website. + + Args: + artist_id (str): MBID of the artist to retrieve. + album (Album): The Album object to use for the processing. + """ + self._album_add_request(album) + helper = CustomHelper(album.tagger.webservice) + handler = partial( + self._artist_submission_handler, + artist=artist_id, + album=album, + ) + return helper.get_artist_by_id(artist_id, handler) + + def _artist_submission_handler(self, document, _reply, error, artist=None, album=None): + """Handles the response from the webservice requests for artist information. + """ + try: + if error: + log.error(*log_helper("Artist '%s' information retrieval error.", artist)) + return + artist_info = {} + for item in ['type', 'gender', 'name', 'sort-name', 'disambiguation']: + if item in document and document[item]: + artist_info[item] = document[item] + if 'life-span' in document: + for item in ['begin', 'end']: + if item in document['life-span'] and document['life-span'][item]: + artist_info[item] = document['life-span'][item] + for item in ['area', 'begin-area', 'end-area']: + if item in document and document[item] and 'id' in document[item] and document[item]['id']: + area_id = document[item]['id'] + artist_info[item] = area_id + if area_id not in self.result_cache[AREA_REQUESTS]: + self._get_area_info(area_id, album) + self.result_cache[ARTIST][artist] = artist_info + finally: + self._album_remove_request(album) + self._save_artist_metadata(album.id) + + def _get_area_info(self, area_id, album): + """Gets the area information from the MusicBrainz website. + + Args: + area_id (str): MBID of the area to retrieve. + album (Album): The Album object to use for the processing. + """ + self.result_cache[AREA_REQUESTS].add(area_id) + self._album_add_request(album) + log.debug(*log_helper('Retrieving area ID %s from MusicBrainz.', area_id)) + helper = CustomHelper(album.tagger.webservice) + handler = partial( + self._area_submission_handler, + area=area_id, + album=album, + ) + return helper.get_area_by_id(area_id, handler) + + def _area_submission_handler(self, document, _reply, error, area=None, album=None): + """Handles the response from the webservice requests for area information. + """ + try: + if error: + log.error(*log_helper("Area '%s' information retrieval error.", area)) + return + (_id, name, country, _type, type_text) = self._parse_area(document) + if _type == AREA_TYPE_COUNTRY and _id not in self.result_cache[AREA]: + self._area_logger(_id, f"{name} ({country})", type_text) + self.result_cache[AREA][_id] = Area('', name, country, _type, type_text) + if 'relations' in document: + for rel in document['relations']: + self._parse_area_relation(_id, rel, album, name, _type, type_text) + finally: + self._album_remove_request(album) + self._save_artist_metadata(album.id) + + @staticmethod + def _area_logger(area_id, area_name, area_type): + """Adds a log entry for the area retrieved. + + Args: + area_id (str): MBID of the area added. + area_name (str): Name of the area added. + area_type (str): Type of area added. + """ + log.debug(*log_helper("Adding area: %s => %s of type '%s'", area_id, area_name, area_type)) + + def _parse_area_relation(self, area_id, area_relation, album, area_name, area_type, area_type_text): + """Parse an area relation to extract the area information. + + Args: + area_id (str): MBID of the area providing the relationship. + area_relation (dict): Dictionary of the area relationship. + album (Album): The Album object to use for the processing. + area_name (str): Name of the area providing the relationship. + area_type (str): MBID of the type of area providing the relationship. + area_type_text (str): Text description of the area providing the relationship. + """ + if 'type-id' not in area_relation or 'area' not in area_relation or area_relation['type-id'] != RELATIONSHIP_TYPE_PART_OF: + return + (_id, name, country, _type, type_text) = self._parse_area(area_relation['area']) + if not _id: + return + + if 'direction' in area_relation and area_relation['direction'] == 'backward': + if area_id not in self.result_cache[AREA]: + self._area_logger(area_id, area_name, area_type_text) + self.result_cache[AREA][area_id] = Area(_id, area_name, '', area_type, type_text) + self.result_cache[AREA_REQUESTS].add(area_id) + if _type == AREA_TYPE_COUNTRY: + if _id not in self.result_cache[AREA]: + self._area_logger(_id, f"{name} ({country})", type_text) + self.result_cache[AREA][_id] = Area('', name, country, _type, type_text) + self.result_cache[AREA_REQUESTS].add(_id) + else: + if _id not in self.result_cache[AREA] and _id not in self.result_cache[AREA_REQUESTS]: + self._get_area_info(_id, album) + else: + self._area_logger(_id, name, type_text) + self.result_cache[AREA_REQUESTS].add(_id) + self.result_cache[AREA][_id] = Area(area_id, name, '', _type, type_text) + + @staticmethod + def _parse_area(area_info): + """Parse a dictionary of area information to return selected elements. + + Args: + area_info (dict): Area information to parse. + + Returns: + tuple: Selected information for the area (id, name, country code, type code, type text). + """ + if 'id' not in area_info: + return ('', '', '', '', '') + area_id = area_info['id'] + area_name = area_info['name'] if 'name' in area_info else 'Unknown Name' + area_type = area_info['type-id'] if 'type-id' in area_info else '' + area_type_text = area_info['type'] if 'type' in area_info else 'Unknown Area Type' + if area_type == AREA_TYPE_COUNTRY: + country = area_info[ISO_CODES][0] if ISO_CODES in area_info and area_info[ISO_CODES] else '' + else: + country = '' + return (area_id, area_name, country, area_type, area_type_text) + + @staticmethod + def _metadata_error(album_id, metadata_element, metadata_group): + """Logs metadata-related errors. + + Args: + album_id (str): MBID of the album being processed. + metadata_element (str): Metadata element initiating the error. + metadata_group (str): Metadata group initiating the error. + """ + log.error(*log_helper("Album '%s' missing '%s' in %s metadata.", album_id, metadata_element, metadata_group)) + + def _drill_area(self, area_id): + """Drills up from the specified area to determine the two-character + country code and the full location description for the area. + + Args: + area_id (str): MBID of the area to process. + + Returns: + tuple: The two-character country code and full location description for the area. + """ + country = '' + location = [] + i = 7 # Counter to avoid potential runaway processing + while i and area_id and not country: + i -= 1 + area = self.result_cache[AREA][area_id] if area_id in self.result_cache[AREA] else Area('', '', '', '', '') + country = area.country + area_id = area.parent + if not location or config.setting[OPT_AREA_DETAILS] or area.type not in EXCLUDE_AREA_TYPES: + location.append(area.name) + return country, ', '.join(location) + + +class AdditionalArtistsDetailsOptionsPage(OptionsPage): + """Options page for the Additional Artists Details plugin. + """ + + NAME = "additional_artists_details" + TITLE = "Additional Artists Details" + PARENT = "plugins" + + options = [ + config.BoolOption('setting', OPT_PROCESS_TRACKS, False), + config.BoolOption('setting', OPT_AREA_DETAILS, False), + ] + + def __init__(self, parent=None): + super(AdditionalArtistsDetailsOptionsPage, self).__init__(parent) + self.ui = Ui_AdditionalArtistsDetailsOptionsPage() + self.ui.setupUi(self) + + # Enable external link + self.ui.format_description.setOpenExternalLinks(True) + + def load(self): + """Load the option settings. + """ + self.ui.cb_process_tracks.setChecked(config.setting[OPT_PROCESS_TRACKS]) + self.ui.cb_area_details.setChecked(config.setting[OPT_AREA_DETAILS]) + + def save(self): + """Save the option settings. + """ + # self._set_settings(config.setting) + config.setting[OPT_PROCESS_TRACKS] = self.ui.cb_process_tracks.isChecked() + config.setting[OPT_AREA_DETAILS] = self.ui.cb_area_details.isChecked() + + +plugin = ArtistDetailsPlugin() + +# Register the plugin to run at a LOW priority so that other plugins that +# modify the artist information can complete their processing and this plugin +# is working with the latest updated data. +register_album_metadata_processor(plugin.make_album_vars, priority=PluginPriority.LOW) +register_track_metadata_processor(plugin.make_track_vars, priority=PluginPriority.LOW) + +register_album_post_removal_processor(plugin.remove_album) +register_options_page(AdditionalArtistsDetailsOptionsPage) diff --git a/plugins/additional_artists_details/docs/README.md b/plugins/additional_artists_details/docs/README.md new file mode 100644 index 00000000..9f5e91cf --- /dev/null +++ b/plugins/additional_artists_details/docs/README.md @@ -0,0 +1,82 @@ +# Additional Artists Details + +## Overview + +This plugin provides specialized album and track variables with artist details such as type, gender, begin and end dates, location (begin, end and current) and country code (begin, end and current) for use in tagging and naming scripts. + +***NOTE:*** This plugin makes additional calls to the MusicBrainz website api for the information, which will slow down retrieving album information from MusicBrainz. This will be particularly noticable when there are many different album or track artists, such as on a \[Various Artists\] release. There is an option to disable track artist processing, which can significantly increase the processing speed if you are only interested in album artist details. + +--- + +## Option Settings + +The plugin adds a settings page under the "Plugins" section under "Options..." from Picard's main menu. This allows you to control how the plugin operates with respect to processing track artists and detail included in the artist location variables' content. + +![Additional Artists Details Option Settings](option_settings.png "Additional Artists Details Option Settings") + +--- + +## What it Does + +This plugin reads the album and track metadata provided to Picard, extracts the list of associated artists, retrieves the detailed information from the MusicBrainz website, and exposes the information in a number of additional variables for use in Picard scripts. + +### Variables Created + +* **\_artist_\{artist_id\}_begin** - The begin date (birth date) of the artist +* **\_artist_\{artist_id\}_begin_country** - The begin two-character country code of the artist +* **\_artist_\{artist_id\}_begin_location** - The begin location of the artist +* **\_artist_\{artist_id\}_country** - The two-character country code for the artist +* **\_artist_\{artist_id\}_disambiguation** - The disambiguation information for the artist +* **\_artist_\{artist_id\}_end** - The end date (death date) of the artist +* **\_artist_\{artist_id\}_end_country** - The end two-character country code of the artist +* **\_artist_\{artist_id\}_end_location** - The end location of the artist +* **\_artist_\{artist_id\}_gender** - The gender of the artist +* **\_artist_\{artist_id\}_name** - The name of the artist +* **\_artist_\{artist_id\}_sort_name** - The sort name of the artist +* **\_artist_\{artist_id\}_type** - The type of artist (person, group, etc.) + +A variable will only be created if the information is returned from MusicBrainz. For example, if a gender has not been specified in the MusicBrainz data then the **%\_artist_\{artist_id\}_gender%** variable will not be created. + +--- + +## Example + +If you load the release **Wrecking Ball** (release [8c759d7a-2ade-4201-abc2-a2a7c1a6ad6c](https://musicbrainz.org/release/8c759d7a-2ade-4201-abc2-a2a7c1a6ad6c)) by Sarah Blackwood (artist [af7e5ea9-bd58-4346-8f78-d672e9f297f7](https://musicbrainz.org/artist/af7e5ea9-bd58-4346-8f78-d672e9f297f7)), Jenni Pleau (artist [07fa21a9-c253-4ed0-b711-d63f7965b723](https://musicbrainz.org/artist/07fa21a9-c253-4ed0-b711-d63f7965b723)) & Emily Bones (artist [541d331c-f041-4895-b8f2-7db9e27dc5ab](https://musicbrainz.org/artist/541d331c-f041-4895-b8f2-7db9e27dc5ab)), the following variables will be created: + +Sarah Blackwood (primary artist): + +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_begin** = "1980-10-18" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_begin_country** = "CA" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_begin_location** = "Burlington, Ontario, Canada" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_country** = "CA" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_disambiguation** = "rockabilly, + "Somebody That I Used to Know"" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_gender** = "Female" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_location** = "Canada" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_name** = "Sarah Blackwood" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_sort_name** = "Blackwood, Sarah" +* **\_artist_af7e5ea9_bd58_4346_8f78_d672e9f297f7_type** = "Person" + +Jenny Pleau (additional artist) + +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_country** = "CA" +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_gender** = "Female" +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_location** = "Kitchener, Ontario, Canada" +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_name** = "Jenni Pleau" +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_sort_name** = "Pleau, Jenni" +* **\_artist_07fa21a9_c253_4ed0_b711_d63f7965b723_type** = "Person" + +Emily Bones (additional artist) + +* **\_artist_541d331c_f041_4895_b8f2_7db9e27dc5ab_gender** = "Female" +* **\_artist_541d331c_f041_4895_b8f2_7db9e27dc5ab_name** = "Emily Bones" +* **\_artist_541d331c_f041_4895_b8f2_7db9e27dc5ab_sort_name** = "Bones, Emily" +* **\_artist_541d331c_f041_4895_b8f2_7db9e27dc5ab_type** = "Person" + +Note that variables will only be created for information that exists for the artist's record. + +This could be used to set a **%country%** tag to the country code of the (primary) album artist with a tagging script like: + +```taggerscript +$set(_tmp,_artist_$getmulti(%musicbrainz_albumartistid%,0)_) +$set(country,$if2($get(%_tmp%country),$get(%_tmp%begin_country),$get(%_tmp%end_country),xx)) +``` diff --git a/plugins/additional_artists_details/docs/option_settings.png b/plugins/additional_artists_details/docs/option_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..ae6b439d1916a95647017a1f8466321e6e367740 GIT binary patch literal 64644 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 qoBzMdmh0n%{gm}DgMt@Qr@ literal 0 HcmV?d00001 diff --git a/plugins/additional_artists_details/options_additional_artists_details.ui b/plugins/additional_artists_details/options_additional_artists_details.ui new file mode 100644 index 00000000..ed08fd8e --- /dev/null +++ b/plugins/additional_artists_details/options_additional_artists_details.ui @@ -0,0 +1,139 @@ + + + AdditionalArtistsDetailsOptionsPage + + + + 0 + 0 + 561 + 802 + + + + + 100 + 0 + + + + Form + + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 543 + 784 + + + + + + + Additional Artists Details + + + + + + + 0 + 0 + + + + <html><head/><body><p>These settings will determine how the <span style=" font-weight:600;">Additional Artists Details</span> plugin operates.</p><p>Please visit the repository on GitHub for <a href="https://github.com/rdswift/picard-plugins/blob/2.0_RDS_Plugins/plugins/additional_artists_details/docs/README.md"><span style=" text-decoration: underline; color:#0000ff;">additional information</span></a>.</p></body></html> + + + true + + + + + + + + + + Process Track Artists + + + + + + <html><head/><body><p>This option determines whether or not details are retrieved for all track artists on the release. If you are only interested in details for the album artists then this should be disabled, thus significantly reducing the number of additional calls made to the MusicBrainz api and reducing the time required to load a release. Album artists are always processed.</p></body></html> + + + true + + + + + + + Process track artists + + + + + + + + + + Include Area Details + + + + + + <html><head/><body><p>This option determines whether or not County and Municipality information is included in the artist location variables created. Regardless of this setting, this information will be included if a County or Municipality is the area specified for an artist.</p></body></html> + + + true + + + + + + + Include area details + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/plugins/additional_artists_details/ui_options_additional_artists_details.py b/plugins/additional_artists_details/ui_options_additional_artists_details.py new file mode 100644 index 00000000..530af9c2 --- /dev/null +++ b/plugins/additional_artists_details/ui_options_additional_artists_details.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file './plugins/additional_artists_details/options_additional_artists_details.ui' +# +# Created by: PyQt5 UI code generator 5.15.6 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_AdditionalArtistsDetailsOptionsPage(object): + def setupUi(self, AdditionalArtistsDetailsOptionsPage): + AdditionalArtistsDetailsOptionsPage.setObjectName("AdditionalArtistsDetailsOptionsPage") + AdditionalArtistsDetailsOptionsPage.resize(561, 802) + AdditionalArtistsDetailsOptionsPage.setMinimumSize(QtCore.QSize(100, 0)) + self.verticalLayout = QtWidgets.QVBoxLayout(AdditionalArtistsDetailsOptionsPage) + self.verticalLayout.setObjectName("verticalLayout") + self.scrollArea = QtWidgets.QScrollArea(AdditionalArtistsDetailsOptionsPage) + self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setObjectName("scrollArea") + self.scrollAreaWidgetContents = QtWidgets.QWidget() + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 543, 784)) + self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.gb_description = QtWidgets.QGroupBox(self.scrollAreaWidgetContents) + self.gb_description.setObjectName("gb_description") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.gb_description) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.format_description = QtWidgets.QLabel(self.gb_description) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.format_description.sizePolicy().hasHeightForWidth()) + self.format_description.setSizePolicy(sizePolicy) + self.format_description.setWordWrap(True) + self.format_description.setObjectName("format_description") + self.verticalLayout_3.addWidget(self.format_description) + self.verticalLayout_2.addWidget(self.gb_description) + self.gb_process_track_artists = QtWidgets.QGroupBox(self.scrollAreaWidgetContents) + self.gb_process_track_artists.setObjectName("gb_process_track_artists") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.gb_process_track_artists) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.label = QtWidgets.QLabel(self.gb_process_track_artists) + self.label.setWordWrap(True) + self.label.setObjectName("label") + self.verticalLayout_4.addWidget(self.label) + self.cb_process_tracks = QtWidgets.QCheckBox(self.gb_process_track_artists) + self.cb_process_tracks.setObjectName("cb_process_tracks") + self.verticalLayout_4.addWidget(self.cb_process_tracks) + self.verticalLayout_2.addWidget(self.gb_process_track_artists) + self.gb_area_details = QtWidgets.QGroupBox(self.scrollAreaWidgetContents) + self.gb_area_details.setObjectName("gb_area_details") + self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.gb_area_details) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.label_2 = QtWidgets.QLabel(self.gb_area_details) + self.label_2.setWordWrap(True) + self.label_2.setObjectName("label_2") + self.verticalLayout_5.addWidget(self.label_2) + self.cb_area_details = QtWidgets.QCheckBox(self.gb_area_details) + self.cb_area_details.setObjectName("cb_area_details") + self.verticalLayout_5.addWidget(self.cb_area_details) + self.verticalLayout_2.addWidget(self.gb_area_details) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + self.verticalLayout.addWidget(self.scrollArea) + + self.retranslateUi(AdditionalArtistsDetailsOptionsPage) + QtCore.QMetaObject.connectSlotsByName(AdditionalArtistsDetailsOptionsPage) + + def retranslateUi(self, AdditionalArtistsDetailsOptionsPage): + _translate = QtCore.QCoreApplication.translate + AdditionalArtistsDetailsOptionsPage.setWindowTitle(_translate("AdditionalArtistsDetailsOptionsPage", "Form")) + self.gb_description.setTitle(_translate("AdditionalArtistsDetailsOptionsPage", "Additional Artists Details")) + self.format_description.setText(_translate("AdditionalArtistsDetailsOptionsPage", "

These settings will determine how the Additional Artists Details plugin operates.

Please visit the repository on GitHub for additional information.

")) + self.gb_process_track_artists.setTitle(_translate("AdditionalArtistsDetailsOptionsPage", "Process Track Artists")) + self.label.setText(_translate("AdditionalArtistsDetailsOptionsPage", "

This option determines whether or not details are retrieved for all track artists on the release. If you are only interested in details for the album artists then this should be disabled, thus significantly reducing the number of additional calls made to the MusicBrainz api and reducing the time required to load a release. Album artists are always processed.

")) + self.cb_process_tracks.setText(_translate("AdditionalArtistsDetailsOptionsPage", "Process track artists")) + self.gb_area_details.setTitle(_translate("AdditionalArtistsDetailsOptionsPage", "Include Area Details")) + self.label_2.setText(_translate("AdditionalArtistsDetailsOptionsPage", "

This option determines whether or not County and Municipality information is included in the artist location variables created. Regardless of this setting, this information will be included if a County or Municipality is the area specified for an artist.

")) + self.cb_area_details.setText(_translate("AdditionalArtistsDetailsOptionsPage", "Include area details")) From 0981cc56874ad9f7cbf942348dea0d5156ad509a Mon Sep 17 00:00:00 2001 From: bob Date: Sat, 13 May 2023 11:32:44 -0600 Subject: [PATCH 2/2] Update to work with Python 3.7 --- plugins/additional_artists_details/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/additional_artists_details/__init__.py b/plugins/additional_artists_details/__init__.py index 91653f07..e7fee04f 100644 --- a/plugins/additional_artists_details/__init__.py +++ b/plugins/additional_artists_details/__init__.py @@ -100,9 +100,11 @@ def log_helper(text, *args): args (list): List of text replacement arguments. Returns: - tuple: updated text and replacement arguments. + list: updated text and replacement arguments. """ - return "%s: " + text, PLUGIN_NAME, *args + retval = ["%s: " + text, PLUGIN_NAME] + retval.extend(args) + return retval class CustomHelper(MBAPIHelper):