From f26540cdc77124440f2bb7431df19b4204a39a32 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 23 Nov 2021 16:33:45 -0800 Subject: [PATCH] Reanalyze media files if file size changes Closes #3366 --- .../MediaFiles/DiskScanService.cs | 41 ++++++++++++++++++- .../EpisodeImport/ImportDecisionMaker.cs | 8 +++- .../MediaInfo/UpdateMediaInfoService.cs | 29 +++++++------ 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs index 0c68b6baa..9a7712a2d 100644 --- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -12,6 +12,7 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.MediaFiles.Events; +using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.RootFolders; @@ -36,8 +37,10 @@ namespace NzbDrone.Core.MediaFiles private readonly IImportApprovedEpisodes _importApprovedEpisodes; private readonly IConfigService _configService; private readonly ISeriesService _seriesService; + private readonly IMediaFileService _mediaFileService; private readonly IMediaFileTableCleanupService _mediaFileTableCleanupService; private readonly IRootFolderService _rootFolderService; + private readonly IUpdateMediaInfo _updateMediaInfoService; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; @@ -46,8 +49,10 @@ namespace NzbDrone.Core.MediaFiles IImportApprovedEpisodes importApprovedEpisodes, IConfigService configService, ISeriesService seriesService, + IMediaFileService mediaFileService, IMediaFileTableCleanupService mediaFileTableCleanupService, IRootFolderService rootFolderService, + IUpdateMediaInfo updateMediaInfoService, IEventAggregator eventAggregator, Logger logger) { @@ -56,8 +61,10 @@ namespace NzbDrone.Core.MediaFiles _importApprovedEpisodes = importApprovedEpisodes; _configService = configService; _seriesService = seriesService; + _mediaFileService = mediaFileService; _mediaFileTableCleanupService = mediaFileTableCleanupService; _rootFolderService = rootFolderService; + _updateMediaInfoService = updateMediaInfoService; _eventAggregator = eventAggregator; _logger = logger; } @@ -124,12 +131,44 @@ namespace NzbDrone.Core.MediaFiles CleanMediaFiles(series, mediaFileList); + var seriesFiles = _mediaFileService.GetFilesBySeries(series.Id); + var unmappedFiles = MediaFileService.FilterExistingFiles(mediaFileList, seriesFiles, series); + var decisionsStopwatch = Stopwatch.StartNew(); - var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, series); + var decisions = _importDecisionMaker.GetImportDecisions(unmappedFiles, series, false); decisionsStopwatch.Stop(); _logger.Trace("Import decisions complete for: {0} [{1}]", series, decisionsStopwatch.Elapsed); _importApprovedEpisodes.Import(decisions, false); + // Update existing files that have a different file size + + var fileInfoStopwatch = Stopwatch.StartNew(); + var filesToUpdate = new List(); + + foreach (var file in seriesFiles) + { + var path = Path.Combine(series.Path, file.RelativePath); + var fileSize = _diskProvider.GetFileSize(path); + + if (file.Size == fileSize) continue; + + file.Size = fileSize; + + if (!_updateMediaInfoService.Update(file, series)) + { + filesToUpdate.Add(file); + } + } + + // Update any files that had a file size change, but didn't get media info updated. + if (filesToUpdate.Any()) + { + _mediaFileService.Update(filesToUpdate); + } + + fileInfoStopwatch.Stop(); + _logger.Trace("Reprocessing existing files complete for: {0} [{1}]", series, decisionsStopwatch.Elapsed); + RemoveEmptySeriesFolder(series.Path); CompletedScanning(series); } diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs index fd8cf8a06..acb57fc32 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport public interface IMakeImportDecision { List GetImportDecisions(List videoFiles, Series series); + List GetImportDecisions(List videoFiles, Series series, bool filterExistingFiles); List GetImportDecisions(List videoFiles, Series series, DownloadClientItem downloadClientItem, ParsedEpisodeInfo folderInfo, bool sceneSource); List GetImportDecisions(List videoFiles, Series series, DownloadClientItem downloadClientItem, ParsedEpisodeInfo folderInfo, bool sceneSource, bool filterExistingFiles); ImportDecision GetDecision(LocalEpisode localEpisode, DownloadClientItem downloadClientItem); @@ -46,7 +47,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport public List GetImportDecisions(List videoFiles, Series series) { - return GetImportDecisions(videoFiles, series, null, null, false); + return GetImportDecisions(videoFiles, series, false); + } + + public List GetImportDecisions(List videoFiles, Series series, bool filterExistingFiles) + { + return GetImportDecisions(videoFiles, series, null, null, false, filterExistingFiles); } public List GetImportDecisions(List videoFiles, Series series, DownloadClientItem downloadClientItem, ParsedEpisodeInfo folderInfo, bool sceneSource) diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/UpdateMediaInfoService.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/UpdateMediaInfoService.cs index 5fcf952ca..807878d9a 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaInfo/UpdateMediaInfoService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/UpdateMediaInfoService.cs @@ -12,10 +12,10 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo { public interface IUpdateMediaInfo { - void Update(EpisodeFile episodeFile, Series series); + bool Update(EpisodeFile episodeFile, Series series); } - public class UpdateMediaInfoService : IHandle, IUpdateMediaInfo + public class UpdateMediaInfoService : IUpdateMediaInfo, IHandle { private readonly IDiskProvider _diskProvider; private readonly IMediaFileService _mediaFileService; @@ -55,34 +55,37 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo } } - public void Update(EpisodeFile episodeFile, Series series) + public bool Update(EpisodeFile episodeFile, Series series) { if (!_configService.EnableMediaInfo) { _logger.Debug("MediaInfo is disabled"); - return; + return false; } - UpdateMediaInfo(episodeFile, series); + + return UpdateMediaInfo(episodeFile, series); } - private void UpdateMediaInfo(EpisodeFile episodeFile, Series series) + private bool UpdateMediaInfo(EpisodeFile episodeFile, Series series) { var path = Path.Combine(series.Path, episodeFile.RelativePath); if (!_diskProvider.FileExists(path)) { _logger.Debug("Can't update MediaInfo because '{0}' does not exist", path); - return; + return false; } var updatedMediaInfo = _videoFileInfoReader.GetMediaInfo(path); - if (updatedMediaInfo != null) - { - episodeFile.MediaInfo = updatedMediaInfo; - _mediaFileService.Update(episodeFile); - _logger.Debug("Updated MediaInfo for '{0}'", path); - } + if (updatedMediaInfo == null) return false; + + episodeFile.MediaInfo = updatedMediaInfo; + _mediaFileService.Update(episodeFile); + _logger.Debug("Updated MediaInfo for '{0}'", path); + + return true; + } } }