using System.Collections.Generic; using System.IO; using System.Linq; using NzbDrone.Common; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Extras { public abstract class ImportExistingExtraFilesBase : IImportExistingExtraFiles where TExtraFile : ExtraFile, new() { private readonly IExtraFileService _extraFileService; public ImportExistingExtraFilesBase(IExtraFileService extraFileService) { _extraFileService = extraFileService; } public abstract int Order { get; } public abstract IEnumerable ProcessFiles(Movie movie, List filesOnDisk, List importedFiles); public virtual ImportExistingExtraFileFilterResult FilterAndClean(Movie movie, List filesOnDisk, List importedFiles) { var movieFiles = _extraFileService.GetFilesByMovie(movie.Id); Clean(movie, filesOnDisk, importedFiles, movieFiles); return Filter(movie, filesOnDisk, importedFiles, movieFiles); } private ImportExistingExtraFileFilterResult Filter(Movie movie, List filesOnDisk, List importedFiles, List movieFiles) { var previouslyImported = movieFiles.IntersectBy(s => Path.Combine(movie.Path, s.RelativePath), filesOnDisk, f => f, PathEqualityComparer.Instance).ToList(); var filteredFiles = filesOnDisk.Except(previouslyImported.Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList(), PathEqualityComparer.Instance) .Except(importedFiles, PathEqualityComparer.Instance) .ToList(); // Return files that are already imported so they aren't imported again by other importers. // Filter out files that were previously imported and as well as ones imported by other importers. return new ImportExistingExtraFileFilterResult(previouslyImported, filteredFiles); } private void Clean(Movie movie, List filesOnDisk, List importedFiles, List movieFiles) { var alreadyImportedFileIds = movieFiles.IntersectBy(f => Path.Combine(movie.Path, f.RelativePath), importedFiles, i => i, PathEqualityComparer.Instance) .Select(f => f.Id); var deletedFiles = movieFiles.ExceptBy(f => Path.Combine(movie.Path, f.RelativePath), filesOnDisk, i => i, PathEqualityComparer.Instance) .Select(f => f.Id); _extraFileService.DeleteMany(alreadyImportedFileIds); _extraFileService.DeleteMany(deletedFiles); } } }