def _process_asin_relation(try_list, relation): match = AMAZON_ASIN_URL_REGEX.match(relation.target[0].text) if match != None: asinHost = match.group(1) asin = match.group(2); if AMAZON_SERVER.has_key(asinHost): serverInfo = AMAZON_SERVER[asinHost] else: serverInfo = AMAZON_SERVER['amazon.com'] try_list.append({'host': serverInfo['server'], 'port': 80, 'path': AMAZON_IMAGE_PATH % (asin, serverInfo['id'], 'L') }) try_list.append({'host': serverInfo['server'], 'port': 80, 'path': AMAZON_IMAGE_PATH % (asin, serverInfo['id'], 'M') }) def _try_list_append_image_url(try_list, parsedUrl): path = str(parsedUrl.encodedPath()) if parsedUrl.hasQuery(): path += '?' + parsedUrl.encodedQuery() try_list.append({ 'host': str(parsedUrl.host()), 'port': parsedUrl.port(80), 'path': str(path) }) picard.webservice.REQUEST_DELAY[("coverartarchive.org", 80)] = 0 register_album_metadata_processor(coverart)
album._requests -= 1 album._finalize_loading(None) def original_release_date(album, metadata, release_node): # First find the earliest release from the release event list get_earliest_release_date(album, metadata) # Check for earliest release ARs and load those if release_node.children.has_key('relation_list'): for relation_list in release_node.relation_list: if relation_list.target_type == 'Release': for relation in relation_list.relation: try: direction = relation.direction if hasattr(relation, 'direction') else '' if (relation.type == 'FirstAlbumRelease' and direction == 'backward') \ or (relation.type == 'Remaster' and direction != 'backward'): album._requests += 1 album.tagger.xmlws.get_release_by_id(relation.target, partial(_earliest_release_downloaded, album, metadata, relation.target), ['release-events']) except AttributeError: pass def get_earliest_release_date(album, metadata): earliest_date = metadata["originaldate"] for event in album.release_events: if not earliest_date or (event.date and event.date < earliest_date): earliest_date = event.date metadata["originaldate"] = earliest_date register_album_metadata_processor(original_release_date)
artists = metadata.getall(artist_key) for r in _feat_re: for i, v in enumerate(artists): match = r.match(v) if match: artists[i] = match.group(1) new = split_artists(match.group(2)) artists.extend(new) for k in other_keys: match = r.match(metadata[k]) if match: metadata[k] = match.group(1) new = split_artists(match.group(2)) artists.extend(new) metadata.set(artist_key, artists) def add_album_feat_artists(tagger, metadata, release): _add_feat_artists(metadata, "albumartist", ["album"]) def add_track_feat_artists(tagger, metadata, track, release): _add_feat_artists(metadata, "artist", ["title"]) register_album_metadata_processor(add_album_feat_artists) register_track_metadata_processor(add_track_feat_artists)
new_artists = list(map(string_title_case, artists)) new_artist = [ artist_title_case(x, artists, new_artists) for x in artist ] if artists != new_artists and artist != new_artist: log.debug("SmartTitleCase: %s: %s replaced with %s", artist_string, artist, new_artist) log.debug("SmartTitleCase: %s: %r replaced with %r", artists_list, artists, new_artists) metadata[artist_string] = new_artist metadata[artists_list] = new_artists elif artists != new_artists or artist != new_artist: if artists != new_artists: log.warning("SmartTitleCase: %s changed, %s wasn't", artists_list, artist_string) log.warning("SmartTitleCase: %s: %r changed to %r", artists_list, artists, new_artists) log.warning("SmartTitleCase: %s: %r unchanged", artist_string, artist) else: log.warning("SmartTitleCase: %s changed, %s wasn't", artist_string, artists_list) log.warning("SmartTitleCase: %s: %r changed to %r", artist_string, artist, new_artist) log.warning("SmartTitleCase: %s: %r unchanged", artists_list, artists) register_track_metadata_processor(title_case) register_album_metadata_processor(title_case)
for relation in relation_list.relation: if relation.target.startswith(discogs_release_url): return relation.target except AttributeError: log.info('Error retrieving release discogs url') pass def process_album(tagger, metadata, release): release_url = get_release_url(release) request = urllib2.Request(discogs_request_url.format(release_url, discogs_api_key), None, discogs_request_headers) try: response = urllib2.urlopen(request) data = response.read() try: data = gzip.GzipFile(fileobj = cStringIO.StringIO(data)).read() except IOError: pass except urllib2.HTTPError, e: logger.info(e.read()) genres = [] doc = libxml2.parseMemory(data, len(data)) for url in doc.xpathEval('/resp/release/genres/genre'): genres.append(url.content) for url in doc.xpathEval('/resp/release/styles/style'): genres.append(url.content) metadata['genre'] = genres register_album_metadata_processor(process_album)
if metadata['releasestatus'] != 'pseudo-release' and metadata['script'] != script: if release_node.children.has_key('relation_list'): for relation_list in release_node.relation_list: if relation_list.target_type == 'release': for relation in relation_list.relation: try: direction = relation.direction if hasattr(relation, 'direction') else '' if (relation.type == 'transl-tracklisting' and direction != 'backward'): album._requests += 1 album.tagger.xmlws.get_release_by_id(relation.target[0].text, partial(_pseudo_release_downloaded, album, metadata, relation.target[0].text), ['recordings', 'artist-credits']) except AttributeError: pass register_album_metadata_processor(fetch_transliterations) def set_transliterations(tagger, metadata, track, release): global tracks if tracks['has_transliteration'] == False: return try: metadata['discsubtitle'] = tracks["mediums"][ int(metadata['discnumber']) ] except: pass try: metadata["artist"] = tracks[ int(metadata['discnumber']) ][ int(metadata['tracknumber']) ]["artist"] except: pass metadata["albumartist"] = tracks["artist"] try:
try: getattr(getattr(self.ui, option[1]), self.loadVars[option[0]])(option[2]) # self.ui.alpha_number.setChecked(option[2]) except: pass # If there's no control in the UI, don't try to set it! def save_defaults(self): # In Windows, saved to HKEY_CURRENT_USER\Software\MusicBrainz\Picard\setting for option in self.cfg.defaults: self.options.setting[option[1]] = option[2] def load(self): for option in self.cfg.defaults: try: getattr(getattr(self.ui, option[1]), self.loadVars[option[0]])(self.options.setting[option[1]]) # self.ui.alpha_number.setChecked(self.options.setting['alpha_number']) except: try: getattr(getattr(self.ui, option[1]), self.loadVars[option[0]])(option[2]) # self.ui.alpha_number.setChecked(self.options.setting['alpha_number']) except: pass # If there's no control in the UI, don't try to set it! def save(self): for option in self.cfg.defaults: try: self.options.setting[option[1]] = getattr(getattr(self.ui, option[1]), self.saveVars[option[0]])() # self.options.setting['alpha_number'] = self.ui.alpha_number.isChecked() except: #self.options.setting[option[1]] = option[2] # self.options.setting['alpha_number'] = option[2] pass register_album_metadata_processor(addalbum) register_track_metadata_processor(addtrack) register_options_page(abetterpathoptionspage)
vol = "9" elif rom_match.group(1) == "X": vol = "10" metadata["discsubtitle"] = vol if rom_match.group(3): metadata["discsubtitle"] = metadata["discsubtitle"] + rom_match.group(3) metadata["album"] = _rom_re.sub('', metadata["album"]) num_match = _num_re.search(metadata["album"]) if num_match and not subfound == 1: metadata["discsubtitle"] = num_match.group(1) if num_match.group(2): metadata["discsubtitle"] = metadata["discsubtitle"] + num_match.group(2) metadata["album"] = _num_re.sub('', metadata["album"]) word_match = _word_re.search(metadata["album"]) if word_match and not subfound == 1: if word_match.group(1) == "One": vol = "1" elif word_match.group(1) == "Two": vol = "2" elif word_match.group(1) == "Three": vol = "3" elif word_match.group(1) == "Four": vol = "4" elif word_match.group(1) == "Five": vol = "5" metadata["discsubtitle"] = vol metadata["album"] = _word_re.sub('', metadata["album"]) register_album_metadata_processor(move_subtitles)
import re #================== # options #================== _SINGLE = " (single)" _EP = " EP" def add_release_type(tagger, metadata, release): # make sure "EP" (or "single", ...) is not already a word in the name words = metadata["album"].lower().split(" ") for word in ["ep", "e.p.", "single", "(single)"]: if word in words: return # check release type if metadata["releasetype"] == "ep": rs = _EP elif metadata["releasetype"] == "single": rs = _SINGLE else: rs = "" # append title metadata["album"] = metadata["album"] + rs register_album_metadata_processor(add_release_type)
# -*- coding: utf-8 -*- # Copyright © 2015 Samir Benmendil <*****@*****.**> # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. PLUGIN_NAME = 'Soundtrack' PLUGIN_AUTHOR = 'Samir Benmendil' PLUGIN_LICENSE = 'WTFPL' PLUGIN_LICENSE_URL = 'http://www.wtfpl.net/' PLUGIN_DESCRIPTION = '''Sets the albumartist to "Soundtrack" if releasetype is a soundtrack.''' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["1.0"] from picard.metadata import register_album_metadata_processor def soundtrack(tagger, metadata, release): if "soundtrack" in metadata["releasetype"]: metadata["albumartist"] = "Soundtrack" register_album_metadata_processor(soundtrack)
# Put this here so that above unit tests can run standalone before getting an import error from picard import log from picard.metadata import ( register_track_metadata_processor, register_album_metadata_processor, ) def abbrev_artistsort_metadata(tagger, metadata, release, track=None): for artist_string, artists_list, original_artist, original_artists in artist_tags: if artist_string in metadata and artists_list in metadata: artists = metadata.getall(artists_list) artist = metadata.getall(artist_string) abbrev_artists = map(abbreviate_artist, artists) abbrev_artist = [abbreviate_artistsort(x, artists, abbrev_artists) for x in artist] if artists != abbrev_artists and artist != abbrev_artist: log.debug("AbbrevArtistSort2: Abbreviated %s from %r to %r", artists_list, artists, abbrev_artists) metadata[original_artists] = artists metadata[artists_list] = abbrev_artists log.debug("AbbrevArtistSort2: Abbreviated %s from %r to %r", artist_string, artist, abbrev_artist) metadata[original_artist] = artist metadata[artist_string] = abbrev_artist elif artists != abbrev_artists or artist != abbrev_artist: if artists != abbrev_artists: log.warning("AbbrevArtistSort2: %s abbreviated, %s wasn't", artists_list, artist_string) else: log.warning("AbbrevArtistSort2: %s abbreviated, %s wasn't", artist_string, artists_list) register_track_metadata_processor(abbrev_artistsort_metadata) register_album_metadata_processor(abbrev_artistsort_metadata)
super(NoReleaseOptionsPage, self).__init__(parent) self.ui = Ui_NoReleaseOptionsPage() self.ui.setupUi(self) def load(self): self.ui.norelease_strip_tags.setText( config.setting['norelease_strip_tags']) self.ui.norelease_enable.setChecked(config.setting['norelease_enable']) def save(self): config.setting['norelease_strip_tags'] = str( self.ui.norelease_strip_tags.text()) config.setting[ 'norelease_enable'] = self.ui.norelease_enable.isChecked() def no_release_album_processor(tagger, metadata, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) def no_release_track_processor(tagger, metadata, track, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) register_album_metadata_processor(no_release_album_processor) register_track_metadata_processor(no_release_track_processor) register_album_action(NoReleaseAction()) register_options_page(NoReleaseOptionsPage)
return post_data(search_data, "album_search", albumtitle, albumartist, album, metadata) def artist_search(album, metadata, albumtitle, albumartist): search_data = "P=amg&opt1=1&sql=" + QtCore.QUrl.toPercentEncoding(albumartist) return post_data(search_data, "artist_search", albumtitle, albumartist, album, metadata) def clean_album_title(albumtitle): albumtitle = re.sub(r"\s+\(disc (\d+)(?::\s+([^)]+))?\)", r"", albumtitle) albumtitle = re.sub(r"\s+\(bonus disc(?::\s+([^)]+))?\)", r"", albumtitle) return albumtitle def allmusic_genre(album, metadata, release): if metadata["albumartist"] != "Various Artists": albumartist = translate_artist(metadata["artist"], metadata["artistsort"]) else: albumartist = metadata["albumartist"] albumtitle = clean_album_title(metadata["album"]) albumartist = unicode(ununicode(albumartist)) albumtitle = unicode(ununicode(albumtitle)) print " * Looking for " + albumtitle + " by " + albumartist print " * Sending album search request", album._requests += 1 album.tagger.xmlws.add_task(partial(album_search, album, metadata, albumtitle, albumartist), position=1) register_album_metadata_processor(allmusic_genre) # register_options_page(AllMusicOptionsPage)
PLUGIN_NAME = 'Disc Numbers' PLUGIN_AUTHOR = 'Lukas Lalinsky' PLUGIN_DESCRIPTION = '''Moves disc numbers and subtitles from album titles to separate tags. For example:<br/> <em>"Aerial (disc 1: A Sea of Honey)"</em> <ul> <li>album = <em>"Aerial"</em></li> <li>discnumber = <em>"1"</em></li> <li>discsubtitle = <em>"A Sea of Honey"</em></li> </ul>''' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "2.0"] from picard.metadata import register_album_metadata_processor import re _discnumber_re = re.compile(r"\s+\(disc (\d+)(?::\s+([^)]+))?\)") def remove_discnumbers(tagger, metadata, release): matches = _discnumber_re.search(metadata["album"]) if matches: metadata["discnumber"] = matches.group(1) if matches.group(2): metadata["discsubtitle"] = matches.group(2) metadata["album"] = _discnumber_re.sub('', metadata["album"]) register_album_metadata_processor(remove_discnumbers)
new_string += s return new_string def title(string, locale="utf-8"): """Title-case a string using a less destructive method than str.title.""" if not string: return u"" # if the string is all uppercase, lowercase it - Erich/Javier # Lots of Japanese songs use entirely upper-case English titles, # so I don't like this change... - JoeW #if string == string.upper(): string = string.lower() if not isinstance(string, unicode): string = string.decode(locale) return utitle(string) PLUGIN_NAME = "Title Case" PLUGIN_API_VERSIONS = ["0.9", "0.10", "0.11"] PLUGIN_DESCRIPTION = "Capitalize First Character In Every Word Of A Title" from picard.metadata import ( register_track_metadata_processor, register_album_metadata_processor, ) def title_case(tagger, metadata, release, track=None): for name, value in metadata.rawitems(): if name in ["title", "album", "artist"]: metadata[name] = [title(x) for x in value] register_track_metadata_processor(title_case) register_album_metadata_processor(title_case)
PLUGIN_NAME = 'Feat. Artists in Titles' PLUGIN_AUTHOR = 'Lukas Lalinsky, Michael Wiencek, Bryan Toth' PLUGIN_DESCRIPTION = 'Move "feat." from artist names to album and track titles. Match is case insensitive.' PLUGIN_VERSION = "0.3" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16"] from picard.metadata import register_album_metadata_processor, register_track_metadata_processor import re _feat_re = re.compile(r"([\s\S]+) feat\.([\s\S]+)", re.IGNORECASE) def move_album_featartists(tagger, metadata, release): match = _feat_re.match(metadata["albumartist"]) if match: metadata["albumartist"] = match.group(1) metadata["album"] += " (feat.%s)" % match.group(2) def move_track_featartists(tagger, metadata, release, track): match = _feat_re.match(metadata["artist"]) if match: metadata["artist"] = match.group(1) metadata["title"] += " (feat.%s)" % match.group(2) register_album_metadata_processor(move_album_featartists) register_track_metadata_processor(move_track_featartists)
# Check for earliest release ARs and load those if 'relation_list' in release_node.children: for relation_list in release_node.relation_list: if relation_list.target_type == 'Release': for relation in relation_list.relation: try: direction = relation.direction if hasattr( relation, 'direction') else '' if (relation.type == 'FirstAlbumRelease' and direction == 'backward') \ or (relation.type == 'Remaster' and direction != 'backward'): album._requests += 1 album.tagger.xmlws.get_release_by_id( relation.target, partial(_earliest_release_downloaded, album, metadata, relation.target), ['release-events']) except AttributeError: pass def get_earliest_release_date(album, metadata): earliest_date = metadata["originaldate"] for event in album.release_events: if not earliest_date or (event.date and event.date < earliest_date): earliest_date = event.date metadata["originaldate"] = earliest_date register_album_metadata_processor(original_release_date)
u"®": "(R)", u"℠": "(SM)", u"™": "(TM)", } FILTER_TAGS = [ "album", "artist", "title", ] def sanitize(char): if char in CHAR_TABLE: return CHAR_TABLE[char] return char def ascii(word): return "".join(sanitize(char) for char in word) def main(tagger, metadata, release, track=None): for name, value in metadata.rawitems(): if name in FILTER_TAGS: metadata[name] = [ascii(x) for x in value] metadata.register_track_metadata_processor(main) metadata.register_album_metadata_processor(main)
PLUGIN_NAME = 'Feat. Artists in Titles (Modified)' PLUGIN_AUTHOR = 'Lukas Lalinsky, Michael Wiencek, Bryan Toth, JeromyNix (NobahdiAtoll), snobdiggy' PLUGIN_DESCRIPTION = 'Move "feat." from artist names to track titles. Removes "feat." from album artists.' \ 'Match is case insensitive.' PLUGIN_VERSION = "0.1.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16", "2.0"] _feat_re = re.compile(r"([\s\S]+) feat\.([\s\S]+)", re.IGNORECASE) def remove_album_featartists(tagger, metadata, release): for field in ['albumartist', 'albumartistsort']: match = _feat_re.match(metadata[field]) if match: metadata[field] = match.group(1) def move_track_featartists(tagger, metadata, track, release): for field in ['artist', 'artistsort']: if metadata[field]: match = _feat_re.match(metadata[field]) if match: metadata[field] = match.group(1) if field == 'artist': metadata['title'] += " (feat.%s)" % match.group(2) register_album_metadata_processor(remove_album_featartists, priority=PluginPriority.LOW) register_track_metadata_processor(move_track_featartists, priority=PluginPriority.LOW)
log.debug("Queuing cover art image %r", coverartimage) self.__queue.append(coverartimage) def _queue_get(self): """Get next image and remove it from queue""" return self.__queue.pop(0) def _queue_empty(self): """Returns True if the queue is empty""" return not self.__queue def _queue_new(self): """Initialize the queue""" self.__queue = [] def _message(self, *args, **kwargs): """Display message to status bar""" QObject.tagger.window.set_statusbar_message(*args, **kwargs) def _retrieve_coverart(album, metadata, release): """Gets all cover art URLs from the metadata and then attempts to download the album art. """ coverart = CoverArt(album, metadata, release) log.debug("New %r", coverart) coverart.retrieve() register_album_metadata_processor(_retrieve_coverart)
# Populate the variables metadata['~{}_google_romanised_search'.format( source_type)] = romanised_string_search metadata['~{}_google_romanised'.format( source_type)] = romanised_string else: log.error('%s: Romanisation failed', PLUGIN_NAME) def make_album_vars(self, mbz_tagger, metadata, release): try: mbz_id = release['id'] except (KeyError, TypeError, ValueError, AttributeError): mbz_id = 'N/A' if metadata['script'].lower() not in banned_scripts: self.make_vars(mbz_tagger, metadata, release, 'album') else: log.info('%s: Script is not whitelisted, skipping release ID "%s"', PLUGIN_NAME, mbz_id) def make_track_vars(self, mbz_tagger, metadata, track, release): if metadata['script'].lower() not in banned_scripts: self.make_vars(mbz_tagger, metadata, release, 'title') register_album_metadata_processor(GoogleRomaniser().make_album_vars, priority=PluginPriority.HIGH) register_track_metadata_processor(GoogleRomaniser().make_track_vars, priority=PluginPriority.HIGH)
setting["acousticbrainz_add_simplemood"]) self.ui.add_simplegenre.setChecked( setting["acousticbrainz_add_simplegenre"]) self.ui.add_fullhighlevel.setChecked( setting["acousticbrainz_add_fullhighlevel"]) self.ui.add_keybpm.setChecked(setting["acousticbrainz_add_keybpm"]) self.ui.add_sublowlevel.setChecked( setting["acousticbrainz_add_sublowlevel"]) def save(self): setting = config.setting setting[ "acousticbrainz_add_simplemood"] = self.ui.add_simplemood.isChecked( ) setting[ "acousticbrainz_add_simplegenre"] = self.ui.add_simplegenre.isChecked( ) setting["acousticbrainz_add_keybpm"] = self.ui.add_keybpm.isChecked() setting[ "acousticbrainz_add_fullhighlevel"] = self.ui.add_fullhighlevel.isChecked( ) setting[ "acousticbrainz_add_sublowlevel"] = self.ui.add_sublowlevel.isChecked( ) plugin = AcousticBrainzPlugin() register_album_metadata_processor(plugin.process_album) register_track_metadata_processor(plugin.process_track) register_options_page(AcousticBrainzOptionsPage)
if side_discnumber == orig_discnumber \ and side_first_tracknumber <= orig_tracknumber \ and orig_tracknumber <= side_last_tracknumber: return side raise RuntimeError('Unable to find side for track: ' + metadata) def analyze_release(tagger, metadata, release): """Analyze a release to determine if its sides should be re-ordered""" side_info = get_side_info(release) if side_info is not None: release_to_side_info[metadata['musicbrainz_albumid']] = side_info register_album_metadata_processor(analyze_release) def reorder_sides(tagger, metadata, *args): """Re-order sides of a release, using the information in release_to_side_info.""" if metadata['musicbrainz_albumid'] not in release_to_side_info: return side_info = release_to_side_info[metadata['musicbrainz_albumid']] all_sides = list(side_info.keys()) side = find_side(side_info, metadata) side_first_tracknumber = side_info[side][1] side_last_tracknumber = side_info[side][2]
# -*- coding: utf-8 -*- # Copyright © 2015 Samir Benmendil <*****@*****.**> # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. PLUGIN_NAME = 'Soundtrack' PLUGIN_AUTHOR = 'Samir Benmendil' PLUGIN_LICENSE = 'WTFPL' PLUGIN_LICENSE_URL = 'http://www.wtfpl.net/' PLUGIN_DESCRIPTION = '''Sets the albumartist to "Soundtrack" if releasetype is a soundtrack.''' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["1.0"] from picard.metadata import register_album_metadata_processor def soundtrack(tagger, metadata, release): if "soundtrack" in metadata["releasetype"]: metadata["albumartist"] = "Soundtrack" metadata["albumartistsort"] = "Soundtrack" register_album_metadata_processor(soundtrack)
PLUGIN_NAME = u"Separate audio and video medium count" PLUGIN_AUTHOR = u"Mark Trolley" PLUGIN_DESCRIPTION = u'''Separates the count of audio mediums and video mediums for a release. With this plugin you can use %_totalaudiomediums% and/or %_totalvideomediums% instead of %totaldiscs% in file name formatting.''' PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = [ "2.0" ] from picard.metadata import register_album_metadata_processor video_mediums = [ u"DVD", u"DVD-Video", u"Blu-ray", u"HD-DVD", u"Videotape", u"VHS", u"Betamax", u"VCD", u"CDV", u"SVCD", u"LaserDisc" ] def count_release_mediums(tagger, metadata, release): total_video_mediums = 0 total_mediums = int(metadata["totaldiscs"] or "0") if total_mediums > 1: for medium in release["media"]: if (medium["format"] in video_mediums): total_video_mediums += 1 metadata["~totalvideomediums"] = total_video_mediums metadata["~totalaudiomediums"] = total_mediums - total_video_mediums register_album_metadata_processor(count_release_mediums)
cap = False new_string += s return new_string def title(string): """Title-case a string using a less destructive method than str.title.""" if not string: return "" # if the string is all uppercase, lowercase it - Erich/Javier # Lots of Japanese songs use entirely upper-case English titles, # so I don't like this change... - JoeW #if string == string.upper(): string = string.lower() return utitle(str(string)) from picard.metadata import ( register_track_metadata_processor, register_album_metadata_processor, ) def title_case(tagger, metadata, *args): for name, value in metadata.rawitems(): if name in ["title", "album", "artist"]: metadata[name] = [title(x) for x in value] register_track_metadata_processor(title_case, priority=PluginPriority.LOW) register_album_metadata_processor(title_case, priority=PluginPriority.LOW)
album_metadata[ "~aaeSortPrimaryAlbumArtist"] = tempSortName else: log.error( "%s: %r: Missing 'artist' in XML contents: %s", PLUGIN_NAME, albumid, releaseXmlNode) aCount += 1 else: log.error("%s: %r: Missing 'name_credit' in XML contents: %s", PLUGIN_NAME, albumid, releaseXmlNode) if len(stdArtist) > 0: album_metadata["~aaeStdAlbumArtists"] = stdArtist if len(credArtist) > 0: album_metadata["~aaeCredAlbumArtists"] = credArtist if len(sortArtist) > 0: album_metadata["~aaeSortAlbumArtists"] = sortArtist if aCount > 0: album_metadata["~aaeAlbumArtistCount"] = aCount else: log.error("%s: %r: Error reading XML contents: %s", PLUGIN_NAME, albumid, releaseXmlNode) return None # Register the plugin to run at a LOW priority so that other plugins that # modify the contents of the _albumartists and _albumartists_sort lists can # complete their processing and this plugin is working with the latest # updated data. register_album_metadata_processor(AlbumArtistStdName().add_artist_std_name, priority=PluginPriority.LOW)
_re_articles['mul'] = re.compile(_regmul[1:]) def make_sorttitle(title, lang): if lang not in _re_articles: lang = "mul" sort_re = _re_articles[lang] match = sort_re.match(title) titlesort = title if match: sort_prefix = match.group().strip() titlesort = sort_re.sub("", title).strip() + ", " + sort_prefix titlesort = titlesort[0].upper() + titlesort[1:] # capitalize first letter return titlesort def add_titlesort(tagger, metadata, release, track): if metadata["titlesort"]: titlesort = metadata["titlesort"] else: titlesort = metadata["title"] metadata["titlesort"] = make_sorttitle(titlesort, metadata["language"]) def add_albumsort(tagger, metadata, release): if metadata["albumsort"]: titlesort = metadata["albumsort"] else: titlesort = metadata["album"] metadata["albumsort"] = make_sorttitle(titlesort, metadata["language"]) register_track_metadata_processor(add_titlesort) register_album_metadata_processor(add_albumsort)
PLUGIN_NAME = 'Feat. Artists in Titles' PLUGIN_AUTHOR = 'Lukas Lalinsky, Michael Wiencek' PLUGIN_DESCRIPTION = 'Move "feat." from artist names to album and track titles.' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15"] from picard.metadata import register_album_metadata_processor, register_track_metadata_processor import re def move_album_featartists(tagger, metadata, release): match = re.match(r"([\s\S]+) feat.([\s\S]+)", metadata["albumartist"]) if match: metadata["albumartist"] = match.group(1) metadata["album"] += " (feat.%s)" % match.group(2) def move_track_featartists(tagger, metadata, release, track): match = re.match(r"([\s\S]+) feat.([\s\S]+)", metadata["artist"]) if match: metadata["artist"] = match.group(1) metadata["title"] += " (feat.%s)" % match.group(2) register_album_metadata_processor(move_album_featartists) register_track_metadata_processor(move_track_featartists)
def standardise_feat(artists_str, artists_list): match_exp = r"(\s*.*\s*)".join((map(re.escape, artists_list))) try: join_phrases = re.match(match_exp, artists_str).groups() except AttributeError: log.debug("Unable to standardise artists: %r", artists_str) return artists_str else: standardised_join_phrases = [_feat_re.sub(" feat. ", phrase) for phrase in join_phrases] # Add a blank string at the end to allow zipping of # join phrases and artists_list since there is one less join phrase standardised_join_phrases.append("") return "".join([artist + join_phrase for artist, join_phrase in zip(artists_list, standardised_join_phrases)]) def standardise_track_artist(tagger, metadata, track, release): metadata["artist"] = standardise_feat(metadata["artist"], metadata.getall("artists")) metadata["artistsort"] = standardise_feat(metadata["artistsort"], metadata.getall("~artists_sort")) def standardise_album_artist(tagger, metadata, release): metadata["albumartist"] = standardise_feat(metadata["albumartist"], metadata.getall("~albumartists")) metadata["albumartistsort"] = standardise_feat(metadata["albumartistsort"], metadata.getall("~albumartists_sort")) register_track_metadata_processor(standardise_track_artist, priority=PluginPriority.HIGH) register_album_metadata_processor(standardise_album_artist, priority=PluginPriority.HIGH)
dcrelease = dcurl[slashindex+1:len(dcurl)] _process_discogs_release(dcrelease) def _process_discogs_release(dcrelease): log.error ("discogs release id is: %s", dcrelease) dcapiurl = DISCOGS_API_URL + dcrelease request = urllib2.Request(dcapiurl) request.add_header('User-Agent',DISCOGS_USER_AGENT) response = urllib2.urlopen(request) dcreleaseresource = response.read() dcapiresp = json.loads(dcreleaseresource) dcimages = dcapiresp['resp']['release']['images'] for dcimg in dcimages: if dcimg['type'] == 'primary': log.error(dcimg['resource_url']) response.close() register_album_metadata_processor(get_discogs_cover)
cred_artist += temp_cred_name + temp_phrase sort_artist += temp_sort_name + temp_phrase if artist_count < 1: album_metadata["~aaeStdPrimaryAlbumArtist"] = temp_std_name album_metadata["~aaeCredPrimaryAlbumArtist"] = temp_cred_name album_metadata["~aaeSortPrimaryAlbumArtist"] = temp_sort_name artist_count += 1 else: metadata_error(album_id, 'artist-credit') if std_artist: album_metadata["~aaeStdAlbumArtists"] = std_artist if cred_artist: album_metadata["~aaeCredAlbumArtists"] = cred_artist if sort_artist: album_metadata["~aaeSortAlbumArtists"] = sort_artist if artist_count: album_metadata["~aaeAlbumArtistCount"] = artist_count return None def metadata_error(album_id, metadata_element): log.error("%s: %r: Missing '%s' in release metadata.", PLUGIN_NAME, album_id, metadata_element) # 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(add_artist_std_name, priority=PluginPriority.LOW)
super(NoReleaseOptionsPage, self).__init__(parent) self.ui = Ui_NoReleaseOptionsPage() self.ui.setupUi(self) def load(self): self.ui.norelease_strip_tags.setText( config.setting['norelease_strip_tags']) self.ui.norelease_enable.setChecked(config.setting['norelease_enable']) def save(self): config.setting['norelease_strip_tags'] = str( self.ui.norelease_strip_tags.text()) config.setting[ 'norelease_enable'] = self.ui.norelease_enable.isChecked() def NoReleaseAlbumProcessor(tagger, metadata, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) def NoReleaseTrackProcessor(tagger, metadata, track, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) register_album_metadata_processor(NoReleaseAlbumProcessor) register_track_metadata_processor(NoReleaseTrackProcessor) register_album_action(NoReleaseAction()) register_options_page(NoReleaseOptionsPage)
PLUGIN_NAME = 'Disc Numbers' PLUGIN_AUTHOR = 'Lukas Lalinsky' PLUGIN_DESCRIPTION = '''Moves disc numbers and subtitles from album titles to separate tags. For example:<br/> <em>"Aerial (disc 1: A Sea of Honey)"</em> <ul> <li>album = <em>"Aerial"</em></li> <li>discnumber = <em>"1"</em></li> <li>discsubtitle = <em>"A Sea of Honey"</em></li> </ul>''' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15"] from picard.metadata import register_album_metadata_processor import re _discnumber_re = re.compile(r"\s+\(disc (\d+)(?::\s+([^)]+))?\)") def remove_discnumbers(tagger, metadata, release): matches = _discnumber_re.search(metadata["album"]) if matches: metadata["discnumber"] = matches.group(1) if matches.group(2): metadata["discsubtitle"] = matches.group(2) metadata["album"] = _discnumber_re.sub('', metadata["album"]) register_album_metadata_processor(remove_discnumbers)
from picard.metadata import register_album_metadata_processor import re #================== # options #================== _SINGLE = " (single)" _EP = " EP" def add_release_type(tagger, metadata, release): # make sure "EP" (or "single", ...) is not already a word in the name words = metadata["album"].lower().split(" ") for word in ["ep", "e.p.", "single", "(single)"]: if word in words: return # check release type if metadata["releasetype"] == "ep": rs = _EP elif metadata["releasetype"] == "single": rs = _SINGLE else: rs = "" # append title metadata["album"] = metadata["album"] + rs register_album_metadata_processor(add_release_type)
log.debug("Queuing cover art image %r", coverartimage) self.__queue.append(coverartimage) def _queue_get(self): """Get next image and remove it from queue""" return self.__queue.pop(0) def _queue_empty(self): """Returns True if the queue is empty""" return not self.__queue def _queue_new(self): """Initialize the queue""" self.__queue = [] def _message(self, *args, **kwargs): """Display message to status bar""" QObject.tagger.window.set_statusbar_message(*args, **kwargs) def _retrieve_coverart(album, metadata, release): """Gets all cover art URLs from the metadata and then attempts to download the album art. """ coverart = CoverArt(album, metadata, release) log.debug("New %r", coverart) coverart.retrieve() register_album_metadata_processor(_retrieve_coverart)
and orig_tracknumber <= side_last_tracknumber: return side raise RuntimeError('Unable to find side for track: ' + metadata) def analyze_release(tagger, metadata, release): """Analyze a release to determine if its sides should be re-ordered""" side_info = get_side_info(release) if side_info is not None: release_to_side_info[metadata['musicbrainz_albumid']] = side_info register_album_metadata_processor(analyze_release) def reorder_sides(tagger, metadata, *args): """Re-order sides of a release, using the information in release_to_side_info.""" if metadata['musicbrainz_albumid'] not in release_to_side_info: return side_info = release_to_side_info[metadata['musicbrainz_albumid']] all_sides = list(side_info.keys()) side = find_side(side_info, metadata) side_first_tracknumber = side_info[side][1] side_last_tracknumber = side_info[side][2]
from picard.track import Track from picard.script import ScriptParser from picard.ui.item import Item from picard.util import format_time, mbid_validate from picard.util.textencoding import asciipunct from picard.cluster import Cluster from picard.collection import Collection, user_collections from picard.mbxml import ( release_group_to_metadata, release_to_metadata, medium_to_metadata, track_to_metadata, ) from picard.const import VARIOUS_ARTISTS_ID register_album_metadata_processor(coverart) class AlbumArtist(DataObject): def __init__(self, id): DataObject.__init__(self, id) class Album(DataObject, Item): release_group_loaded = QtCore.pyqtSignal() def __init__(self, id, discid=None): DataObject.__init__(self, id) self.metadata = Metadata() self.tracks = []
source_type, )] = sort_pri_artist if artist_count: destination_metadata['~artists_{0}_all_count'.format( source_type, )] = artist_count def make_album_vars(album, album_metadata, release_metadata): album_id = release_metadata['id'] if release_metadata else 'No Album ID' process_artists(album_id, release_metadata, album_metadata, 'album') def make_track_vars(album, album_metadata, track_metadata, release_metadata): album_id = release_metadata['id'] if release_metadata else 'No Album ID' process_artists(album_id, track_metadata, album_metadata, 'track') def metadata_error(album_id, metadata_element, metadata_group): log.error("{0}: {1!r}: Missing '{2}' in {3} metadata.".format( PLUGIN_NAME, album_id, metadata_element, metadata_group, )) # 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(make_album_vars, priority=PluginPriority.LOW) register_track_metadata_processor(make_track_vars, priority=PluginPriority.LOW)
options = [ BoolOption('setting', 'norelease_enable', False), TextOption('setting', 'norelease_strip_tags', 'asin,barcode,catalognumber,date,label,media,releasecountry,releasestatus'), ] def __init__(self, parent=None): super(NoReleaseOptionsPage, self).__init__(parent) self.ui = Ui_NoReleaseOptionsPage() self.ui.setupUi(self) def load(self): self.ui.norelease_strip_tags.setText(self.config.setting['norelease_strip_tags']) self.ui.norelease_enable.setChecked(self.config.setting['norelease_enable']) def save(self): self.config.setting['norelease_strip_tags'] = unicode(self.ui.norelease_strip_tags.text()) self.config.setting['norelease_enable'] = self.ui.norelease_enable.isChecked() def NoReleaseAlbumProcessor(tagger, metadata, release): if tagger.config.setting['norelease_enable']: strip_release_specific_metadata(tagger, metadata) def NoReleaseTrackProcessor(tagger, metadata, track, release): if tagger.config.setting['norelease_enable']: strip_release_specific_metadata(tagger, metadata) register_album_metadata_processor(NoReleaseAlbumProcessor) register_track_metadata_processor(NoReleaseTrackProcessor) register_album_action(NoReleaseAction()) register_options_page(NoReleaseOptionsPage)
wanted_tags = ( "title", "artist", "albumartist", "album", "date", "genre", "encodedby", "tracknumber", "totaltracks", "discnumber", "totaldiscs", "length", ) def album_remove_unwanted_tags(tagger, metadata, release): for m in metadata: if m not in wanted_tags: metadata.deleted_tags.add(m) def track_remove_unwanted_tags(tagger, metadata, track, release): for m in metadata: if m not in wanted_tags: metadata.deleted_tags.add(m) register_album_metadata_processor(album_remove_unwanted_tags) register_track_metadata_processor(track_remove_unwanted_tags)