Skip to main content

User Stage

The User Stage uses search-and-replace expressions, provided by you, to modify/replace parts of Play data.

This Stage is most useful for correcting individual instances of bad data, or patterns, in your known data. Example scenarios:

  • Removing (Album Version) from all Titles
  • Removing Various Artists from Artist data
  • Correcting spelling mistakes for individual Artist names

The user Stage type is user.

Configuration

All Stage Configuration is done using search-and-replace expressions inside individual rules. Default configuration for all Rules can still be done using Stage defaults.

Example
config.json
{
// ...
"transformers": [
{
"type": "user",
"name": "Normalizer",
"defaults": {
"title": [
"(Album Version)"
],
"artists": [
"Various Artists"
]
}
}
]
}

Default Stage

For your convenience, if you do not define any User Stage Configurations then multi-scrobbler automatically builds an empty one for you.

This can be used by omitting the name in your modification Stage.

Example

In a Subsonic File Config:

subsonic.json
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "user",
// do not include name, the default user stage will be used
"title": [
// removes badterm from track title
"badterm"
]
}
]
}
}
}
]

Search-And-Replace Expression

A Search-And-Replace Expression can be a plain string that matches a literal, then removes it:

Expression: "badTerm"

"this is badTerm cool string" => "this is a cool string"

or a regular expression that matches and removes the match:

Expression: "/bad\w+/i"

"this is badSomething cool string" => "this is a cool string"

Or it may be an object that specifies what to match (using either plain string or regular expression) and what to replace it with:

{
"search": "anotherBadTerm", // match all instances of 'anotherBadTerm'
"replace": "goodTerm" // replace with the string 'goodTerm'
}
"this is anotherBadTerm cool string" => "this is goodTerm cool string"
{
"search": "/^\(\w+.com)/i", // matches any string that starts with EX '(YourMusic.com)'
"replace": "[MySite.com]" // replace with the string '[MySite.com]'
}
"(Foo.com) this is a cool string" => "[MySite.com] this is a cool string"

The replace property uses javascript's replace() function and so can use any special string characters.

Rules

Each Rule must be an array of search-and-replace expressions:

lastfm.json
[
{
"name": "myLastFm",
"configureAs": "source",
"data": {
// ...
},
"options": {
"playTransform": {
"type": "user",
"preCompare": [
{
"title": [
// removes "badTerm" from title
"badTerm",
{
// removes "fooTerm" from title and replaces it with "barTerm"
"search": "fooTerm",
"replace": "barTerm"
}
]
}
],
}
}
}
]
note

If the value of the field (title, an artist, album) is an empty string after transforming then the field is removed.

Examples

Usage with when condition

Using when for Conditional Modification

Example
//   On search-replace in title...
// IF artist matches "Elephant Gym"
// THEN Run regex search-replace ELSE skip this rule
//
// Run live|remastered regex remove on title
{
"title": [
{
"search": "/\\s\\-\\s滾石40\\s滾石撞樂隊\\s40團拚經典(.+)$/i",
"replace": "",
"when": [
{
"artist": "/Elephant Gym/"
}
]
},
"/(\\s\\-\\s|\\s)(feat\\.(.+)|live|remastered(.+))$/i"
],
}

Remove phrase from Title in all new Plays

Removes the phrase (Album Version) from the Title of a Play

Example
{
"title": [
"(Album Version)"
]
}

Remove all parenthesized content from the end of a title

Example
{
"compare": {
"candidate": {
"title": [
"/(\(.+\))\s*$/"
]
},
"existing": {
"title": [
"/(\(.+\))\s*$/"
]
},
},
}

Rename misspelled artist in all new Plays

Example
{
"artists": [
{
"search": "Boz Skaggs",
"replace": "Boz Scaggs"
}
]
}

Remove "Various Artists" albums in all new Plays

Example
{
"album": [
{
"search": "Various Artists",
"replace": ""
}
]
}

Extract primary Artist from delimited, multi-Artist string

Details

When the Artist string is actually a multi-artist, delimited string, this search-and-replace will replace the string with just the first artist found.

Ex

My Artist One / My Artist Two / Another Guy
My Artist One

Artists are delimited with a spaced forward slash (/) in the regex below. Replace the contents of the delim capture group with the delimiter for your use case. Some more common scenarios:

  • (?<delim>\\/) No spaces between slash IE My Artist One/My Artist Two/Another Guy
  • (?<delim>\\s*\\\\\s*) Backslash instead of forward slash IE My Artist One \ My Artist Two \ Another Guy
  • (?<delim>,) Comma IE My Artist One, My Artist Two, Another Guy
Example
{
"artists": [
{
"search": "(.*?)(?<delim>\\s*\\/\\s*)(.*$)",
"replace": "$1"
}
]
}