Beispiel #1
0
                genre = unicode(
                            re.split('<|>', trackinfo[3])[2].title(), 'utf8'
                        )
            else:
                genre = False
            # Get date
            if trackinfo[6] and not trackinfo[6] == "-":
                date = unicode(re.split('<|>', trackinfo[6])[2], 'utf8')
            else:
                date = False
            # Get singers
            if trackinfo[5] == "-" or not trackinfo[5]:
                vocal = False
            elif trackinfo[5]:
                # Catch and strip <a> tags
                vocal = unicode(re.sub("<[^>]*>", "", trackinfo[5]), 'utf8')
            else:
                vocal = False

            # expected format in HTML: <a href="/002390...">...
            tint = trackinfo[8].split("\"")[1][1:]
            albuminfo[tint] = {
                                'genre': genre,
                                'date': date,
                                'vocal': vocal
                              }

        return albuminfo

register_track_metadata_processor(TangoInfoTagger().add_tangoinfo_data)
            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)
    if len(studio_artists) == 1:
        return populate_comment_join(studio_artists.items()[0][0][1])
    if len(studio_artists) == 0:
        if len(all_artists) == 1 :
            return populate_comment_join(all_artists.items()[0][0][1])
        return ''
    multi_recordings = []
    for artists, count in studio_artists.iteritems():
        if count > 1:
            multi_recordings.append(artists)
    if len(multi_recordings) == 1:
        return populate_comment_join(multi_recordings[0][1])
    return populate_comment_join(
        [populate_comment_join(key[1]) for key in studio_artists.keys()],
        final = ' and by ',
        joiner = ', by ',
    )
    return ''

try:
    from picard.plugin import PluginPriority
    register_track_metadata_processor(populate_comment, priority=PluginPriority.LOW)
except ImportError:
    log.warning(
        "The %r plugin is designed to run at a specific priority,"
        "however this version of Picard does not include the priority capability"
        "and so the plugins may not run in the correct sequence and"
        "therefore may not work as you expect.",
        PLUGIN_NAME
    )
    register_track_metadata_processor(populate_comment)
    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)
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)
Beispiel #6
0
            PLUGIN_NAME,
            subkey,
        )
        prefixes = []
        words = instruments[0].split()
        for word in words[:]:
            if not word in ['guest', 'solo', 'additional', 'minor']:
                break
            prefixes.append(word)
            words.remove(word)
        instruments[0] = " ".join(words)
        prefix = " ".join(prefixes) + " " if prefixes else ""
        for instrument in instruments:
            newkey = '%s:%s%s' % (mainkey, prefix, instrument)
            for value in values:
                metadata.add_unique(newkey, value)
        del metadata[key]


try:
    from picard.plugin import PluginPriority

    register_track_metadata_processor(standardise_performers,
                                      priority=PluginPriority.HIGH)
except ImportError:
    log.warning(
        "Running %r plugin on this Picard version may not work as you expect. "
        "Any other plugins that run before it will get the old performers "
        "rather than the standardized performers.", PLUGIN_NAME)
    register_track_metadata_processor(standardise_performers)
Beispiel #7
0
   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)
Beispiel #8
0
            return
        data = json.loads(response)
        if "tonal" in data:
            if "key_key" in data["tonal"]:
                key = data["tonal"]["key_key"]
                if "key_scale" in data["tonal"]:
                    scale = data["tonal"]["key_scale"]
                    if scale == "minor":
                        key += "m"
                track_metadata["key"] = key
                log.debug("%s: Track '%s' is in key %s", PLUGIN_NAME,
                          track_metadata["title"], key)
        if "rhythm" in data:
            if "bpm" in data["rhythm"]:
                bpm = int(data["rhythm"]["bpm"] + 0.5)
                track_metadata["bpm"] = bpm
                log.debug("%s: Track '%s' has %s bpm", PLUGIN_NAME,
                          track_metadata["title"], bpm)
        self.album_remove_request(album)

    def album_add_request(self, album):
        album._requests += 1

    def album_remove_request(self, album):
        album._requests -= 1
        if album._requests == 0:
            album._finalize_loading(None)


register_track_metadata_processor(AcousticBrainz_Key().get_data)
Beispiel #9
0
        self.xmlws=album.tagger.xmlws
        self.log=album.log
        tagger=album
        
        item_id = dict.get(metadata,'musicbrainz_releasegroupid')[0]		
        log.debug('WIKIDATA: looking up release metadata for %s ' % item_id)
        self.process_request(metadata,tagger,item_id,type='release-group')
        
        for artist in dict.get(metadata,'musicbrainz_albumartistid'):
            item_id=artist
            log.info('WIKIDATA: processing release artist %s' % item_id)
            self.process_request(metadata,tagger,item_id,type='artist')
        
        for artist in dict.get(metadata,'musicbrainz_artistid'):
            item_id=artist
            log.info('WIKIDATA: processing track artist %s' % item_id)
            self.process_request(metadata,tagger,item_id,type='artist')
        
        if 'musicbrainz_workid' in metadata:
            for workid in dict.get(metadata,'musicbrainz_workid'):
                item_id=workid
                log.info('WIKIDATA: processing track artist %s' % item_id)
                self.process_request(metadata,tagger,item_id,type='work')

        

wikidata=wikidata()
#register_album_metadata_processor(wikidata.process_release)
register_track_metadata_processor(wikidata.process_track)

Beispiel #10
0
                    fm['artistarea'] = urls
            self.album_remove_request(album)

    # noinspection PyMethodMayBeStatic
    def album_add_request(self, album):
        # noinspection PyProtectedMember
        album._requests += 1

    # noinspection PyMethodMayBeStatic,PyProtectedMember
    def album_remove_request(self, album):
        album._requests -= 1
        album._finalize_loading(None)

    # noinspection PyMethodMayBeStatic
    def artist_process_metadata(self, artist_id, response):
        if 'metadata' in response.children:
            if 'artist' in response.metadata[0].children:
                if 'area' in response.metadata[0].artist[0].children:
                    if 'name' in response.metadata[0].artist[0].area[
                            0].children:
                        return response.metadata[0].artist[0].area[0].name[
                            0].text
            else:
                log.error(
                    "%s: %r: MusicBrainz artist xml result not in correct format - %s",
                    PLUGIN_NAME, artist_id, response)
        return None


register_track_metadata_processor(AlbumArtistArea().add_artist_area)
Beispiel #11
0
    except:
        return False


dgenre = get_data_from_csv()


def get_discnumber(metadata):
    retval = 1
    if (is_integer(metadata["discnumber"])):
        if metadata["discnumber"] > 0:
            retval = metadata["discnumber"]
    else:
        matches = _discnumber_re.search(metadata["album"])
        if matches:
            retval = matches.group(1)
    return retval


def set_tangoinfo_genre(tagger, metadata, release, track):
    mydiscnumber = get_discnumber(metadata)

    if (len(metadata["barcode"]) > 0):
        myidk = str(int(metadata["barcode"])) + "#" + str(
            mydiscnumber) + "#" + metadata["tracknumber"]
        if myidk in dgenre:
            metadata["genre"] = dgenre[myidk]


register_track_metadata_processor(set_tangoinfo_genre)
             self.txxx_add(metadata, 'MISC', name, name, '; ')

    def txxx_add(self, metadata, tagname, label, name, joiner):
        name = name.lower()
        if not name in metadata:
            return
        tag = dict.get(metadata, name)
        value = ', '.join(tag)
        if label:
            label += ': '
        if tagname in metadata:
            metadata[tagname] += joiner + label + value
        else:
            metadata[tagname] = label + value

try:
    from picard.plugin import PluginPriority

    register_track_metadata_processor(
        MusicBeeCompatibility().musicbee_compatibility,
        priority=PluginPriority.LOW
        )

except ImportError:
    log.warning(
        "Running %r plugin on this Picard version may not work as you expect. "
        "This plugin should be run after other plugins and if it runs before "
        "some changes to metadata may be incorrect.", PLUGIN_NAME
    )
    register_track_metadata_processor(MusicBeeCompatibility().musicbee_compatibility)
                    )
                    if _debug_level > 2:
                        print("Abbreviated (%s, %s) to (%s, %s)." % (surname, forename, surname, inits))
            else:  # while loop ended without a break i.e. no errors
                if unsorts[i] != new_unsort:
                    log.error(
                        _("%s: Track %s: Logic error - mangled %s from '%s' to '%s'."),
                        PLUGIN_NAME,
                        metadata['tracknumber'],
                        unsortTag,
                        unsorts[i],
                        new_unsort,
                    )
                    if _debug_level > 0:
                        print()
                        print("Error: Unsorted text for %s has changed from '%s' to '%s'!" % (unsortTag, unsorts[i], new_unsort))
                        print()
                _abbreviate_cache[sorts[i]] = new_sort
                if _debug_level > 1:
                    print("  Abbreviated and cached (%s) as (%s)." % (sorts[i], new_sort))
                if sorts[i] != new_sort:
                    log.debug(_("%s: Abbreviated tag '%s' to '%s'."),
                              PLUGIN_NAME,
                              sorts[i],
                              new_sort,
                              )
                    sorts[i] = new_sort
        metadata[sortTagNew] = sorts

register_track_metadata_processor(abbreviate_artistsort)
Beispiel #14
0
    def album_remove_request(self, album):
        album._requests -= 1
        if album._requests == 0:
            album._finalize_loading(None)

    def artist_process_metadata(self, artistId, response):
        if 'metadata' in response.children:
            if 'artist' in response.metadata[0].children:
                if 'relation_list' in response.metadata[0].artist[0].children:
                    if 'relation' in response.metadata[0].artist[
                            0].relation_list[0].children:
                        return self.artist_process_relations(
                            response.metadata[0].artist[0].relation_list[0].
                            relation)
            else:
                log.error(
                    "%s: %r: MusicBrainz artist xml result not in correct format - %s",
                    PLUGIN_NAME, artistId, response)
        return None

    def artist_process_relations(self, relations):
        urls = []
        for relation in relations:
            if relation.type == 'official homepage' \
                and 'target' in relation.children:
                urls.append(relation.target[0].text)
        return urls


register_track_metadata_processor(AlbumArtistWebsite().add_artist_website)
Beispiel #15
0
PLUGIN_NAME = 'Classic Disc Numbers'
PLUGIN_AUTHOR = 'Lukas Lalinsky'
PLUGIN_DESCRIPTION = '''Moves disc numbers and subtitles from the separate tags to album titles.'''
PLUGIN_VERSION = "0.1"
PLUGIN_API_VERSIONS = ["0.15"]

from picard.metadata import register_track_metadata_processor
import re


def add_discnumbers(tagger, metadata, release, track):
    if int(metadata["totaldiscs"] or "0") > 1:
        if "discsubtitle" in metadata:
            metadata["album"] = "%s (disc %s: %s)" % (metadata["album"],
                                                      metadata["discnumber"],
                                                      metadata["discsubtitle"])
        else:
            metadata["album"] = "%s (disc %s)" % (metadata["album"],
                                                  metadata["discnumber"])


register_track_metadata_processor(add_discnumbers)
Beispiel #16
0
PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html"

from picard.metadata import register_track_metadata_processor

# Define tags where sort order is important
_sort_multivalue_tags_exclude = (
    'artists', '~artists_sort', 'musicbrainz_artistid',
    'albumartists', '~albumartists_sort', 'musicbrainz_albumartistid',
    'work', 'musicbrainz_workid',
    'label', 'catalognumber',
    'country', 'date',
    'releasetype',
)
# Possible future enhancement:
# Sort linked tags e.g. work so that the sequence in related tags e.g. workid retains the relationship between
# e.g. work and workid.


def sort_multivalue_tags(tagger, metadata, track, release):

    for tag in metadata.keys():
        if tag in _sort_multivalue_tags_exclude:
            continue
        data = metadata.getall(tag)
        if len(data) > 1:
            sorted_data = sorted(data)
            if data != sorted_data:
                metadata.set(tag, sorted_data)

register_track_metadata_processor(sort_multivalue_tags)
Beispiel #17
0
        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)
            log.error("%s: Network error retrieving acousticBrainz data for recordingId %s",
                PLUGIN_NAME, track_metadata['musicbrainz_recordingid'])
            self.album_remove_request(album)
            return
        data = json.loads(response)
        if "tonal" in data:
            if "key_key" in data["tonal"]:
                key = data["tonal"]["key_key"]
                if "key_scale" in data["tonal"]:
                    scale = data["tonal"]["key_scale"]
                    if scale == "minor":
                        key += "m"
                track_metadata["key"] = key
                log.debug("%s: Track '%s' is in key %s", PLUGIN_NAME, track_metadata["title"], key)
        if "rhythm" in data:
            if "bpm" in data["rhythm"]:
                bpm = int(data["rhythm"]["bpm"] + 0.5)
                track_metadata["bpm"] = bpm
                log.debug("%s: Track '%s' has %s bpm", PLUGIN_NAME, track_metadata["title"], bpm)
        self.album_remove_request(album)

    def album_add_request(self, album):
        album._requests += 1

    def album_remove_request(self, album):
        album._requests -= 1
        if album._requests == 0:
            album._finalize_loading(None)

register_track_metadata_processor(AcousticBrainz_Key().get_data)
Beispiel #19
0
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)
    def album_add_request(self, album):
        album._requests += 1

    def album_remove_request(self, album):
        album._requests -= 1
        if album._requests == 0:
            album._finalize_loading(None)


    def artist_process_metadata(self, artistId, response):
        if 'metadata' in response.children:
            if 'artist' in response.metadata[0].children:
                if 'relation_list' in response.metadata[0].artist[0].children:
                    if 'relation' in response.metadata[0].artist[0].relation_list[0].children:
                        return self.artist_process_relations(response.metadata[0].artist[0].relation_list[0].relation)
            else:
                log.error("%s: %r: MusicBrainz artist xml result not in correct format - %s",
                          PLUGIN_NAME, artistId, response)
        return None

    def artist_process_relations(self, relations):
        urls = []
        for relation in relations:
            if relation.type == 'official homepage' \
                and 'target' in relation.children:
                urls.append(relation.target[0].text)
        return urls


register_track_metadata_processor(AlbumArtistWebsite().add_artist_website)
Beispiel #21
0
            # 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)
Beispiel #22
0
PLUGIN_NAME = 'Feat. Artists'
PLUGIN_AUTHOR = 'Lukas Lalinsky'
PLUGIN_DESCRIPTION = 'Removes feat. artists from track titles.'
PLUGIN_VERSION = "0.1"
PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15"]

from picard.metadata import register_track_metadata_processor
import re


def remove_featartists(tagger, metadata, release, track):
    metadata["title"] = re.sub(r"\s+\(feat. [^)]*\)", "", metadata["title"])


register_track_metadata_processor(remove_featartists)
Beispiel #23
0
            if dtobjmax < olddate:
                olddate = dtobjmax
                olddatestr = release.date[0].text

            if dtobjmin > newdate:
                newdate = dtobjmin
                newdatestr = release.date[0].text

        try:
            self.metadata['firstrecorded'] = olddatestr
            log.debug("Oldest Date = %s", olddatestr)
        except:
            log.info("Unable to find oldest date for Recording ID: %s",
                     self.track_node.recording[0].id)
        finally:
            self.album._finalize_loading(None)

    def mydolookup(self):
        self.album._requests += 1
        self.album.tagger.xmlws._get_by_id('recording',
                                           self.track_node.recording[0].id,
                                           self.myhandler, ['releases'])


def first_year_track(album, metadata, track_node, release_node):
    mylookup = MyLookup(album, metadata, track_node, release_node)
    mylookup.mydolookup()


register_track_metadata_processor(first_year_track)
PLUGIN_NAME = 'Prefer Multiple Artists Fields'
PLUGIN_AUTHOR = 'Alex Palmer'
PLUGIN_DESCRIPTION = '''Replaces artist and albumartist tags with the contents of the artists and albumartists tags.'''
PLUGIN_VERSION = "1.1"
PLUGIN_API_VERSIONS = ["0.16", "1.0", "2.0"]

MAPPINGS = [{
    'from': 'artists',
    'to': 'artist'
}, {
    'from': 'albumartists',
    'to': 'albumartist'
}]

from picard.metadata import register_track_metadata_processor


def prefer_multiple_artist_fields(tagger, metadata, release, track):
    for mapping in MAPPINGS:
        from_ = mapping['from']
        to = mapping['to']
        if from_ in metadata:
            metadata[to] = metadata[from_]
            del metadata[from_]


register_track_metadata_processor(prefer_multiple_artist_fields)
Beispiel #25
0
PLUGIN_NAME = 'Format Ft.'
PLUGIN_AUTHOR = 'Keno März'
PLUGIN_DESCRIPTION = 'Formats all featuring variants to "Ft." in title. Plays well with StandardiseFeat and FeatArtistInTitles.'
PLUGIN_VERSION = "1.0"
PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16", "2.0"]

from picard.metadata import register_album_metadata_processor, register_track_metadata_processor
from picard.plugin import PluginPriority
from picard import log

def format_feat(tagger, metadata, track, release):
	aliases = ['feat. ', 'Feat. ', 'featuring ', 'Featuring ', ' feat ', ' Feat ']
	for alias in aliases:
		title = metadata["title"]
		if alias in title:
			i = title.find(alias)
			feature = title[i + len (alias):].strip(' \t\n\r()')
			metadata["title"] = title[:i].rstrip(' \t\n\r()') + ' (Ft. '+ feature + ')'

register_track_metadata_processor(format_feat, priority=PluginPriority.LOW)
            continue
        mainkey, subkey = key.split(':', 1)
        if not subkey:
            continue
        instruments = standardise_performers_split(subkey)
        if len(instruments) == 1:
            continue
        log.debug("%s: Splitting Performer [%s] into separate performers",
            PLUGIN_NAME,
            subkey,
            )
        for instrument in instruments:
            newkey = '%s:%s' % (mainkey, instrument)
            for value in values:
                metadata.add_unique(newkey, value)
        del metadata[key]


try:
    from picard.plugin import PluginPriority

    register_track_metadata_processor(standardise_performers,
                                      priority=PluginPriority.HIGH)
except ImportError:
    log.warning(
        "Running %r plugin on this Picard version may not work as you expect. "
        "Any other plugins that run before it will get the old performers "
        "rather than the standardized performers.", PLUGIN_NAME
    )
    register_track_metadata_processor(standardise_performers)
Beispiel #27
0
  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]

  metadata['totaldiscs'] = str(len(all_sides))
  metadata['discnumber'] = str(all_sides.index(side) + 1)

  metadata['totaltracks'] = \
    str(side_last_tracknumber - side_first_tracknumber + 1)
  metadata['tracknumber'] = \
    str(int(metadata['tracknumber']) - side_first_tracknumber + 1)

register_track_metadata_processor(reorder_sides)
                        _("%s: Track %s: Logic error - mangled %s from '%s' to '%s'."
                          ),
                        PLUGIN_NAME,
                        metadata['tracknumber'],
                        unsortTag,
                        unsorts[i],
                        new_unsort,
                    )
                    if _debug_level > 0:
                        print()
                        print(
                            "Error: Unsorted text for %s has changed from '%s' to '%s'!"
                            % (unsortTag, unsorts[i], new_unsort))
                        print()
                _abbreviate_cache[sorts[i]] = new_sort
                if _debug_level > 1:
                    print("  Abbreviated and cached (%s) as (%s)." %
                          (sorts[i], new_sort))
                if sorts[i] != new_sort:
                    log.debug(
                        _("%s: Abbreviated tag '%s' to '%s'."),
                        PLUGIN_NAME,
                        sorts[i],
                        new_sort,
                    )
                    sorts[i] = new_sort
        metadata[sortTagNew] = sorts


register_track_metadata_processor(abbreviate_artistsort)
        self.label.setText('Apiseeds API key')
        self.box.addWidget(self.label)

        self.description = QtWidgets.QLabel(self)
        self.description.setText(
            'Happi.dev Music provides millions of lyrics from artist all around the world. '
            'Lyrics provided are for educational purposes and personal use only. Commercial use is not allowed. '
            'In order to use Happi.dev Music you need to get a free API key <a href="https://happi.dev">here</a>.'
        )
        self.description.setOpenExternalLinks(True)
        self.box.addWidget(self.description)

        self.input = QtWidgets.QLineEdit(self)
        self.box.addWidget(self.input)

        self.spacer = QtWidgets.QSpacerItem(0, 0,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.box.addItem(self.spacer)

    def load(self):
        self.input.setText(config.setting['happidev_apikey'])

    def save(self):
        config.setting['happidev_apikey'] = self.input.text()


register_track_metadata_processor(
    HappidevLyricsMetadataProcessor().process_metadata)
register_options_page(HappidevLyricsOptionsPage)
Beispiel #30
0
        }
        instruments_example = self.build_example(instruments_credits, word_dict, settings)
        self.ui.example_instruments.setText(instruments_example)

        vocals_credits = {
            "additional solo lead vocals": ["Robert Plant"],
            "additional solo guest lead vocals": ["Sandy Denny"],
        }
        vocals_example = self.build_example(vocals_credits, word_dict, settings)
        self.ui.example_vocals.setText(vocals_example)

    @staticmethod
    def build_example(credits, word_dict, settings):
        prefix = "performer:"
        metadata = Metadata()
        for key, values in credits.items():
            rewrite_tag(prefix + key, values, metadata, word_dict, settings)

        examples = []
        for key, values in metadata.rawitems():
            credit = "%s: %s" % (key, ", ".join(values))
            if credit.startswith(prefix):
                credit = credit[len(prefix):]
            examples.append(credit)
        return "\n".join(examples)


# Register the plugin to run at a HIGH priority.
register_track_metadata_processor(format_performer_tags, priority=PluginPriority.HIGH)
register_options_page(FormatPerformerTagsOptionsPage)
Beispiel #31
0
        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)
Beispiel #32
0
            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)
Beispiel #33
0
        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]

    metadata['totaldiscs'] = string_(len(all_sides))
    metadata['discnumber'] = string_(all_sides.index(side) + 1)

    metadata['totaltracks'] = \
      string_(side_last_tracknumber - side_first_tracknumber + 1)
    metadata['tracknumber'] = \
      string_(int(metadata['tracknumber']) - side_first_tracknumber + 1)


register_track_metadata_processor(reorder_sides)
Beispiel #34
0
class EchoNestOptionsPage(OptionsPage):
    NAME = "echonest"
    TITLE = "echonest"
    PARENT = "plugins"

    options = [
        BoolOption("setting", "echonest_upload", False),
        BoolOption("setting", "echonest_artist_title_lookup", True),
        FloatOption("setting", "echonest_duration_diff", 5.0),
    ]

    def __init__(self, parent=None):
        super(EchoNestOptionsPage, self).__init__(parent)
        self.ui = Ui_EchoNestOptionsPage()
        self.ui.setupUi(self)

    def load(self):
        #self.ui.echonest_upload.setChecked(self.config.setting["echonest_upload"])
        self.ui.echonest_artist_title_lookup.setChecked(self.config.setting["echonest_artist_title_lookup"])
        #self.ui.echonest_duration_diff.setChecked(self.config.setting["echonest_duration_diff"])

    def save(self):
        #self.config.setting["echonest_upload"] = self.ui.echonest_upload.isChecked()
        self.config.setting["echonest_artist_title_lookup"] = self.ui.echonest_artist_title_lookup.isChecked()
        #self.config.setting["echonest_duration_diff"] = self.ui.echonest_duration_diff.value()

register_track_metadata_processor(process_track)
register_options_page(EchoNestOptionsPage)

# eof
Beispiel #35
0
    like 'guest performer'.
  """
    instrument_prefixes = {
        'additional',
        'guest',
        'solo',
    }
    remaining = instrument
    while remaining:
        prefix, sep, remaining = remaining.partition(' ')
        if prefix not in instrument_prefixes:
            return ''.join((prefix, sep, remaining))
    return None


def add_instruments(tagger, metadata_, *args):
    key_prefix = 'performer:'
    instruments = set()
    for key in metadata_.keys():
        if not key.startswith(key_prefix):
            continue
        for instrument in _iterate_instruments(key[len(key_prefix):]):
            instrument = _strip_instrument_prefixes(instrument)
            if instrument:
                instruments.add(instrument)
    metadata_['~instruments'] = list(instruments)


metadata.register_track_metadata_processor(add_instruments,
                                           priority=plugin.PluginPriority.HIGH)
_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)
Beispiel #37
0
            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)
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)
# coding=utf-8

PLUGIN_NAME = 'zh_CN convert'
PLUGIN_AUTHOR = 'alswl'
PLUGIN_DESCRIPTION = 'Convert zh_TW'
PLUGIN_VERSION = '0.1'
PLUGIN_API_VERSIONS = ['0.9.0', '0.10', '0.15', '0.16']

import re

from picard.metadata import register_track_metadata_processor

from langconv import Converter

#import logging
#logger = logging.getLogger(__name__)
#log_handler = logging.FileHandler('/tmp/xxx.log')
#logger.addHandler(log_handler)

TO_LOCAL = 'zh-hans'  # 'zh-hans' = simple, 'zh-hant' = traditional


def convert_track(tagger, metadata, release, track):
    for key in metadata:
        if not isinstance('', (str, unicode)):
            continue
        metadata[key] = Converter(TO_LOCAL).convert(metadata[key])


register_track_metadata_processor(convert_track)
PLUGIN_NAME = 'zh_CN convert'
PLUGIN_AUTHOR = 'alswl'
PLUGIN_DESCRIPTION = 'Convert zh_TW'
PLUGIN_VERSION = '0.1'
PLUGIN_API_VERSIONS = ['0.9.0', '0.10', '0.15', '0.16']

import re

from picard.metadata import register_track_metadata_processor

from langconv import Converter


#import logging
#logger = logging.getLogger(__name__)
#log_handler = logging.FileHandler('/tmp/xxx.log')
#logger.addHandler(log_handler)

TO_LOCAL = 'zh-hans'  # 'zh-hans' = simple, 'zh-hant' = traditional


def convert_track(tagger, metadata, release, track):
    for key in metadata:
        if not isinstance('', (str, unicode)):
            continue
        metadata[key] = Converter(TO_LOCAL).convert(metadata[key])


register_track_metadata_processor(convert_track)
								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:
		if tracks[ int(metadata['discnumber']) ][ int(metadata['tracknumber']) ]["mbid"] == metadata["musicbrainz_trackid"]:
			metadata['title'] = tracks[ int(metadata['discnumber']) ][ int(metadata['tracknumber']) ]["title"]
		else:
			tagger.log.error("MBID for %s (%s) does not match MBID for %s (%s).", tracks[ int(metadata['discnumber']) ][ int(metadata['tracknumber']) ]["title"], tracks[ int(metadata['discnumber']) ][ int(metadata['tracknumber']) ]["mbid"], metadata['title'], metadata["musicbrainz_trackid"])
	except: pass

register_track_metadata_processor(set_transliterations)

    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)
Beispiel #43
0
PLUGIN_NAME = 'Classic Disc Numbers'
PLUGIN_AUTHOR = 'Lukas Lalinsky'
PLUGIN_DESCRIPTION = '''Moves disc numbers and subtitles from the separate tags to album titles.'''
PLUGIN_VERSION = "0.1"
PLUGIN_API_VERSIONS = ["0.15"]

from picard.metadata import register_track_metadata_processor
import re

def add_discnumbers(tagger, metadata, release, track):
    if int(metadata["totaldiscs"] or "0") > 1:
        if "discsubtitle" in metadata:
            metadata["album"] = "%s (disc %s: %s)" % (
                metadata["album"], metadata["discnumber"],
                metadata["discsubtitle"])
        else:
            metadata["album"] = "%s (disc %s)" % (
                metadata["album"], metadata["discnumber"])

register_track_metadata_processor(add_discnumbers)

    def process_track(self, album, metadata, trackXmlNode, releaseXmlNode):
        self.xmlws = album.tagger.xmlws
        self.log = album.log
        tagger = album

        item_id = dict.get(metadata, 'musicbrainz_releasegroupid')[0]
        log.debug('WIKIDATA: looking up release metadata for %s ' % item_id)
        self.process_request(metadata, tagger, item_id, type='release-group')

        for artist in dict.get(metadata, 'musicbrainz_albumartistid'):
            item_id = artist
            log.info('WIKIDATA: processing release artist %s' % item_id)
            self.process_request(metadata, tagger, item_id, type='artist')

        for artist in dict.get(metadata, 'musicbrainz_artistid'):
            item_id = artist
            log.info('WIKIDATA: processing track artist %s' % item_id)
            self.process_request(metadata, tagger, item_id, type='artist')

        if 'musicbrainz_workid' in metadata:
            for workid in dict.get(metadata, 'musicbrainz_workid'):
                item_id = workid
                log.info('WIKIDATA: processing track artist %s' % item_id)
                self.process_request(metadata, tagger, item_id, type='work')


wikidata = wikidata()
#register_album_metadata_processor(wikidata.process_release)
register_track_metadata_processor(wikidata.process_track)
        self.label.setText('Apiseeds API key')
        self.box.addWidget(self.label)

        self.description = QtWidgets.QLabel(self)
        self.description.setText('Apiseeds Lyrics provides millions of lyrics from artist all around the world. '
                                 'Lyrics provided are for educational purposes and personal use only. Commercial use is not allowed. '
                                 'In order to use Apiseeds Lyrics you need to get a free API key <a href="https://apiseeds.com">here</a>.')
        self.description.setOpenExternalLinks(True)
        self.box.addWidget(self.description)

        self.input = QtWidgets.QLineEdit(self)
        self.box.addWidget(self.input)

        self.contribute = QtWidgets.QLabel(self)
        self.contribute.setText('Want to contribute? Check out the <a href="https://github.com/avalloneandrea/apiseeds-lyrics">project page</a>!')
        self.contribute.setOpenExternalLinks(True)
        self.box.addWidget(self.contribute)

        self.spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.box.addItem(self.spacer)

    def load(self):
        self.input.setText(config.setting['apiseeds_apikey'])

    def save(self):
        config.setting['apiseeds_apikey'] = self.input.text()


register_track_metadata_processor(ApiseedsLyricsMetadataProcessor().process_metadata)
register_options_page(ApiseedsLyricsOptionsPage)
Beispiel #46
0
    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)
PLUGIN_NAME = 'Move metadata to version tag'
PLUGIN_AUTHOR = 'Jacob Rask'
PLUGIN_DESCRIPTION = 'Moves song metadata such as "demo", "live" from title and titlesort to version tag.'
PLUGIN_VERSION = "0.1.4"
PLUGIN_API_VERSIONS = ["0.12", "0.15"]

from picard.metadata import register_track_metadata_processor
import re

_p_re = re.compile(r"\(.*?\)")
_v_re = re.compile(r"((\s|-)?(acoustic|akustisk|album|bonus|clean|club|cut|C=64|dance|dirty|disco|encore|extended|inch|maxi|live|original|radio|redux|rehearsal|reprise|reworked|ringtone|[Ss]essions?|short|studio|take|variant|version|vocal)(\s|-)?|.*?(capp?ella)\s?|(\s|-)?(alternat|demo|dub|edit|ext|fail|instr|long|orchestr|record|remaster|remix|strument|[Tt]ape|varv).*?|.*?(complete|mix|inspel).*?)")

def add_title_version(tagger, metadata, release, track):
    if metadata["titlesort"]:
        title = metadata["titlesort"]
    else:
        title = metadata["title"]
    pmatch = _p_re.findall(title)
    if pmatch: # if there's a parenthesis, investigate
        pstr = pmatch[-1][1:-1] # get last match and strip paranthesis
        vmatch = _v_re.search(pstr)
        if vmatch:
            metadata["titlesort"] = re.sub("\(" + pstr + "\)", "", title).strip()
            metadata["title"] = re.sub("\(" + pstr + "\)", "", title).strip()
            metadata["version"] = pstr

register_track_metadata_processor(add_title_version)