navidrome/model
Deluan Quintão 82fde00ecc
feat(scrobbler): add per-user scrobble filter (#5964)
* feat(scrobbler): add scrobble_filter column to user

* feat(scrobbler): validate scrobble filter criteria on user save

* refactor(persistence): make smart playlist join helpers package-level

* feat(scrobbler): add MediaFileRepository.MatchesCriteria

* feat(scrobbler): filter external scrobbles with per-user criteria

* feat(ui): add scrobble filter field to user form

* fix(scrobbler): default scrobble_filter to empty string for existing users

* refactor(scrobbler): also gate playback reports on the scrobble filter

Playback reports carry the same track metadata to plugin scrobblers, so a
filtered track leaked through that third dispatch path. Skip the filter
evaluation entirely when no scrobbler is active.

* refactor(persistence): move criteria join building into criteria_sql.go

The join set a criteria needs was decided in criteria_sql.go but built in
smart_playlist_repository.go, so both callers had to pair the two by hand.

* refactor(persistence): unexport smartPlaylistCriteria methods

The type never leaves the package, so the exported names advertised an API
that callers outside persistence could never reach. Also disambiguates
where/orderBy from squirrel's SelectBuilder methods of the same name.

* fix(ui): cap the scrobble filter field width

fullWidth stretched it across the whole page next to 256px inputs. Bounded
at 40em, with two rows and a resize handle so JSON rules stay readable.

* refactor(ui): move scrobble filter input in UserEdit component

* feat(ui): add pt-BR translations for the scrobble filter

* fix(scrobbler): take the filter verdict before incPlay

incPlay mutates play counts and dates a filter can test on, so evaluating at
dispatch time let one play decide differently on either side of the increment:
a track could be scrobbled despite matching, or lose only its stopped report
and strand presence plugins. Reject limit/offset too, rather than silently
ignoring part of a rule copied from a smart playlist.

* fix(scrobbler): filter the report from an expired session

The expiry callback runs with a stub user carrying no filter, so evaluating
there always returned false and leaked the track to plugin scrobblers. That is
the normal path for clients that never send stopped, such as legacy Subsonic
now-playing. Carry the last verdict on the session instead.

* refactor(scrobbler): skip the now-playing enqueue instead of threading the verdict

Queuing an entry only to drop it at dispatch also cancelled a pending
announcement for the previous, unfiltered track, since the queue is keyed by
player and a new entry replaces the old one.

* fix(scrobbler): evaluate the filter regardless of active scrobblers

The verdict is stored on the session and dispatched at expiry, so skipping
evaluation when no scrobbler was active let a plugin enabled mid-session
receive a filtered track. The empty-filter guard above already gives servers
without scrobbling the same free path, so the shortcut only ever applied to
users who had a filter set.
2026-08-15 16:10:53 -04:00
..
criteria feat(smartplaylist): add album-level fields for sorting and filtering (#5899) 2026-08-06 10:59:50 -04:00
id refactor(db): migrate all ids to a uniform canonical 128-bit base62 encoding (#5824) 2026-08-02 12:58:53 -04:00
metadata refactor(db): migrate all ids to a uniform canonical 128-bit base62 encoding (#5824) 2026-08-02 12:58:53 -04:00
request fix(scanner) artist stats not refreshing during quick scan and after missing file deletion (#4269) 2025-06-26 15:50:56 -04:00
album.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
album_test.go fix(subsonic): avoid double brackets when appending subtitle or version (#5832) 2026-07-20 21:49:14 -04:00
annotation.go feat(subsonic): Add avgRating from subsonic spec (#4900) 2026-01-18 17:42:42 -05:00
artist.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
artist_info.go Get Similar Artists in parallel 2020-10-21 21:44:03 -04:00
artist_test.go refactor(conf): replace eager dir creation with lazy Dir type (#5495) 2026-05-13 17:44:22 -03:00
artwork.go feat(cli): add an artwork command group for diagnosing and re-driving artwork (#5957) 2026-08-14 21:07:56 -04:00
artwork_id.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
artwork_id_test.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
artwork_test.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
bookmark.go Use structs lib to map models to DB. Fix #1266 2021-08-01 12:04:45 -04:00
datastore.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
errors.go feat: Multi-library support (#4181) 2025-07-18 18:41:12 -04:00
file_types.go Fix M3U mimetype on Debian Bullseye 2024-05-09 22:26:15 -04:00
file_types_test.go Refactor file type functions 2022-12-28 15:31:56 -05:00
folder.go fix(scanner): import playlists skipped when no admin existed yet (#5609) 2026-06-14 13:39:16 -04:00
folder_test.go ci: run Go tests on Windows (#5380) 2026-04-19 13:16:47 -04:00
genre.go fix(jellyfin): resolve genre id as a MusicGenre item 2026-08-10 21:37:57 -04:00
get_entity.go feat(jellyfin): emit refreshResource events on favorite/rating changes 2026-07-18 16:50:23 -04:00
get_entity_test.go feat(jellyfin): emit refreshResource events on favorite/rating changes 2026-07-18 16:50:23 -04:00
image.go refactor(conf): replace eager dir creation with lazy Dir type (#5495) 2026-05-13 17:44:22 -03:00
library.go feat: Multi-library support (#4181) 2025-07-18 18:41:12 -04:00
lyrics.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_benchmark_test.go fix(scanner): stop logging expected lyrics sniff misses as warnings (#5702) 2026-07-02 09:46:57 -04:00
lyrics_lrc.go fix(lyrics): consider trailing timestamp in ELRC lyrics (#5677) 2026-06-27 16:11:08 -04:00
lyrics_lrc_test.go fix(lyrics): consider trailing timestamp in ELRC lyrics (#5677) 2026-06-27 16:11:08 -04:00
lyrics_lyricsfile.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_lyricsfile_test.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_normalize.go fix(lyrics): correct TTML background-vocal cue timing and whitespace (#5672) 2026-06-27 10:37:25 -04:00
lyrics_normalize_test.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_parse.go fix(scanner): stop logging expected lyrics sniff misses as warnings (#5702) 2026-07-02 09:46:57 -04:00
lyrics_parse_test.go fix(scanner): stop logging expected lyrics sniff misses as warnings (#5702) 2026-07-02 09:46:57 -04:00
lyrics_srt.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_srt_test.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_test.go refactor(lyrics): single ParseLyrics entry point + all-format plugin lyrics (#5632) 2026-06-19 18:25:35 -04:00
lyrics_ttml.go fix(lyrics): correct TTML background-vocal cue timing and whitespace (#5672) 2026-06-27 10:37:25 -04:00
lyrics_ttml_test.go fix(lyrics): correct TTML background-vocal cue timing and whitespace (#5672) 2026-06-27 10:37:25 -04:00
mediafile.go feat(scrobbler): add per-user scrobble filter (#5964) 2026-08-15 16:10:53 -04:00
mediafile_internal_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
mediafile_test.go fix(subsonic): avoid double brackets when appending subtitle or version (#5832) 2026-07-20 21:49:14 -04:00
model_suite_test.go Rename log.LevelCritical to log.LevelFatal 2022-12-21 14:53:36 -05:00
participants.go feat(server): expose main credit stat to reflect only album artist | artist credit (#4268) 2025-06-28 19:00:13 -04:00
participants_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
player.go chore: remove more outdated TODOs 2025-03-23 11:53:43 -04:00
playlist.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
playlist_test.go feat(smartplaylist): per-playlist refreshDelay for stable daily/weekly playlists (#5790) 2026-07-16 22:20:35 -04:00
playqueue.go feat(server): add update and clear play queue endpoints to native API (#4215) 2025-06-11 12:02:31 -04:00
plugin.go fix(plugins): clear plugin errors on startup to allow retrying 2026-03-02 08:56:56 -05:00
properties.go Associate main entities with library 2024-05-12 21:37:42 -04:00
radio.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
radio_test.go feat(artwork): new artwork pipeline with background resolution and Low Quality Image Placeholders (#5847) 2026-08-09 15:03:27 -04:00
scanner.go fix(cli): accept absolute paths in selective scan --target (#5947) 2026-08-12 14:55:04 -04:00
scanner_test.go feat(scanner): implement selective folder scanning and file system watcher improvements (#4674) 2025-11-14 22:15:43 -05:00
scrobble.go feat(server): add scrobble history Native API (#5761) 2026-07-13 11:32:03 -04:00
scrobble_buffer.go fix(plugins): discard buffered scrobbles when a plugin is removed (#5737) 2026-07-08 12:37:17 -04:00
searchable.go feat(subsonic): sort search3 results by relevance (#5086) 2026-02-23 08:51:54 -05:00
share.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
tag.go feat(jellyfin): filter items by year and record label (#5817) 2026-07-19 12:39:31 -04:00
tag_mappings.go feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701) 2026-07-02 08:29:44 -04:00
tag_mappings_test.go feat(scanner): add ArtistSplitExceptions to protect artist names from splitting (#5701) 2026-07-02 08:29:44 -04:00
tag_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
transcoding.go Replace beego/orm with dbx (#2693) 2023-12-09 13:52:17 -05:00
user.go feat(scrobbler): add per-user scrobble filter (#5964) 2026-08-15 16:10:53 -04:00
user_props.go Pass userId explicitly to UserPropsRepository methods 2021-06-25 22:21:37 -04:00
user_test.go feat: Multi-library support (#4181) 2025-07-18 18:41:12 -04:00