Subsonic: playlist endpoints (getPlaylists, getPlaylist, createPlaylist, updatePlaylist, deletePlaylist)

This commit is contained in:
2026-08-23 00:09:36 -05:00
parent a297454065
commit 6e2b875eaa
3 changed files with 461 additions and 0 deletions
+47
View File
@@ -123,3 +123,50 @@ func RemovePlaylistEntry(db *sql.DB, entryID string) error {
_, err := db.Exec(`DELETE FROM playlist_entries WHERE id = ?`, entryID)
return err
}
// ReplacePlaylistSongs atomically replaces a playlist's entire song list
// with songIDs, in order.
func ReplacePlaylistSongs(db *sql.DB, playlistID string, songIDs []string) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
if _, err := tx.Exec(`DELETE FROM playlist_entries WHERE playlist_id = ?`, playlistID); err != nil {
return err
}
for i, songID := range songIDs {
if _, err := tx.Exec(`INSERT INTO playlist_entries (id, playlist_id, song_id, position) VALUES (?, ?, ?, ?)`,
idgen.New("pe"), playlistID, songID, i); err != nil {
return err
}
}
if _, err := tx.Exec(`UPDATE playlists SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE id = ?`, playlistID); err != nil {
return err
}
return tx.Commit()
}
// ListPlaylistsByOwner returns only playlists owned by userID (used when
// an admin requests another user's playlists by username).
func ListPlaylistsByOwner(db *sql.DB, ownerID string) ([]*Playlist, error) {
rows, err := db.Query(playlistSelect+` WHERE owner_id = ? ORDER BY name COLLATE NOCASE`, ownerID)
if err != nil {
return nil, err
}
defer rows.Close()
var out []*Playlist
for rows.Next() {
var p Playlist
var isPublic int
var createdAt, updatedAt string
if err := rows.Scan(&p.ID, &p.OwnerID, &p.Name, &p.Description, &isPublic, &createdAt, &updatedAt); err != nil {
return nil, err
}
p.IsPublic = isPublic != 0
p.CreatedAt, _ = parseTime(createdAt)
p.UpdatedAt, _ = parseTime(updatedAt)
out = append(out, &p)
}
return out, rows.Err()
}