feat(subsonic): support public playlists
When multiple people share the same instance, they might want to share their playlists between them. This allows people to mark playlists as public, and to listen to public playlists from other people. Listeners will also know who owns the playlist, to help avoid confusion and make this feature a bit nicer. Subsonic restrict updating playlists only to owners, this honors that behavior, but adding flexibility could be achieved easily.
This commit is contained in:
@@ -23,6 +23,8 @@ func playlistRender(c *Controller, playlist *db.Playlist) *spec.Playlist {
|
||||
Comment: playlist.Comment,
|
||||
Created: playlist.CreatedAt,
|
||||
SongCount: playlist.TrackCount,
|
||||
Public: playlist.IsPublic,
|
||||
Owner: user.Name,
|
||||
}
|
||||
|
||||
trackIDs := playlist.GetItems()
|
||||
@@ -48,7 +50,7 @@ func playlistRender(c *Controller, playlist *db.Playlist) *spec.Playlist {
|
||||
func (c *Controller) ServeGetPlaylists(r *http.Request) *spec.Response {
|
||||
user := r.Context().Value(CtxUser).(*db.User)
|
||||
var playlists []*db.Playlist
|
||||
c.DB.Where("user_id=?", user.ID).Find(&playlists)
|
||||
c.DB.Where("user_id=?", user.ID).Or("is_public=?", true).Find(&playlists)
|
||||
sub := spec.NewResponse()
|
||||
sub.Playlists = &spec.Playlists{
|
||||
List: make([]*spec.Playlist, len(playlists)),
|
||||
@@ -90,6 +92,9 @@ func (c *Controller) ServeCreatePlaylist(r *http.Request) *spec.Response {
|
||||
FirstOrCreate(&playlist)
|
||||
|
||||
// update meta info
|
||||
if playlist.UserID != 0 && playlist.UserID != user.ID {
|
||||
return spec.NewResponse()
|
||||
}
|
||||
playlist.UserID = user.ID
|
||||
if val, err := params.Get("name"); err == nil {
|
||||
playlist.Name = val
|
||||
@@ -123,6 +128,9 @@ func (c *Controller) ServeUpdatePlaylist(r *http.Request) *spec.Response {
|
||||
FirstOrCreate(&playlist)
|
||||
|
||||
// update meta info
|
||||
if playlist.UserID != 0 && playlist.UserID != user.ID {
|
||||
return spec.NewResponse()
|
||||
}
|
||||
playlist.UserID = user.ID
|
||||
if val, err := params.Get("name"); err == nil {
|
||||
playlist.Name = val
|
||||
@@ -130,6 +138,9 @@ func (c *Controller) ServeUpdatePlaylist(r *http.Request) *spec.Response {
|
||||
if val, err := params.Get("comment"); err == nil {
|
||||
playlist.Comment = val
|
||||
}
|
||||
if val, err := params.GetBool("public"); err == nil {
|
||||
playlist.IsPublic = val
|
||||
}
|
||||
trackIDs := playlist.GetItems()
|
||||
|
||||
// delete items
|
||||
|
||||
@@ -40,6 +40,7 @@ func (db *DB) Migrate(ctx MigrationContext) error {
|
||||
construct(ctx, "202201042236", migrateArtistGuessedFolder),
|
||||
construct(ctx, "202202092013", migrateArtistCover),
|
||||
construct(ctx, "202202121809", migrateAlbumRootDirAgain),
|
||||
construct(ctx, "202202241218", migratePublicPlaylist),
|
||||
}
|
||||
|
||||
return gormigrate.
|
||||
@@ -327,3 +328,7 @@ func migrateArtistCover(tx *gorm.DB, ctx MigrationContext) error {
|
||||
func migrateAlbumRootDirAgain(tx *gorm.DB, ctx MigrationContext) error {
|
||||
return migrateAlbumRootDir(tx, ctx)
|
||||
}
|
||||
|
||||
func migratePublicPlaylist(tx *gorm.DB, ctx MigrationContext) error {
|
||||
return tx.AutoMigrate(Playlist{}).Error
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ type Playlist struct {
|
||||
Comment string
|
||||
TrackCount int
|
||||
Items string
|
||||
IsPublic bool `sql:"default: null"`
|
||||
}
|
||||
|
||||
func (p *Playlist) GetItems() []int {
|
||||
|
||||
Reference in New Issue
Block a user