navidrome/model/metadata
Deluan Quintão 4cbba2ae49
feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701)
* refactor(scanner): make tag value splitting position-based

Replaces the ZWSP substitution trick with index-based cutting, in
preparation for artist split exceptions, which need match positions.

* feat(scanner): protect whitelisted names in tag value splitting

Separator matches inside word-bounded exception matches no longer split.
Matching is case-insensitive and longest-first; boundaries are rune-aware.

* feat(scanner): add Scanner.ArtistSplitExceptions config option

* feat(scanner): honor artist split exceptions for participant tags

Applies Scanner.ArtistSplitExceptions to artist, albumartist and role tag
splitting. Generic tags (genre, mood, ...) are unaffected.

* fix(scanner): apply split exceptions when per-tag Split overrides participant tags

Per-tag Tags.<name>.Split makes the generic ingestion path split the tag
before participant mapping runs, bypassing the whitelist. Attach the
exceptions to participant tag mappings (including sort variants) in clean().

* feat(scanner): split performer names and honor split exceptions

Performer pair values were never split; multiple names in one PERFORMER
value stayed a single artist. Split them with the roles separators, using
the same whitelist protection as other participant tags.

* test(scanner): lock MBID ordering for split performer values

* refactor(scanner): consolidate split-exception wiring and drop hot-path lock

ArtistSplitExceptionsRx is called per tag mapping per scanned file across
concurrent goroutines; replace the mutex+joined-key cache with an atomic
pointer compared via slices.Equal. Route all participant call sites through
WithParticipantExceptions and a shared splitParticipantValues helper.

* refactor(scanner): unexport artistSplitExceptionsRx

All external callers go through WithParticipantExceptions, so the accessor
does not need to be part of the model package API.
2026-07-02 08:29:44 -04:00
..
legacy_ids.go refactor(scanner): refactor legacyReleaseDate logic and add tests for date mapping 2025-11-12 13:11:33 -05:00
map_mediafile.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
map_mediafile_test.go feat(smartplaylist): extend isMissing/isPresent to bpm, bitDepth and many text fields (#5603) 2026-06-13 13:15:20 -04:00
map_participants.go feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701) 2026-07-02 08:29:44 -04:00
map_participants_test.go feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701) 2026-07-02 08:29:44 -04:00
metadata.go feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701) 2026-07-02 08:29:44 -04:00
metadata_suite_test.go feat(bfr): Big Refactor: new scanner, lots of new fields and tags, improvements and DB schema changes (#2709) 2025-02-19 20:35:17 -05:00
metadata_test.go feat(subsonic): add structured sidecar lyrics support with OpenSubsonic v2 karaoke cues and agent layers (#5076) 2026-06-19 12:00:58 -04:00
persistent_ids.go perf: reduce hot-path heap escapes from value-param pointer aliasing (#5342) 2026-04-10 21:59:49 -04:00
persistent_ids_test.go ci: run Go tests on Windows (#5380) 2026-04-19 13:16:47 -04:00