Skip to content

Commit

Permalink
feat(subsonic): support public playlists
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
grilix authored and sentriz committed Feb 24, 2022
1 parent 4176b9e commit 1647eaa
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
13 changes: 12 additions & 1 deletion server/ctrlsubsonic/handlers_playlist.go
Expand Up @@ -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()
Expand All @@ -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)),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -123,13 +128,19 @@ 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
}
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
Expand Down
5 changes: 5 additions & 0 deletions server/db/migrations.go
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
1 change: 1 addition & 0 deletions server/db/model.go
Expand Up @@ -247,6 +247,7 @@ type Playlist struct {
Comment string
TrackCount int
Items string
IsPublic bool `sql:"default: null"`
}

func (p *Playlist) GetItems() []int {
Expand Down

0 comments on commit 1647eaa

Please sign in to comment.