using System.Collections.Generic; using System.IO; using System.Linq; using NLog; using NzbDrone.Common; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Movies; using NzbDrone.Core.Movies.Events; namespace NzbDrone.Core.MediaFiles { public interface IMediaFileService { MovieFile Add(MovieFile movieFile); void Update(MovieFile movieFile); void Update(List movieFile); void Delete(MovieFile movieFile, DeleteMediaFileReason reason); List GetFilesByMovie(int movieId); List GetFilesWithoutMediaInfo(); List FilterExistingFiles(List files, Movie movie); MovieFile GetMovie(int id); List GetMovies(IEnumerable ids); } public class MediaFileService : IMediaFileService, IHandleAsync { private readonly IEventAggregator _eventAggregator; private readonly IMediaFileRepository _mediaFileRepository; private readonly Logger _logger; public MediaFileService(IMediaFileRepository mediaFileRepository, IEventAggregator eventAggregator, Logger logger) { _mediaFileRepository = mediaFileRepository; _eventAggregator = eventAggregator; _logger = logger; } public MovieFile Add(MovieFile movieFile) { var addedFile = _mediaFileRepository.Insert(movieFile); addedFile.Movie.LazyLoad(); if (addedFile.Movie == null || addedFile.Movie.Value == null) { _logger.Error("Movie is null for the file {0}. Please run the houskeeping command to ensure movies and files are linked correctly."); } //_movieService.SetFileId(addedFile.Movie.Value, addedFile); //Should not be necessary, but sometimes below fails? _eventAggregator.PublishEvent(new MovieFileAddedEvent(addedFile)); return addedFile; } public void Update(MovieFile movieFile) { _mediaFileRepository.Update(movieFile); } public void Update(List movieFiles) { _mediaFileRepository.UpdateMany(movieFiles); } public void Delete(MovieFile movieFile, DeleteMediaFileReason reason) { //Little hack so we have the movie attached for the event consumers movieFile.Movie.LazyLoad(); movieFile.Path = Path.Combine(movieFile.Movie.Value.Path, movieFile.RelativePath); _mediaFileRepository.Delete(movieFile); _eventAggregator.PublishEvent(new MovieFileDeletedEvent(movieFile, reason)); } public List GetFilesByMovie(int movieId) { return _mediaFileRepository.GetFilesByMovie(movieId); } public List GetFilesWithoutMediaInfo() { return _mediaFileRepository.GetFilesWithoutMediaInfo(); } public List FilterExistingFiles(List files, Movie movie) { var movieFiles = GetFilesByMovie(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList(); if (!movieFiles.Any()) { return files; } return files.Except(movieFiles, PathEqualityComparer.Instance).ToList(); } public List GetMovies(IEnumerable ids) { return _mediaFileRepository.Get(ids).ToList(); } public MovieFile GetMovie(int id) { return _mediaFileRepository.Get(id); } public void HandleAsync(MovieDeletedEvent message) { var files = GetFilesByMovie(message.Movie.Id); _mediaFileRepository.DeleteMany(files); } } }