feat(server): add percentage-based limits to smart playlists (#5144)
* feat(playlists): add percentage-based limits to smart playlists Add a new `limitPercent` JSON field to Criteria that allows smart playlist limits to be expressed as a percentage of matching tracks rather than a fixed number. For example, a playlist matching 450 songs with a 10% limit returns 45 songs, scaling dynamically as the library grows. When `limitPercent` is set, refreshSmartPlaylist runs a COUNT query first to determine the total matching tracks, then resolves the percentage to an absolute LIMIT before executing the main query. The fixed `limit` field takes precedence when both are set. Values are clamped to [0, 100] during JSON unmarshaling. No database migration is needed since rules are stored as a JSON string. * fix(criteria): validate percentage limit range in IsPercentageLimit method Signed-off-by: Deluan <deluan@navidrome.org> * fix(criteria): ensure idempotency of ToSql method for expressions Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
@@ -122,6 +122,21 @@ var _ = Describe("parseNSP", func() {
|
||||
Expect(pls.Name).To(Equal("Original"))
|
||||
})
|
||||
|
||||
It("parses limitPercent from NSP", func() {
|
||||
nsp := `{
|
||||
"all": [{"is": {"loved": true}}],
|
||||
"sort": "playCount",
|
||||
"order": "desc",
|
||||
"limitPercent": 25
|
||||
}`
|
||||
pls := &model.Playlist{}
|
||||
err := s.parseNSP(ctx, pls, strings.NewReader(nsp))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pls.Rules).ToNot(BeNil())
|
||||
Expect(pls.Rules.LimitPercent).To(Equal(25))
|
||||
Expect(pls.Rules.Limit).To(Equal(0))
|
||||
})
|
||||
|
||||
It("parses criteria with multiple rules", func() {
|
||||
nsp := `{
|
||||
"all": [
|
||||
|
||||
Reference in New Issue
Block a user