Looking for a more concise way to set a flag based on catalog number prefix

Tags: #<Tag:0x00007fe84cd93f50> #<Tag:0x00007fe84cd93e88>

I’m trying to use catalog number prefixes to automatically create some new tags. e.g.,

$set(_enclosureCatno,0)
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,ANZX),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,ANZB),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,AVBA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,AVXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,BCXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,DMPXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,EYXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,GNBA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,GNXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,KABA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,KAXA),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,KIZX),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,MFXN),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,PCBG),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,PCXG),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,SSX),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,TBR),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,VTCY),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,ZMBZ),1,0)))
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,ZMXZ),1,0)))

$if($eq($get(_enclosureCatno),1),$set(format,Enclosure))
$unset(_enclosureCatno)

This works, but is there a way to reduce the boilerplate? I tried using the $or function, but it relies on the return values being empty rather than true/false, and it also detects the line breaks as non-empty data, preventing me from placing each case on a separate line.

I would try to solve this with the loop function:
https://picard-docs.musicbrainz.org/en/functions/func_foreach.html

i.e. (untested code)

$foreach(ANZX;ANZB;...,
$if($startswith(%catalognumber%,%_loop_value%),...,...)
)
2 Likes

Is there a solution where I can store each case on a separate line? This is more important to me than reducing the amount of horizontal space the code takes up.

Yes, this seems to work in my short test (note the space between the semicolons and linebreaks):

$foreach(123; 
456; 
789,
$copymerge(test,_loop_value))
$join(%test%,+)

as a file naming script yields 123+456+789 as expected.

Or put all the prefixes into a regular expression like:

^ANZX|^ANZB|^AVBA etc.

and then see if %catalognumber% matches this regex.

But that doesn’t address the OP’s desire to put each case on a separate line, unless I’m missing something.

You might be able to avoid having the spaces at each line end by specifying a separator of just a semicolon. I haven’t tried it, so I’m not sure if it would work.

1 Like

$foreach also detects the line break as part of the argument. However, I have found it relatively easy to work around it:

$set(_enclosureCatno,0)
$noop(DON'T FORGET TO ADD A TRAILING WHITESPACE AFTER EACH SEMICOLON)
$foreach(ANZB; 
ANZX; 
AVBA; 
AVXA; 
BCXA; 
DMPXA; 
EYXA; 
GNBA; 
GNXA; 
KABA; 
KAXA; 
KIZX; 
MFXN; 
PCBE; 
PCBG; 
PCXE; 
PCXG; 
SSX; 
TBR; 
VTCY; 
ZMBZ; 
ZMXZ,
$if($ne($get(_enclosureCatno),1),$set(_enclosureCatno,$if($startswith(%catalognumber%,$rreplace(%_loop_value%,\\n,)),1,0)))
)

Without $rreplace(%_loop_value%,\\n,), the script does not work. So thanks for leading me in the right direction to reducing the boilerplate.

1 Like

A bit simplified, removing the need for extra spaces and the $rreplace (but untested):

$set(_enclosureCatno,0)
$foreach(ANZB;
ANZX;
AVBA;
AVXA;
BCXA;
DMPXA;
EYXA;
GNBA;
GNXA;
KABA;
KAXA;
KIZX;
MFXN;
PCBE;
PCBG;
PCXE;
PCXG;
SSX;
TBR;
VTCY;
ZMBZ;
ZMXZ,
$if($ne(%_enclosureCatno%,1),$set(_enclosureCatno,$if($startswith(%catalognumber%,%_loop_value%),1,0)))
,;\n)

I also replaced the $get with %…% notation, IMHO it is better to read.

2 Likes

Slightly shorter version of original idea…

$set(_enclosureCatno,0)
$if($startswith(%catalognumber%,ANZX),$set(_enclosureCatno,1))
$if($startswith(%catalognumber%,ANZB),$set(_enclosureCatno,1))
...
$if($startswith(%catalognumber%,ZMXZ),$set(_enclosureCatno,1))

$if($eq(%_enclosureCatno%,1),$set(format,Enclosure))
$unset(_enclosureCatno)
1 Like