SUGGESTION - JSON file to control settings of WS scripts

I've thought about this over the past days and like it a lot. Thank you for the suggestion.

I've also thought about the data schema for the JSON settings and came up with a slightly different version than you've suggested. I've used your existing settings to create an initial example settings schema:

{
  "settings": [
    {
      "type": "string",
      "key": "dateFormat",
      "title": "DATE Format",
      "description": "Format used for the DATE field.",
      "choices": [
        "YYYY-MM-DD",
        "MMDD",
        "DDMM"
      ],
      "default": "YYYY-MM-DD"
    },
    {
      "type": "string",
      "key": "yearFormat",
      "title": "YEAR Format",
      "description": "Format used for the YEAR field.",
      "choices": [
        "YYYY-MM-DD",
        "DD-MM-YYYY",
        "YYYY"
      ],
      "default": "YYYY-MM-DD"
    },
    {
      "type": "bool",
      "key": "genreRename",
      "title": "Rename Genres",
      "description": "'Progressive House' => 'House Progressive', 'Electro House' => 'House Electro', etc.",
      "default": true
    },
    {
      "type": "bool",
      "key": "initialkeyAddPadding",
      "title": "Add Padding to INITIALKEY",
      "description": "8A => 08A, 7B => 07B, etc.",
      "default": true
    },
    {
      "type": "bool",
      "key": "initialkeyAddPadding",
      "title": "Add Padding to INITIALKEY",
      "description": "8A => 08A, 7B => 07B, etc.",
      "default": true
    },
    {
      "type": "string",
      "key": "initialkeyFormat",
      "title": "INITIALKEY Format",
      "description": "Format used for the INITIALKEY field.",
      "choices": [
        "camelot",
        "musical"
      ],
      "default": "camelot"
    },
    {
      "type": "bool",
      "key": "totaltracksAddPadding",
      "title": "Add Padding to TOTALTRACKS",
      "default": true
    },
    {
      "type": "bool",
      "key": "trackAddPadding",
      "title": "Add Padding to TRACK",
      "default": true
    },
    {
      "type": "bool",
      "key": "trackTotaltracksAppend",
      "title": "Append TOTALTRACKS to TRACK",
      "description": "1/10, 2/10, 3/10 etc.",
      "default": true
    }
  ]
}

What I currently have in mind is that this information is stored in, e.g.,
Beatport by &stevehero v6#SETTINGS.settings

which can be referenced in, e.g.,
Beatport by &stevehero v6_Release Search.inc

via a new key
[Settings]=Beatport by &stevehero v6#SETTINGS.settings

to make the settings available to the WS.

The actual values that are configured by the user should most likely be stored in a separate file, e.g.,
Beatport by &stevehero v6#SETTINGS.user as simple key-value pairs, e.g.,

{
  "dateFormat": "MMDD",
  "genreRename": false
}

This ensures that you can add new configuration options with future versions of the WS without the need to ask users to copy the additions to their settings file. It would just use the default if there is no value for the added key in the .user file.


I've also thought about how to access the settings and think a dedicated function
IfVar "key" "value"

would be best. With the examples above, you'd use

IfVar "dateFormat" "MMDD"
  ...
Else
 ...
Endif

or

IfVar "genreRename" "true"
  ...
Else
 ...
Endif

I still need to implement all that, maybe without the dynamic generation of the UI in the first iteration. But I wanted to share this, so that you and others can potentially comment on my initial ideas.

3 Likes

Thanks, Florian, I was worried this may be too much work for you but I feel it's something that can be expanded on as you say and will hopefully not scare people from using scripts because they can't set them up like they would like.


My only suggestion is to have the JSON file set up so the UI idea can be added without the need for people to swap it out with a newer one.

Things like the:

  • The Title of the dialog
  • Tooltips (maybe that's what description is?)

One Question for now:

  • Would multiple radio buttons be possible? e.g. more than 2.

Perfect :slight_smile:

Yes, I plan to add UI-only types like title for the title of the dialog. I've used description for the description of the individual configuration setting to allow it to be used in other contexts than a tooltip.

I thought about using a drop-down list for those settings, as in dateFormat above, where the user then can select the desired format from the list.

1 Like

This is a great idea and would help with making the scripts more versatile and relevant for more people without needing too many variants and that users need to modify them.

Drop downs work for me too. This will be a huge feature to add so thanks for even considering it Florian :+1:t2:

I've worked quite extensively on this over the past days and refined my original design further. Here is the current status.

This is the definition of a settings schema for a Beatport Tag Source and needs to be stored in a *.settings file, e.g.,
Beatport by &stevehero v6#SETTINGS.settings

and will be referenced in, e.g.,
Beatport by &stevehero v6_Release Search.inc

via a new key
[Settings]=Beatport by &stevehero v6#SETTINGS.settings

to make the settings available to the WS.

{
  "key": "beatport",
  "title": "Beatport Settings",
  "settings": [
    {
      "type": "string",
      "key": "dateFormat",
      "title": "DATE Format",
      "description": "Format used for the DATE field.",
      "choices": [
        "YYYY-MM-DD",
        "MMDD",
        "DDMM"
      ],
      "default": "YYYY-MM-DD"
    },
    {
      "type": "string",
      "key": "yearFormat",
      "title": "YEAR Format",
      "description": "Format used for the YEAR field.",
      "choices": [
        "YYYY-MM-DD",
        "DD-MM-YYYY",
        "YYYY"
      ],
      "default": "YYYY-MM-DD"
    },
    {
      "type": "bool",
      "key": "genreRename",
      "title": "Rename Genres",
      "description": "'Progressive House' => 'House Progressive', 'Electro House' => 'House Electro', etc.",
      "default": true
    },
    {
      "type": "bool",
      "key": "initialkeyAddPadding",
      "title": "Add Padding to INITIALKEY",
      "description": "8A => 08A, 7B => 07B, etc.",
      "default": true
    },
    {
      "type": "string",
      "key": "initialkeyFormat",
      "title": "INITIALKEY Format",
      "description": "Format used for the INITIALKEY field.",
      "choices": [
        "camelot",
        "musical"
      ],
      "default": "camelot"
    },
    {
      "type": "bool",
      "key": "totaltracksAddPadding",
      "title": "Add Padding to TOTALTRACKS",
      "default": true
    },
    {
      "type": "bool",
      "key": "trackAddPadding",
      "title": "Add Padding to TRACK",
      "default": true
    },
    {
      "type": "bool",
      "key": "trackTotaltracksAppend",
      "title": "Append TOTALTRACKS to TRACK",
      "description": "1/10, 2/10, 3/10 etc.",
      "default": true
    }
  ]
}

To configure the settings, the user would use the dedicated menu item that is created at the end of the Tag Sources menu, separated from the actual Tag Sources. The example name Beatport by &stevehero v6#SETTINGS.settings results in a menu item SETTINGS in the Beatport by &stevehero v6 submenu.

Choosing this menu item shows a dedicated dialog that is generated based on the individual settings schema.

The actual values that are configured by the user are stored in a separate file settings.json as simple key-value pairs, e.g.,

{
  "beatport": {
    "dateFormat": "MMDD",
    "genreRename": false
    "yearFormat": "YYYY"
  }
}

Note, that this settings file is used for the user settings of all Tag Sources. The individual objects use the key from the respective settings schema definition.

This ensures that you can add new configuration options with future versions of the WS without the need to ask users to copy the additions to their settings file. It would just use the default if there is no value for the added key in the settings.json file.


A dedicated function is used to access the individual settings in the WS, where the key is used to access the setting which is compared to the given value.

IfVar "key" "value"
IfNotVar "key" "value"

With the examples above, you'd use

IfVar "genreRename" "true"
  ...
Else
 ...
Endif

or

IfNotVar "dateFormat" "MMDD"
  ...
Else
 ...
Endif
3 Likes

In addition it should be possible to localize the text strings.

Also, an edit box to allow a user to type a string would be great.

I want to get allow users to change the way feat. is done as some like it like:
ft.
feat. or
featuring.

So I think a GetVar function would be great too.

But not sure how difficult this would be to implement because you'd have to do something like this:

RegexpReplace "(?i)\s+f(ea)?t\.*\s+" GetVar "SettingFeaturingString"       # 'ft. => feat.' 'Ft. => feat.' 'Feat. => feat.'

This is beyond the scope for now, you'd need to provide some sensible defaults for the user to choose from and handle the variations in the script.

1 Like

Ok, I guess that could work too but less customisable.

A restore defaults button somewhere?

And perhaps a method for a separator?

As you see there will be a lot of settings. EDIT: This may cause an issue with small monitors so a scrollbar may be needed.

I think all the remove fields settings should better be handled via the field checkboxes I’ve added to the adjust tag information dialog a while ago.

It doesn't stop people from editing the scripts and breaking them. Please see the latest few replies on the Beatport thread. So this is why I will be adding these global options.

In addition to what I've described above in #7, I've worked on dynamic adaptation of the dialog height to a size that shows the most options. I've also added a separator type that simple shows a line between controls and has an optional title:

{
  "type": "separator"
  "title": "Optional Separator Text"
}

If you're looking for a visually more distinctive header text, I've also added a heading type that creates a bold text control with different background:

{
  "type": "heading"
  "title": "Header Text"
}

This is now available with Mp3tag v3.21h.

This is now also available on macOS with Mp3tag for Mac v1.8.2.

This seem great, and seem to work fine in the script, except (at least on Mac) it does not actually save the settings to the settings.json file (or remember the settings). I had to manually create settings.json file as well, otherwise it would just complain about the file not existing.

1 Like

Thanks for pointing! It's getting created automatically on Windows and I'll fix that for macOS with the next release. I'll keep you posted.

I've just released Mp3tag for Mac v1.8.3 which should fix this issue. Thanks again for reporting — and for experimenting with the new features!

I'll think about a solution that doesn't require replicating the configuration schema for each language and keeps everything in one place.

1 Like

I'm experimenting with a dedicated localizations object in the .settings file, which lists all languages with localizations, where the individual localization items reference the key that is used at the control definition.

Example:

{
  "key": "test",
  "title": "Test Settings",
  "settings": [
    {
      "type": "string",
      "key": "testChoices",
      "title": "Something to choose from",
      "description": "Select the preferred item",
      "choices": [
        "Item 1",
        "Item 2",
        "Item 3"
      ],
      "default": "Item 1"
    },
    {
      "type": "bool",
      "key": "testCheck",
      "title": "Something to check",
      "description": "Check to enable",
      "default": false
    }
  ],
  "localizations": {
    "de": [
      {
        "key": "test",
        "title": "Test Einstellungen"
      },
      {
        "key": "testChoices",
        "title": "Etwas zur Auswahl",
        "description": "Wählen Sie den gewünschten Eintrag"
      },
      {
        "key": "testCheck",
        "title": "Etwas zum Abhaken",
        "description": "Häkchen setzen zum Aktivieren"
      }
    ]
  }
}

Please note that localization items are optional and are referenced using the key from the individual items in the settings definition. The window title is referenced using the root key from the settings definition.

The language keys are using the ISO-639-1 language code.