SongKong Jaikoz

SongKong and Jaikoz Music Tagger Community Forum

Noob help: Can i achieve my goals with SongKong and if so how?

So would it be valid to add something like this as an extra line between the existing lines 1 and 2 like this?:

if(mbreleasetype.toLowerCase().contains(“bootleg”) && mbreleasetype.toLowerCase().contains(“album”)) return brackets(‘Bootleg’) + ’ ';

And

if(mbreleasetype.toLowerCase().contains(“interview”) && mbreleasetype.toLowerCase().contains(“album”)) return brackets(‘Interview’) + ’ ';

Yes you got it, as long as you use the regular double quote and apostophe easily available on the keyboard rather than the fancy unicode ones that you used above in your example

e.g

if(mbreleasetype.toLowerCase().contains("bootleg") && mbreleasetype.toLowerCase().contains("album")) return brackets('Bootleg') + ' ';

1 Like

Can i ask, how this field is output, how would i need to format them when including them in the naming masks?
eg; “single; live”. i can’t remember if “;” is an illegal character on some systems? is it better to change the “;” to a “-” or “,” for example?

because some ‘types’ are primary or secondary, etc does this affect how i need to deal with them when adding in the masks? (any logic i need to observe?)

i adjusted the mask like this (so far):

function ignoreThe(name)
{
   if(name.startsWith('The ')) return name.substring(4);
   return name;
}

function brackets(name)
{
   if(name.length>0) return '(' + name + ')';
   return '';
}

function squareBrackets(name)
{
   if(name.length>0) return '[' + name + ']';
   return '';
}

function yearOnly(year)
{
   if(year.length>4) return year.substring(0,4);
   return year;
}

function r(value)
{
   return value.replaceAll("\\?","");
}

function formatSubtitle(subtitle)
{
    if(subtitle.length>0) return ' - ' + subtitle;
    return "";
}

function formatTrackArtist()
{
     featuredartists="";
     for(i=0; i<artists_index.length;i++)
     {
        if(!albumartists.contains(artists_index[i]))
        {
            featuredartists+=artists_index[i] + ", ";
        }
     }
     if(featuredartists.length>0)
     {
         return 'feat. ' + substring(featuredartists, featuredartists.length -2);
     }
     return ""; 
}

function formatReleaseType()
{
   if(mbreleasetype.toLowerCase().contains("live") && mbreleasetype.toLowerCase().contains("album")) return brackets('Live') + ' ';
   if(mbreleasetype.toLowerCase().contains("bootleg") && mbreleasetype.toLowerCase().contains("album")) return brackets('Bootleg') + ' ';
   if(mbreleasetype.toLowerCase().contains("interview") && mbreleasetype.toLowerCase().contains("album")) return brackets('Interview') + ' ';
   if(mbreleasetype.toLowerCase().contains("album")) return "";
   return brackets(mbreleasetype) + ' ';
}

function writeArtist(type)
{
   return r(type
    + "/"
    + ifnotempty2(ignoreThe(albumartist).substring(0,1),ignoreThe(artist).substring(0,1),'/')
    + ifnotempty2(albumartist,artist,'/')
    + formatReleaseType()
    + ifnotempty(album + ' ' + brackets(yearOnly(year)),'/')
    + ifmultidisc(squareBrackets('CD' + pad(discno,2) +  formatSubtitle(subtitle)) + ' ')
    + ifnotempty(pad(trackno,2),' - ')
    + ifnotempty(title,' ') 
    + squareBrackets(formatTrackArtist()))
}

function writeSoundtrack(type)
{
   return r(type
    + "/"
    + ifnotempty(album + ' ' + brackets(yearOnly(year)) + " by " + albumartist,'/')
    + ifmultidisc(squareBrackets('CD' + pad(discno,2) +  formatSubtitle(subtitle))+ ' ')
    + ifnotempty(pad(trackno,2),' - ')
    + ifnotempty(title,' ')
    + squareBrackets(formatTrackArtist()))
}

function writeAudiobook(type)
{
   return r(type
    + "/"
    + ifnotempty(album + ' ' + brackets(yearOnly(year)) + " by " + albumartist,'/')
    + ifmultidisc('CD' + pad(discno,2) + formatSubtitle(subtitle)+ '/')
    + ifnotempty(pad(trackno,2),' - ')
    + ifnotempty(title,' '))
}

if(mbreleasetype.contains("Soundtrack"))
{
    writeSoundtrack("Soundtracks");
}
else if(mbreleasetype.contains("Audiobook"))
{
    writeAudiobook("Audiobooks");
}
else
{
    writeArtist("Artists");
}

could i do this and it would work?:

   if(mbreleasetype.toLowerCase().contains("live") && mbreleasetype.toLowerCase().contains("album")) return brackets('Live') + ' ';
   if(mbreleasetype.toLowerCase().contains("bootleg") && mbreleasetype.toLowerCase().contains("album")) return brackets('Bootleg') + ' ';
   if(mbreleasetype.toLowerCase().contains("interview") && mbreleasetype.toLowerCase().contains("album")) return brackets('Interview') + ' ';
   if(mbreleasetype.toLowerCase().contains("broadcast") && mbreleasetype.toLowerCase().contains("album")) return brackets('Broadcast') + ' ';
   if(mbreleasetype.toLowerCase().contains("spokenword") && mbreleasetype.toLowerCase().contains("album")) return brackets('Spokenword') + ' ';
   if(mbreleasetype.toLowerCase().contains("audio drama") && mbreleasetype.toLowerCase().contains("album")) return brackets('Audio Drama') + ' ';
   if(mbreleasetype.toLowerCase().contains("remix") && mbreleasetype.toLowerCase().contains("album")) return brackets('Remix') + ' ';
   if(mbreleasetype.toLowerCase().contains("dj mix") && mbreleasetype.toLowerCase().contains("album")) return brackets('DJ Mix') + ' ';
   if(mbreleasetype.toLowerCase().contains("mixtape") && mbreleasetype.toLowerCase().contains("album")) return brackets('Mixtape') + ' ';
   if(mbreleasetype.toLowerCase().contains("demo") && mbreleasetype.toLowerCase().contains("album")) return brackets('Demo') + ' ';
   if(mbreleasetype.toLowerCase().contains("album")) return "";
   return brackets(mbreleasetype) + ' ';

and this for compilations?:

function ignoreThe(name)
{
   if(name.startsWith('The ')) return name.substring(4);
   return name;
}

function brackets(name)
{
   if(name.length>0) return '(' + name + ')';
   return '';
}

function squareBrackets(name)
{
   if(name.length>0) return '[' + name + ']';
   return '';
}

function yearOnly(year)
{
   if(year.length>4) return year.substring(0,4);
   return year;
}

function r(value)
{
   return value.replaceAll("\\?","");
}

function formatSubtitle(subtitle)
{
    if(subtitle.length>0) return ' - ' + subtitle;
    return "";
}

function formatReleaseType()
{
   if(mbreleasetype.toLowerCase().contains("live") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Live') + ' ';
   if(mbreleasetype.toLowerCase().contains("bootleg") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Bootleg') + ' ';
   if(mbreleasetype.toLowerCase().contains("interview") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Interview') + ' ';
   if(mbreleasetype.toLowerCase().contains("broadcast") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Broadcast') + ' ';
   if(mbreleasetype.toLowerCase().contains("spokenword") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Spokenword') + ' ';
   if(mbreleasetype.toLowerCase().contains("audio drama") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Audio Drama') + ' ';
   if(mbreleasetype.toLowerCase().contains("remix") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Remix') + ' ';
   if(mbreleasetype.toLowerCase().contains("dj mix") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('DJ Mix') + ' ';
   if(mbreleasetype.toLowerCase().contains("mixtape") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Mixtape') + ' ';
   if(mbreleasetype.toLowerCase().contains("demo") && mbreleasetype.toLowerCase().contains("compilation")) return brackets('Demo') + ' ';
   if(mbreleasetype.toLowerCase().contains("compilation")) return "";
   return brackets(mbreleasetype) + ' ';
}

function formatTrackArtist()
{
     mainartist=artists_index[0];
     featuredartists="";
     for(i=1; i<artists_index.length;i++)
     {
        if(!albumartists.contains(artists_index[i]))
        {
            featuredartists+=artists_index[i] + ", ";
        }
     }
     if(featuredartists.length>0)
     {
         return mainartist + ' feat. ' + substring(featuredartists, featuredartists.length -2);
     }
     return mainartist; 
}

function writeBody(subFolder)
{
  return r(subFolder + "/"
  + ifnotempty(album + ' ' + brackets(yearOnly(year)) + " by " + albumartist,'/')
  + ifmultidisc(squareBrackets('CD' + pad(discno,2) +  formatSubtitle(subtitle))+ ' ')
  + ifnotempty(pad(trackno,2),' - ')
  + ifnotempty(title,' ')
  + squareBrackets(formatTrackArtist()))
}

function writeAudiobooks(subFolder)
{
  return r(subFolder + "/"
  + ifnotempty(album + ' ' + brackets(yearOnly(year)) + " by " + albumartist,'/')
  + ifmultidisc('CD' + pad(discno,2) +  formatSubtitle(subtitle)+ '/')
  + ifnotempty(pad(trackno,2),' - ')
  + ifnotempty(title,' ')
  + squareBrackets(formatTrackArtist()))
}

if(mbreleasetype.contains("Soundtrack"))
{
  writeBody("Soundtracks")
}
else if(mbreleasetype.contains("Audiobook"))
{
  writeAudiobooks("Audiobooks")
}
else
{
  writeBody("Compilations");
}

i’m also trying to remember, theres a setting to include release type right? but then we are also adding them with the mask. i can’t remember why though, is it to have more granular control? and should i turn off the setting for this if so?

Yes the rename mask looks fine.

Compilation Mask is okay except the formatReleaseType() function is never called because if you look at your example masks you see there wasn’t a requirement to show release type for compilations.

Apologies, I have just found a bug

SongKong adds multiple types as seperate values to the ReleaseType field.

e.g

  • Album
  • Live

but RenameMasks and Scripter think it is added as single value

e.g
Album; Live

So the example files show Album; Compilation when it should be Album;;;Compilation and the Script Fields 1st Value and 2nd Value buttons are incorrectly disabled, and therefore formatReleaseType() function is not correct

I have raised a bug and will prioritize this once I have finished the issue I am currently working on

Yes, you mean the Fix Songs:Album Format:Add EP, Single, Compilation, Live and Remix release types to release title option. So this adds release type to the album field, and then if the album field is used in your rename mask you would see release types as part of the filename.

So this is a simpler solution to using the mbreleasetype field directly in the mask but I dont think it offers the control you require, for example it doesnt do anything with some secondary type such as Interview it only deals with Compilation, Live, Remix and Soundtrack,

Aso it only adds primary types EP and Single, it would not add Other or Audiobook to the album title

Fixed issue now, and turns out the formatReleaseType() function does continue to work fine after all as it is, also ran your masks on some test folders and could not see any issues. Will do a new release soon either the end of this week or the start of next week.

Fixes now released as part of 11.6.1