Can Picard read existing file tags and use those for scripting?

I now this has been discussed before, but I can’t find the earlier posts regarding this.
(if a mod can, feel free to merge this one into an older thread on the same subject)

I would like to make a script check for the existence and/or value of an existing tag in the imported file(s), so that it can perform certain further scripting actions based on that.

This was never possible, but I was wondering if perhaps something has changed, and this now can be done?

Something like this?

or

or

1 Like

Thanks InvisibleMan78

I just did a quick check using $if(%tag%,…) using a ‘known’ tag (not a custom one) and that seems to fail, it also assuming the tag is there if it’s not in the file but it is offered by MusicBrainz.
I’ll do some more and better testing perhaps later today.

edit
Hm, this might work:
$unset(tagname)
$if(tagname,…)

Maybe we can help you better if you give us a real example with real tags of what you have already tried?

1 Like

You can access the tags from the file as well. But you cannot explicitly access a file’s tags only, if the tag is also provided by the track metadata then this will be visible only. So you cannot for example compare the value from the track with the value of the same tag in the file.

Regarding:

$unset(tagname)
$if(%tagname%,…)

That $if will never do anything, as the tag got cleared by the $unset.

@outsidecontext: Is this assumption correct?

As long as files are loaded only to the left (unclustered) side of Picard, there are no tags fetched from the MB online source. The tags read from the files can be processed by scripts.

As soon as the files on the left side will be processed by “Lookup” or “Scan” tags from the MB online source will be fetched (if they exist). From this point on you can no more distinguish between - for example - then content of the tag ARTIST from the file and the content of ARTIST from the online source.

Yes, that’s correct.

That also means you could for example run a script on the unmatched file on the left that checks for certain tags and sets variables based on the result. Something like:

$if(%sometag%,$set(_has_sometag,1))

Running this script on the unmatched files needs to be done manually via context menu. But afterwards this _has_sometag variable would be set on the file if sometag has a value.

Then in a regular tagger script that runs automatically on loaded tags one could check for this variable:

$if(%_has_sometag%,...)
2 Likes

It’s not cleared in the sense of deleted.
The tag will still be and remain present in the file

I was hoping that the $if statement would be able to ‘know’ that.

Just a little reminder:
Don’t forget to delete this _has_sometag tag in your files afterwards if you don’t need it further.

So if I understand correctly, for regular tags (tags known by Picard) present in files that are being matched to the right panel, Picard can still not read them and perform specific scripting actions based on them.

But it can be done for custom tags (tags not known by Picard).

Is this a correct assumption/conclusion?

If you do $unset(var) then var gets cleared. It is like it was never set before. Hence %var% is empty, that’s the purpose of $unset.

That it does not get deleted is just because Picard writes all the new tags to the files and by default keeps other tags untouched. If you enable “clear existing tags” the unset tag would also get deleted.

That’s not really needed as variable names starting with an underscore are just considered variables are never written as tags to the file. That’s also why all the predefined variables work.

1 Like

No. Any tag from the file also gets made available in scripting. But scripting for matched files runs on the track metadata and hence track metadata overwrites the data from the file.

As an example if your file has data for barcode set, but the release data loaded for the track does not have any barcode then the scripting will still show the data from the file if you access %barcode%. But it the track’s release provides a barcode this will be used instead of the data from the file.

Is that the crucial difference?

Essentially yes. With the small addition that plugins also can manipulate the track metadata and that happens before scripts are applied. So it’s essentially the data from MB (based on your Picard settings), but might be some additional changes due to plugins (e.g. someone uses the last.fm genre plugin, then %genre% might be set with data from there).

A practical example:

Suppose you have a file that contains several genres in the genre tag.
And you have set: $unset(genre) in Picard because you don’t want to get them overwritten automatically.

Now you want to add a script that checks if the existing genre tag contains ‘rock’, and have it perform some action depending on that.

Can this be done?

Currently not directly in a single script. But you could do the workaround I outlined above of first running a script manually on the unmatched files in the left pane. If you have a script like:

$if($inmulti(%genre%,rock),$set(_is_rock,1))

you could run this manually (via context menu → run script) on the files on the left (you might need to drag the files to the left first). Ideally set this script to be deactivated so it does not run automatically.

Then in your regular tagger script you could check for $if(%_is_rock%,...) and act on that.

2 Likes

I created [PICARD-2767] Make a file's origninal metadata available in tagger script - MetaBrainz JIRA to track having the ability to access a file’s original metadata from within the scripting. Unfortunately the details are a bit tricky here. I once tried to add this, but the simple approach led to issues with the $matchedtracks and $is_complete functions