using System; using System.Collections.Generic; using System.IO; using System.Linq; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.Extras.Files; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Extras.Others { public class OtherExtraService : ExtraFileManager { private readonly IDiskProvider _diskProvider; private readonly IOtherExtraFileService _otherExtraFileService; private readonly IMediaFileAttributeService _mediaFileAttributeService; private readonly Logger _logger; public OtherExtraService(IConfigService configService, IDiskProvider diskProvider, IDiskTransferService diskTransferService, IOtherExtraFileService otherExtraFileService, IMediaFileAttributeService mediaFileAttributeService, Logger logger) : base(configService, diskProvider, diskTransferService, logger) { _diskProvider = diskProvider; _otherExtraFileService = otherExtraFileService; _mediaFileAttributeService = mediaFileAttributeService; _logger = logger; } public override int Order => 2; public override IEnumerable CreateAfterMediaCoverUpdate(Series series) { return Enumerable.Empty(); } public override IEnumerable CreateAfterSeriesScan(Series series, List episodeFiles) { return Enumerable.Empty(); } public override IEnumerable CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile) { return Enumerable.Empty(); } public override IEnumerable CreateAfterEpisodeFolder(Series series, string seriesFolder, string seasonFolder) { return Enumerable.Empty(); } public override IEnumerable MoveFilesAfterRename(Series series, List episodeFiles) { var extraFiles = _otherExtraFileService.GetFilesBySeries(series.Id); var movedFiles = new List(); foreach (var episodeFile in episodeFiles) { var extraFilesForEpisodeFile = extraFiles.Where(m => m.EpisodeFileId == episodeFile.Id).ToList(); foreach (var extraFile in extraFilesForEpisodeFile) { movedFiles.AddIfNotNull(MoveFile(series, episodeFile, extraFile)); } } _otherExtraFileService.Upsert(movedFiles); return movedFiles; } public override bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly) { return true; } public override IEnumerable ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List files, bool isReadOnly) { var importedFiles = new List(); var filteredFiles = files.Where(f => CanImportFile(localEpisode, episodeFile, f, Path.GetExtension(f), isReadOnly)).ToList(); var sourcePath = localEpisode.Path; var sourceFolder = _diskProvider.GetParentFolder(sourcePath); var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath); var matchingFiles = new List(); var hasNfo = false; foreach (var file in filteredFiles) { try { // Filter out duplicate NFO files if (file.EndsWith(".nfo", StringComparison.InvariantCultureIgnoreCase)) { if (hasNfo) { continue; } hasNfo = true; } // Filename match if (Path.GetFileNameWithoutExtension(file).StartsWith(sourceFileName, StringComparison.InvariantCultureIgnoreCase)) { matchingFiles.Add(file); continue; } // Season and episode match var fileEpisodeInfo = Parser.Parser.ParsePath(file) ?? new ParsedEpisodeInfo(); if (fileEpisodeInfo.EpisodeNumbers.Length == 0) { continue; } if (fileEpisodeInfo.SeasonNumber == localEpisode.FileEpisodeInfo.SeasonNumber && fileEpisodeInfo.EpisodeNumbers.SequenceEqual(localEpisode.FileEpisodeInfo.EpisodeNumbers)) { matchingFiles.Add(file); } } catch (Exception ex) { _logger.Warn(ex, "Failed to import extra file: {0}", file); } } foreach (var file in matchingFiles) { try { var extraFile = ImportFile(localEpisode.Series, episodeFile, file, isReadOnly, Path.GetExtension(file), null); _mediaFileAttributeService.SetFilePermissions(file); _otherExtraFileService.Upsert(extraFile); importedFiles.Add(extraFile); } catch (Exception ex) { _logger.Warn(ex, "Failed to import extra file: {0}", file); } } return importedFiles; } } }