Browse Source

remove missing episodes, empty seasons, empty shows

pull/40/head
Jason Dove 5 years ago
parent
commit
41c8cbf8d9
  1. 9
      ErsatzTV.Core.Tests/Fakes/FakeTelevisionRepository.cs
  2. 5
      ErsatzTV.Core/Interfaces/Repositories/ITelevisionRepository.cs
  3. 12
      ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs
  4. 12
      ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs
  5. 50
      ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs

9
ErsatzTV.Core.Tests/Fakes/FakeTelevisionRepository.cs

@ -57,11 +57,12 @@ namespace ErsatzTV.Core.Tests.Fakes @@ -57,11 +57,12 @@ namespace ErsatzTV.Core.Tests.Fakes
public Task<Either<BaseError, Episode>> GetOrAddEpisode(Season season, LibraryPath libraryPath, string path) =>
throw new NotSupportedException();
public Task<Unit> DeleteEmptyShows() => throw new NotSupportedException();
public Task<IEnumerable<string>> FindEpisodePaths(LibraryPath libraryPath) => throw new NotSupportedException();
public Task<Option<Show>> GetShowByPath(int mediaSourceId, string path) => throw new NotSupportedException();
public Task<Unit> DeleteByPath(LibraryPath libraryPath, string path) => throw new NotSupportedException();
public Task<Unit> DeleteMissingSources(int localMediaSourceId, List<string> allFolders) =>
throw new NotSupportedException();
public Task<Unit> DeleteEmptySeasons(LibraryPath libraryPath) => throw new NotSupportedException();
public Task<Unit> DeleteEmptyShows(LibraryPath libraryPath) => throw new NotSupportedException();
}
}

5
ErsatzTV.Core/Interfaces/Repositories/ITelevisionRepository.cs

@ -27,6 +27,9 @@ namespace ErsatzTV.Core.Interfaces.Repositories @@ -27,6 +27,9 @@ namespace ErsatzTV.Core.Interfaces.Repositories
Task<Either<BaseError, Show>> AddShow(int libraryPathId, string showFolder, ShowMetadata metadata);
Task<Either<BaseError, Season>> GetOrAddSeason(Show show, int libraryPathId, int seasonNumber);
Task<Either<BaseError, Episode>> GetOrAddEpisode(Season season, LibraryPath libraryPath, string path);
Task<Unit> DeleteEmptyShows();
Task<IEnumerable<string>> FindEpisodePaths(LibraryPath libraryPath);
Task<Unit> DeleteByPath(LibraryPath libraryPath, string path);
Task<Unit> DeleteEmptySeasons(LibraryPath libraryPath);
Task<Unit> DeleteEmptyShows(LibraryPath libraryPath);
}
}

12
ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs

@ -63,7 +63,17 @@ namespace ErsatzTV.Core.Metadata @@ -63,7 +63,17 @@ namespace ErsatzTV.Core.Metadata
_ => Task.FromResult(Unit.Default));
}
await _televisionRepository.DeleteEmptyShows();
foreach (string path in await _televisionRepository.FindEpisodePaths(libraryPath))
{
if (!_localFileSystem.FileExists(path))
{
_logger.LogInformation("Removing missing episode at {Path}", path);
await _televisionRepository.DeleteByPath(libraryPath, path);
}
}
await _televisionRepository.DeleteEmptySeasons(libraryPath);
await _televisionRepository.DeleteEmptyShows(libraryPath);
return Unit.Default;
}

12
ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs

@ -109,7 +109,6 @@ namespace ErsatzTV.Infrastructure.Data.Repositories @@ -109,7 +109,6 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
@"SELECT M.Id
FROM Movie M
INNER JOIN MediaItem MI on M.Id = MI.Id
INNER JOIN MovieMetadata MM on M.Id = MM.MovieId
INNER JOIN MediaVersion MV on M.Id = MV.MovieId
INNER JOIN MediaFile MF on MV.Id = MF.MediaVersionId
WHERE MI.LibraryPathId = @LibraryPathId AND MF.Path = @Path",
@ -117,17 +116,12 @@ namespace ErsatzTV.Infrastructure.Data.Repositories @@ -117,17 +116,12 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
foreach (int movieId in ids)
{
await Delete(movieId);
Movie movie = await _dbContext.Movies.FindAsync(movieId);
_dbContext.Movies.Remove(movie);
}
return Unit.Default;
}
private async Task<Unit> Delete(int movieId)
{
Movie movie = await _dbContext.Movies.FindAsync(movieId);
_dbContext.Movies.Remove(movie);
await _dbContext.SaveChangesAsync();
return Unit.Default;
}

50
ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs

@ -230,9 +230,55 @@ namespace ErsatzTV.Infrastructure.Data.Repositories @@ -230,9 +230,55 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
() => AddEpisode(season, libraryPath.Id, path));
}
public Task<Unit> DeleteEmptyShows() =>
public Task<IEnumerable<string>> FindEpisodePaths(LibraryPath libraryPath) =>
_dbConnection.QueryAsync<string>(
@"SELECT MF.Path
FROM MediaFile MF
INNER JOIN MediaVersion MV on MF.MediaVersionId = MV.Id
INNER JOIN Episode E on MV.EpisodeId = E.Id
INNER JOIN MediaItem MI on E.Id = MI.Id
WHERE MI.LibraryPathId = @LibraryPathId",
new { LibraryPathId = libraryPath.Id });
public async Task<Unit> DeleteByPath(LibraryPath libraryPath, string path)
{
IEnumerable<int> ids = await _dbConnection.QueryAsync<int>(
@"SELECT E.Id
FROM Episode E
INNER JOIN MediaItem MI on E.Id = MI.Id
INNER JOIN MediaVersion MV on E.Id = MV.EpisodeId
INNER JOIN MediaFile MF on MV.Id = MF.MediaVersionId
WHERE MI.LibraryPathId = @LibraryPathId AND MF.Path = @Path",
new { LibraryPathId = libraryPath.Id, Path = path });
foreach (int episodeId in ids)
{
Episode episode = await _dbContext.Episodes.FindAsync(episodeId);
_dbContext.Episodes.Remove(episode);
}
await _dbContext.SaveChangesAsync();
return Unit.Default;
}
public Task<Unit> DeleteEmptySeasons(LibraryPath libraryPath) =>
_dbContext.Seasons
.Filter(s => s.LibraryPathId == libraryPath.Id)
.Filter(s => s.Episodes.Count == 0)
.ToListAsync()
.Bind(
list =>
{
_dbContext.Seasons.RemoveRange(list);
return _dbContext.SaveChangesAsync();
})
.ToUnit();
public Task<Unit> DeleteEmptyShows(LibraryPath libraryPath) =>
_dbContext.Shows
.Where(s => s.Seasons.Count == 0)
.Filter(s => s.LibraryPathId == libraryPath.Id)
.Filter(s => s.Seasons.Count == 0)
.ToListAsync()
.Bind(
list =>

Loading…
Cancel
Save