Help developing Picard Plug-in

Tags: #<Tag:0x00007fe3d3b1ae90> #<Tag:0x00007fe3d3b1ab98> #<Tag:0x00007fe3d3b1a788>


My google-fu skills keep bring me to the old forums and I see no topics here regarding development. I am trying to write a plug-in that will delete all non-standard tags. My Python skills are weak - enough to be dangerous - but I am unsure if I am on the right path.

The following has been edited multiple times and I assume I have a Python error - which is why I cannot see my plug-in after install to enable - I have referred to the bundled plug-ins to see what I can learn. The following is the code so far;

PLUGIN_NAME = u'Cleanup Bad Tags'
PLUGIN_AUTHOR = u'Matthew A Snell'
PLUGIN_DESCRIPTION = '''Remove all non-standard tags. Keep standard tags inc musicbrainz_*, acouticid_*, musicip_* or _* '''
PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16"]

from picard.metadata import register_album_metadata_processor, register_track_metadata_processor

_KEEPTAGS = [album, albumartist, albumartistsort, albumsort, arranger,
             artist, artistsort, asin, barcode, bpm, catalognumber,
             comment, compilation, composer, composersort, conductor,
             copyright, date, discnumber, discsubtitle, djmixer,
             encodedby, encodersettings, engineer, gapless, genre,
             grouping, isrc, label, language, license, lyricist,
             lyrics, media, mixer, mood, originaldate, originalyear,
             performer, podcast, podcasturl, producer, releasecountry,
             releasestatus, releasetype, remixer, script, show,
             showsort, subtitle, title, titlesort, totaldiscs,
             totaltracks, tracknumber, website, work, writer]

def strip_bad_tags(tagger, metadata):

    for key, values in metadata.rawitems():

        mainkey, subkey = key.split(':', 1)

        if subkey:

        if (key not in _KEEPTAGS:
            if not key.startswith("musicbrainz_"):
                if not key.startswith("acouticid_"):
                    if not key.startswith("musicip_"):
                        if not key[0] == "~"):
                            del metadata[key]

def CleanupBadTagsAlbumProcessor(tagger, metadata, release):
    strip_bad_tags(tagger, metadata)

def CleanupBadTagsTrackProcessor(tagger, metadata, track, release):
    strip_bad_tags(tagger, metadata)


I have tried installing the plugin manually (in user plug-in directory) and through the Picard Install Plug-in interface.

I have checked the Initialization block for the plug-in multiple times and see no error. I have tried parsing metadata.keys() vs metadata.rawitems() plus other code changes to see if I can figure this out.

I assume it doesn’t show because I have bad Python code, incorrect initialization in the plug-in header or not using the registration call correctly. I have tried doing the _KEEPTAGS list with & without quotes - keep thinking the bad code is there.

I have successfully made a variation of plug-in which installs, is listed as a plug-in and works as expected.

Appreciate any input or guidance (or code improvements). Thanks.


Noob here in Python but I think your list of keys needs quotation marks around every item. I’ll see if I can figure out anything else.


Hi, Thanks for the reply - assume you are referring to _KEEPTAGS - yep, had already tried that - should have posted the copy with the list delimited correctly - I was just try ‘wild’ stuff to see what I could break or find that could make the error or issue more obvious - I just changed my code back to have the quotes - though no luck. Haven’t looked at it for a couple of weeks now, so maybe tonight I will have a look again, and maybe i will see what I have done wrong that I was oblivious to before.


Sorry, wanted to answer you earlier but didn’t find the time to look into it.

First, yes, you have a couple of syntax errors. You should be able to see the errors in Help -> View Error/Debug Log. You have some superflous braces in the if statements, and the values in _KEEPTAGS need to be in quotes. Also key.split(':', 1) will fail for tags that don’t contain a colon, in this case just use something like:

if ':' in key:

But I am actually not sure what you want to achieve with this script. With the tags defined in KEEP_TAGS, the exceptions for musicbrainz_, acoustid_ and musicip_ and all tags containing a colon there is actually not much left, if anything, that would be removed from an album loaded. See for a list of tags supported by Picard.

If your goal was to just have tags in your files that are supported by Picard, there is an easier option: Just enable Tags > Clear existing tags in the options :slight_smile:


outsidecontext; thanks for all the info - that should get me on the right path. The reason for the script is because in some cases I have the value in the file already (e.g. particularly around date fields), and doing a Clear Existing Tags will destroy those tags when they are not in the MusicBrainz DB (maybe I should do a feature request for an option to Clear Unsupported/Unknown tags only) - plus gives me an idea for a plug-in to report missing data from MB DB I can later confirm and submit an update for.
Another part of the issue I have is that due to past maintenance of my library, I have either created private tags that Picard makes unnecessary, and no longer supported by my streaming solutions. There are also artifacts left over from converting FLAC files to MP3 via ffmpeg (e.g. MEDIA, CD tags) - didn’t really want to pull CD’s from storage and re-rip when I have good quality FLACs on-hand - and re-ripping analog media would be just too much hassle.
Once i have confirmed as-is functionality works, I will look at doing some validation before killing those non-standard fields, e.g. if MEDIA exists, but media doesn’t, then move the value over before destruction - so I will have to have a Dictionary of some sort to achieve this.
Again thanks - I found little documentation on plug-in development so tips like the log are great.


Have you tried “Preserve these tags from being deleted” options in picard?


Rovastar; The option is “Preserve these tags from being cleared or overwritten with MusicBrainz data” - I want the MusicBrainz data, I just don’t want it to delete good tags not in the Release data from MusicBrainz. Personally think these are two very different logical scenarios, and should never been combined as such.