feat(subsonic): add support for track/album/artist ratings/stars
fixes #171 fixes #31 * Initial code. Compiles and passes unit tests. * Moved average rating calculation from rating fetch to set rating function. Still only compiled and unit tested. * Bug fixes * Fixed bug in savePlayQueue. Removed unique_index for star / rating entries because it's not valid. * Changed time format on stars to RFC3339Nano to match created date format. * Lint fixes. * More lint fixes. * Removed add* functions and replaced with Preload. * Fixed several bugs in handlers for getStarred and getStarred2. * Fixed bug when using music folder ID. Co-authored-by: Brian Doherty <brian@hplaptop.dohertyfamily.me>
This commit is contained in:
@@ -44,6 +44,7 @@ func (db *DB) Migrate(ctx MigrationContext) error {
|
||||
construct(ctx, "202204270903", migratePodcastDropUserID),
|
||||
construct(ctx, "202206011628", migrateInternetRadioStations),
|
||||
construct(ctx, "202206101425", migrateUser),
|
||||
construct(ctx, "202207251148", migrateStarRating),
|
||||
}
|
||||
|
||||
return gormigrate.
|
||||
@@ -371,3 +372,18 @@ func migrateUser(tx *gorm.DB, _ MigrationContext) error {
|
||||
).
|
||||
Error
|
||||
}
|
||||
|
||||
func migrateStarRating(tx *gorm.DB, _ MigrationContext) error {
|
||||
return tx.AutoMigrate(
|
||||
Album{},
|
||||
AlbumStar{},
|
||||
AlbumRating{},
|
||||
Artist{},
|
||||
ArtistStar{},
|
||||
ArtistRating{},
|
||||
Track{},
|
||||
TrackStar{},
|
||||
TrackRating{},
|
||||
).
|
||||
Error
|
||||
}
|
||||
|
||||
58
db/model.go
58
db/model.go
@@ -1,4 +1,5 @@
|
||||
// Package db provides database helpers and models
|
||||
//
|
||||
//nolint:lll // struct tags get very long and can't be split
|
||||
package db
|
||||
|
||||
@@ -42,12 +43,15 @@ func joinInt(in []int, sep string) string {
|
||||
}
|
||||
|
||||
type Artist struct {
|
||||
ID int `gorm:"primary_key"`
|
||||
Name string `gorm:"not null; unique_index"`
|
||||
NameUDec string `sql:"default: null"`
|
||||
Albums []*Album `gorm:"foreignkey:TagArtistID"`
|
||||
AlbumCount int `sql:"-"`
|
||||
Cover string `sql:"default: null"`
|
||||
ID int `gorm:"primary_key"`
|
||||
Name string `gorm:"not null; unique_index"`
|
||||
NameUDec string `sql:"default: null"`
|
||||
Albums []*Album `gorm:"foreignkey:TagArtistID"`
|
||||
AlbumCount int `sql:"-"`
|
||||
Cover string `sql:"default: null"`
|
||||
ArtistStar *ArtistStar
|
||||
ArtistRating *ArtistRating
|
||||
AverageRating float64 `sql:"default: null"`
|
||||
}
|
||||
|
||||
func (a *Artist) SID() *specid.ID {
|
||||
@@ -98,6 +102,9 @@ type Track struct {
|
||||
TagTrackNumber int `sql:"default: null"`
|
||||
TagDiscNumber int `sql:"default: null"`
|
||||
TagBrainzID string `sql:"default: null"`
|
||||
TrackStar *TrackStar
|
||||
TrackRating *TrackRating
|
||||
AverageRating float64 `sql:"default: null"`
|
||||
}
|
||||
|
||||
func (t *Track) AudioLength() int { return t.Length }
|
||||
@@ -212,6 +219,9 @@ type Album struct {
|
||||
Tracks []*Track
|
||||
ChildCount int `sql:"-"`
|
||||
Duration int `sql:"-"`
|
||||
AlbumStar *AlbumStar
|
||||
AlbumRating *AlbumRating
|
||||
AverageRating float64 `sql:"default: null"`
|
||||
}
|
||||
|
||||
func (a *Album) SID() *specid.ID {
|
||||
@@ -304,6 +314,42 @@ type AlbumGenre struct {
|
||||
GenreID int `gorm:"not null; unique_index:idx_album_id_genre_id" sql:"default: null; type:int REFERENCES genres(id) ON DELETE CASCADE"`
|
||||
}
|
||||
|
||||
type AlbumStar struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
AlbumID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES albums(id) ON DELETE CASCADE"`
|
||||
StarDate time.Time
|
||||
}
|
||||
|
||||
type AlbumRating struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
AlbumID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES albums(id) ON DELETE CASCADE"`
|
||||
Rating int `gorm:"not null; check:(rating >= 1 AND rating <= 5)"`
|
||||
}
|
||||
|
||||
type ArtistStar struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
ArtistID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES artists(id) ON DELETE CASCADE"`
|
||||
StarDate time.Time
|
||||
}
|
||||
|
||||
type ArtistRating struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
ArtistID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES artists(id) ON DELETE CASCADE"`
|
||||
Rating int `gorm:"not null; check:(rating >= 1 AND rating <= 5)"`
|
||||
}
|
||||
|
||||
type TrackStar struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
TrackID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES tracks(id) ON DELETE CASCADE"`
|
||||
StarDate time.Time
|
||||
}
|
||||
|
||||
type TrackRating struct {
|
||||
UserID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES users(id) ON DELETE CASCADE"`
|
||||
TrackID int `gorm:"primary_key; not null" sql:"default: null; type:int REFERENCES tracks(id) ON DELETE CASCADE"`
|
||||
Rating int `gorm:"not null; check:(rating >= 1 AND rating <= 5)"`
|
||||
}
|
||||
|
||||
type PodcastAutoDownload string
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user