FoxxMD / multi-scrobbler

Scrobble plays from multiple sources to multiple clients
https://foxxmd.github.io/multi-scrobbler
MIT License
424 stars 17 forks source link

feat(modifications): Implement "when" conditions #186

Closed FoxxMD closed 1 month ago

FoxxMD commented 2 months ago
github-actions[bot] commented 2 months ago

:package: A new release has been made for this pull request.

To play around with this PR, pull an image:

Images are available for x86_64 and ARM64.

Latest commit: 9b808c88146f5f995c9646891ecaf565049119f2

FoxxMD commented 2 months ago

when (if-then logic)

Top-level hooks and individual rules now support a when key for testing if they should be run.

The when key is similar to a normal modification except:

All parts of an individual when clause must test true to "pass" but if any when clauses pass the hook/rule is processed. Example when data:

{
  "when": [
    {
      "artist": "Elephant Gym", // both of these must match the Play object (AND)
      "album": "Dreams" // both of these must match the Play object (AND)
    },
    // OR
    {
      "title": "/(Remastered)$/", // both of these must match the Play object (AND)
      "album": "Various Artists" // both of these must match the Play object (AND)
    }
  ]
}

More succinctly:

(I need to come up with better terminology)

Example for top-level hook:

{
  // IF the artist is Elephant Gym 
  // THEN Run preCompare hook ELSE skip this hook
  //
  //    Run search-replace on album
  //    Run regex title remove
  "sourceDefaults": {
    "playTransform": {
      "preCompare": {
        "when": [
          {
            "artist": "/Elephant Gym/"
          }
        ],
        "album": [
          {
            "search": "Dreams",
            "replace": "夢境"
          }
        ],
        "title": ["/\s\-\s滾石40\s滾石撞樂隊\s40團拚經典(.+)$/i"]
      },
    }
  }
}

Example of individual rules:

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

Top-level hook array

Top-level hooks can now also be an array of hooks. This makes creating multiple scenarios for top-level when-gated hooks easier. All hooks in the array will be run (assuming their when's pass, if they exist) and their input will be the Play object output of the previous hook in the array.

{
  "sourceDefaults": {
    "playTransform": {
      "preCompare": [
        {
          "title": [
            {
              "search": "something",
              "replace": "else unique"
            }
          ]
        },
        {
          "title": [
            {
              "search": "else unique",
              "replace": "very demure"
            }
          ]
        },
      ]
    }
  }
}

Example using the above two preCompare hooks:

Logging

MS can log the output of hook transformations if/when they occur. In the playTransform object use log:

{
  "name": "myThing",
  "data": {/*...*/},
  "options": {
    "playTransform": {
      "preCompare": {/*...*/},
      "log": true
    }
  }
}