feat: add support for public/private playlists in NSP import
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
+13
-1
@@ -168,6 +168,11 @@ func (s *playlists) parseNSP(_ context.Context, pls *model.Playlist, reader io.R
|
|||||||
if nsp.Comment != "" {
|
if nsp.Comment != "" {
|
||||||
pls.Comment = nsp.Comment
|
pls.Comment = nsp.Comment
|
||||||
}
|
}
|
||||||
|
if nsp.Public != nil {
|
||||||
|
pls.Public = *nsp.Public
|
||||||
|
} else {
|
||||||
|
pls.Public = conf.Server.DefaultPlaylistPublicVisibility
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +414,10 @@ func (s *playlists) updatePlaylist(ctx context.Context, newPls *model.Playlist)
|
|||||||
} else {
|
} else {
|
||||||
log.Info(ctx, "Adding synced playlist", "playlist", newPls.Name, "path", newPls.Path, "owner", owner.UserName)
|
log.Info(ctx, "Adding synced playlist", "playlist", newPls.Name, "path", newPls.Path, "owner", owner.UserName)
|
||||||
newPls.OwnerID = owner.ID
|
newPls.OwnerID = owner.ID
|
||||||
newPls.Public = conf.Server.DefaultPlaylistPublicVisibility
|
// For NSP files, Public may already be set from the file; for M3U, use server default
|
||||||
|
if !newPls.IsSmartPlaylist() {
|
||||||
|
newPls.Public = conf.Server.DefaultPlaylistPublicVisibility
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s.ds.Playlist(ctx).Put(newPls)
|
return s.ds.Playlist(ctx).Put(newPls)
|
||||||
}
|
}
|
||||||
@@ -473,6 +481,7 @@ type nspFile struct {
|
|||||||
criteria.Criteria
|
criteria.Criteria
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Comment string `json:"comment"`
|
Comment string `json:"comment"`
|
||||||
|
Public *bool `json:"public"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *nspFile) UnmarshalJSON(data []byte) error {
|
func (i *nspFile) UnmarshalJSON(data []byte) error {
|
||||||
@@ -483,5 +492,8 @@ func (i *nspFile) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
i.Name, _ = m["name"].(string)
|
i.Name, _ = m["name"].(string)
|
||||||
i.Comment, _ = m["comment"].(string)
|
i.Comment, _ = m["comment"].(string)
|
||||||
|
if public, ok := m["public"].(bool); ok {
|
||||||
|
i.Public = &public
|
||||||
|
}
|
||||||
return json.Unmarshal(data, &i.Criteria)
|
return json.Unmarshal(data, &i.Criteria)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,27 @@ var _ = Describe("Playlists", func() {
|
|||||||
_, err := ps.ImportFile(ctx, folder, "invalid_json.nsp")
|
_, err := ps.ImportFile(ctx, folder, "invalid_json.nsp")
|
||||||
Expect(err.Error()).To(ContainSubstring("line 19, column 1: invalid character '\\n'"))
|
Expect(err.Error()).To(ContainSubstring("line 19, column 1: invalid character '\\n'"))
|
||||||
})
|
})
|
||||||
|
It("parses NSP with public: true and creates public playlist", func() {
|
||||||
|
pls, err := ps.ImportFile(ctx, folder, "public_playlist.nsp")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(pls.Name).To(Equal("Public Playlist"))
|
||||||
|
Expect(pls.Public).To(BeTrue())
|
||||||
|
})
|
||||||
|
It("parses NSP with public: false and creates private playlist", func() {
|
||||||
|
pls, err := ps.ImportFile(ctx, folder, "private_playlist.nsp")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(pls.Name).To(Equal("Private Playlist"))
|
||||||
|
Expect(pls.Public).To(BeFalse())
|
||||||
|
})
|
||||||
|
It("uses server default when public field is absent", func() {
|
||||||
|
DeferCleanup(configtest.SetupConfig())
|
||||||
|
conf.Server.DefaultPlaylistPublicVisibility = true
|
||||||
|
|
||||||
|
pls, err := ps.ImportFile(ctx, folder, "recently_played.nsp")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(pls.Name).To(Equal("Recently Played"))
|
||||||
|
Expect(pls.Public).To(BeTrue()) // Should be true since server default is true
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Cross-library relative paths", func() {
|
Describe("Cross-library relative paths", func() {
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "Private Playlist",
|
||||||
|
"comment": "A smart playlist that is explicitly private",
|
||||||
|
"public": false,
|
||||||
|
"all": [
|
||||||
|
{"is": {"loved": true}}
|
||||||
|
],
|
||||||
|
"sort": "title",
|
||||||
|
"order": "asc",
|
||||||
|
"limit": 100
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "Public Playlist",
|
||||||
|
"comment": "A smart playlist that is public",
|
||||||
|
"public": true,
|
||||||
|
"all": [
|
||||||
|
{"inTheLast": {"lastPlayed": 30}}
|
||||||
|
],
|
||||||
|
"sort": "lastPlayed",
|
||||||
|
"order": "desc",
|
||||||
|
"limit": 50
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user