feat(subsonic): add support for podcast episodes in both playlists and play queues
This commit is contained in:
@@ -45,6 +45,7 @@ func (db *DB) Migrate(ctx MigrationContext) error {
|
||||
construct(ctx, "202206011628", migrateInternetRadioStations),
|
||||
construct(ctx, "202206101425", migrateUser),
|
||||
construct(ctx, "202207251148", migrateStarRating),
|
||||
construct(ctx, "202211111057", migratePlaylistsQueuesToFullID),
|
||||
}
|
||||
|
||||
return gormigrate.
|
||||
@@ -386,3 +387,57 @@ func migrateStarRating(tx *gorm.DB, _ MigrationContext) error {
|
||||
).
|
||||
Error
|
||||
}
|
||||
|
||||
func migratePlaylistsQueuesToFullID(tx *gorm.DB, _ MigrationContext) error {
|
||||
step := tx.Exec(`
|
||||
UPDATE playlists SET items=('tr-' || items) WHERE items IS NOT NULL;
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate playlists to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
UPDATE playlists SET items=REPLACE(items,',',',tr-') WHERE items IS NOT NULL;
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate playlists to full id: %w", err)
|
||||
}
|
||||
|
||||
step = tx.Exec(`
|
||||
UPDATE play_queues SET items=('tr-' || items) WHERE items IS NOT NULL;
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
UPDATE play_queues SET items=REPLACE(items,',',',tr-') WHERE items IS NOT NULL;
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
ALTER TABLE play_queues ADD COLUMN newcurrent varchar[255];
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
UPDATE play_queues SET newcurrent=('tr-' || CAST(current AS varchar(10)));
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
ALTER TABLE play_queues DROP COLUMN current;
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
step = tx.Exec(`
|
||||
ALTER TABLE play_queues RENAME COLUMN newcurrent TO "current";
|
||||
`)
|
||||
if err := step.Error; err != nil {
|
||||
return fmt.Errorf("step migrate play_queues to full id: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
38
db/model.go
38
db/model.go
@@ -9,7 +9,6 @@ package db
|
||||
import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -19,26 +18,26 @@ import (
|
||||
"go.senan.xyz/gonic/server/ctrlsubsonic/specid"
|
||||
)
|
||||
|
||||
func splitInt(in, sep string) []int {
|
||||
func splitIDs(in, sep string) []specid.ID {
|
||||
if in == "" {
|
||||
return []int{}
|
||||
return []specid.ID{}
|
||||
}
|
||||
parts := strings.Split(in, sep)
|
||||
ret := make([]int, 0, len(parts))
|
||||
ret := make([]specid.ID, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
i, _ := strconv.Atoi(p)
|
||||
ret = append(ret, i)
|
||||
id, _ := specid.New(p)
|
||||
ret = append(ret, id)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func joinInt(in []int, sep string) string {
|
||||
func joinIds(in []specid.ID, sep string) string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
strs := make([]string, 0, len(in))
|
||||
for _, i := range in {
|
||||
strs = append(strs, strconv.Itoa(i))
|
||||
for _, id := range in {
|
||||
strs = append(strs, id.String())
|
||||
}
|
||||
return strings.Join(strs, sep)
|
||||
}
|
||||
@@ -256,12 +255,12 @@ type Playlist struct {
|
||||
IsPublic bool `sql:"default: null"`
|
||||
}
|
||||
|
||||
func (p *Playlist) GetItems() []int {
|
||||
return splitInt(p.Items, ",")
|
||||
func (p *Playlist) GetItems() []specid.ID {
|
||||
return splitIDs(p.Items, ",")
|
||||
}
|
||||
|
||||
func (p *Playlist) SetItems(items []int) {
|
||||
p.Items = joinInt(items, ",")
|
||||
func (p *Playlist) SetItems(items []specid.ID) {
|
||||
p.Items = joinIds(items, ",")
|
||||
p.TrackCount = len(items)
|
||||
}
|
||||
|
||||
@@ -271,22 +270,23 @@ type PlayQueue struct {
|
||||
UpdatedAt time.Time
|
||||
User *User
|
||||
UserID int `sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
Current int
|
||||
Current string
|
||||
Position int
|
||||
ChangedBy string
|
||||
Items string
|
||||
}
|
||||
|
||||
func (p *PlayQueue) CurrentSID() *specid.ID {
|
||||
return &specid.ID{Type: specid.Track, Value: p.Current}
|
||||
id, _ := specid.New(p.Current)
|
||||
return &id
|
||||
}
|
||||
|
||||
func (p *PlayQueue) GetItems() []int {
|
||||
return splitInt(p.Items, ",")
|
||||
func (p *PlayQueue) GetItems() []specid.ID {
|
||||
return splitIDs(p.Items, ",")
|
||||
}
|
||||
|
||||
func (p *PlayQueue) SetItems(items []int) {
|
||||
p.Items = joinInt(items, ",")
|
||||
func (p *PlayQueue) SetItems(items []specid.ID) {
|
||||
p.Items = joinIds(items, ",")
|
||||
}
|
||||
|
||||
type TranscodePreference struct {
|
||||
|
||||
Reference in New Issue
Block a user