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) GetStarred(options ...QueryOptions) (Albums, error)
Search(q string, offset int, size int) (Albums, error) Search(q string, offset int, size int) (Albums, error)
Refresh(ids ...string) error Refresh(ids ...string) error
PurgeEmpty() error
AnnotatedRepository AnnotatedRepository
} }

View File

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

View File

@ -180,7 +180,7 @@ func getMinYear(years string) int {
return 0 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)") del := Delete(r.tableName).Where("id not in (select distinct(album_id) from media_file)")
c, err := r.executeSQL(del) c, err := r.executeSQL(del)
if err == nil { if err == nil {

View File

@ -155,7 +155,7 @@ func (r *artistRepository) GetStarred(options ...model.QueryOptions) (model.Arti
return starred, err 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)") del := Delete(r.tableName).Where("id not in (select distinct(album_artist_id) from album)")
c, err := r.executeSQL(del) c, err := r.executeSQL(del)
if err == nil { 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 { func (s *SQLStore) GC(ctx context.Context) error {
err := s.Album(ctx).PurgeEmpty() err := s.Album(ctx).(*albumRepository).purgeEmpty()
if err != nil { if err != nil {
return err return err
} }
err = s.Artist(ctx).PurgeEmpty() err = s.Artist(ctx).(*artistRepository).purgeEmpty()
if err != nil { if err != nil {
return err return err
} }
@ -124,7 +124,11 @@ func (s *SQLStore) GC(ctx context.Context) error {
if err != nil { if err != nil {
return err 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 { func (s *SQLStore) getOrmer() orm.Ormer {

View File

@ -165,6 +165,40 @@ func (r *playlistRepository) Update(entity interface{}, cols ...string) error {
return err 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 _ model.PlaylistRepository = (*playlistRepository)(nil)
var _ rest.Repository = (*playlistRepository)(nil) var _ rest.Repository = (*playlistRepository)(nil)
var _ rest.Persistable = (*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 { 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 // Get all current tracks
all := r.newSelect().Columns("media_file_id").Where(Eq{"playlist_id": r.playlistId}).OrderBy("id") all := r.newSelect().Columns("media_file_id").Where(Eq{"playlist_id": r.playlistId}).OrderBy("id")