Remove orphan tracks from playlists after they are removed from library

This commit is contained in:
Deluan 2020-05-18 20:32:01 -04:00
parent 0e4f7036eb
commit c2d1e9df9f
7 changed files with 46 additions and 8 deletions

View File

@ -46,6 +46,5 @@ type AlbumRepository interface {
GetStarred(options ...QueryOptions) (Albums, error)
Search(q string, offset int, size int) (Albums, error)
Refresh(ids ...string) error
PurgeEmpty() error
AnnotatedRepository
}

View File

@ -36,6 +36,5 @@ type ArtistRepository interface {
Search(q string, offset int, size int) (Artists, error)
Refresh(ids ...string) error
GetIndex() (ArtistIndexes, error)
PurgeEmpty() error
AnnotatedRepository
}

View File

@ -180,7 +180,7 @@ func getMinYear(years string) int {
return 0
}
func (r *albumRepository) PurgeEmpty() error {
func (r *albumRepository) purgeEmpty() error {
del := Delete(r.tableName).Where("id not in (select distinct(album_id) from media_file)")
c, err := r.executeSQL(del)
if err == nil {

View File

@ -155,7 +155,7 @@ func (r *artistRepository) GetStarred(options ...model.QueryOptions) (model.Arti
return starred, err
}
func (r *artistRepository) PurgeEmpty() error {
func (r *artistRepository) purgeEmpty() error {
del := Delete(r.tableName).Where("id not in (select distinct(album_artist_id) from album)")
c, err := r.executeSQL(del)
if err == nil {

View File

@ -108,11 +108,11 @@ func (s *SQLStore) WithTx(block func(tx model.DataStore) error) error {
}
func (s *SQLStore) GC(ctx context.Context) error {
err := s.Album(ctx).PurgeEmpty()
err := s.Album(ctx).(*albumRepository).purgeEmpty()
if err != nil {
return err
}
err = s.Artist(ctx).PurgeEmpty()
err = s.Artist(ctx).(*artistRepository).purgeEmpty()
if err != nil {
return err
}
@ -124,7 +124,11 @@ func (s *SQLStore) GC(ctx context.Context) error {
if err != nil {
return err
}
return s.Artist(ctx).(*artistRepository).cleanAnnotations()
err = s.Artist(ctx).(*artistRepository).cleanAnnotations()
if err != nil {
return err
}
return s.Playlist(ctx).(*playlistRepository).removeOrphans()
}
func (s *SQLStore) getOrmer() orm.Ormer {

View File

@ -165,6 +165,40 @@ func (r *playlistRepository) Update(entity interface{}, cols ...string) error {
return err
}
func (r *playlistRepository) removeOrphans() error {
sel := Select("playlist_tracks.playlist_id as id", "p.name").From("playlist_tracks").
Join("playlist p on playlist_tracks.playlist_id = p.id").
LeftJoin("media_file mf on playlist_tracks.media_file_id = mf.id").
Where(Eq{"mf.id": nil}).
GroupBy("playlist_tracks.playlist_id")
var pls []struct{ Id, Name string }
err := r.queryAll(sel, &pls)
if err != nil {
return err
}
for _, pl := range pls {
log.Debug(r.ctx, "Cleaning-up orphan tracks from playlist", "id", pl.Id, "name", pl.Name)
del := Delete("playlist_tracks").Where(And{
ConcatExpr("media_file_id not in (select id from media_file)"),
Eq{"playlist_id": pl.Id},
})
n, err := r.executeSQL(del)
if n == 0 || err != nil {
return err
}
log.Debug(r.ctx, "Deleted tracks, now reordering", "id", pl.Id, "name", pl.Name, "deleted", n)
// To reorganize the playlist, just add an empty list of new tracks
trks := r.Tracks(pl.Id)
if err := trks.Add(nil); err != nil {
return err
}
}
return nil
}
var _ model.PlaylistRepository = (*playlistRepository)(nil)
var _ rest.Repository = (*playlistRepository)(nil)
var _ rest.Persistable = (*playlistRepository)(nil)

View File

@ -66,7 +66,9 @@ func (r *playlistTrackRepository) NewInstance() interface{} {
}
func (r *playlistTrackRepository) Add(mediaFileIds []string) error {
log.Debug(r.ctx, "Adding songs to playlist", "playlistId", r.playlistId, "mediaFileIds", mediaFileIds)
if len(mediaFileIds) > 0 {
log.Debug(r.ctx, "Adding songs to playlist", "playlistId", r.playlistId, "mediaFileIds", mediaFileIds)
}
// Get all current tracks
all := r.newSelect().Columns("media_file_id").Where(Eq{"playlist_id": r.playlistId}).OrderBy("id")