From 3b9ed49d0fdcd67f09fb08b610e6ed57a7498a80 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 13 Oct 2018 13:41:38 -0700 Subject: [PATCH] New: Option to disable rescanning of series folder after RefreshSeriesInfo Closes #1592 --- .../Configuration/ConfigService.cs | 7 ++ .../Configuration/IConfigService.cs | 1 + .../Configuration/RescanAfterRefreshType.cs | 9 +++ .../MediaFiles/DiskScanService.cs | 6 -- src/NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Tv/Commands/RefreshSeriesCommand.cs | 8 ++- src/NzbDrone.Core/Tv/RefreshSeriesService.cs | 65 ++++++++++++++----- src/NzbDrone.Core/Tv/SeriesAddedHandler.cs | 6 +- src/NzbDrone.Core/Tv/SeriesEditedService.cs | 4 +- .../Config/MediaManagementConfigResource.cs | 2 + 10 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 src/NzbDrone.Core/Configuration/RescanAfterRefreshType.cs diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 3fea2c560..105ddfc8d 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -215,6 +215,13 @@ namespace NzbDrone.Core.Configuration set { SetValue("ExtraFileExtensions", value); } } + public RescanAfterRefreshType RescanAfterRefresh + { + get { return GetValueEnum("RescanAfterRefresh", RescanAfterRefreshType.Always); } + + set { SetValue("RescanAfterRefresh", value); } + } + public bool SetPermissionsLinux { get { return GetValueBoolean("SetPermissionsLinux", false); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 10427020a..33cc40aff 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -33,6 +33,7 @@ namespace NzbDrone.Core.Configuration bool EnableMediaInfo { get; set; } bool ImportExtraFiles { get; set; } string ExtraFileExtensions { get; set; } + RescanAfterRefreshType RescanAfterRefresh { get; set; } //Permissions (Media Management) bool SetPermissionsLinux { get; set; } diff --git a/src/NzbDrone.Core/Configuration/RescanAfterRefreshType.cs b/src/NzbDrone.Core/Configuration/RescanAfterRefreshType.cs new file mode 100644 index 000000000..d1e3a9f18 --- /dev/null +++ b/src/NzbDrone.Core/Configuration/RescanAfterRefreshType.cs @@ -0,0 +1,9 @@ +namespace NzbDrone.Core.Configuration +{ + public enum RescanAfterRefreshType + { + Always, + AfterManual, + Never + } +} diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs index eb950d1c2..407ac40dc 100644 --- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -30,7 +30,6 @@ namespace NzbDrone.Core.MediaFiles public class DiskScanService : IDiskScanService, - IHandle, IExecute { private readonly IDiskProvider _diskProvider; @@ -210,11 +209,6 @@ namespace NzbDrone.Core.MediaFiles } } - public void Handle(SeriesUpdatedEvent message) - { - Scan(message.Series); - } - public void Execute(RescanSeriesCommand message) { if (message.SeriesId.HasValue) diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 157fcd514..1e201e5ed 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -133,6 +133,7 @@ + diff --git a/src/NzbDrone.Core/Tv/Commands/RefreshSeriesCommand.cs b/src/NzbDrone.Core/Tv/Commands/RefreshSeriesCommand.cs index 4cae630cd..98657351e 100644 --- a/src/NzbDrone.Core/Tv/Commands/RefreshSeriesCommand.cs +++ b/src/NzbDrone.Core/Tv/Commands/RefreshSeriesCommand.cs @@ -1,22 +1,24 @@ -using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.Tv.Commands { public class RefreshSeriesCommand : Command { public int? SeriesId { get; set; } + public bool IsNewSeries { get; set; } public RefreshSeriesCommand() { } - public RefreshSeriesCommand(int? seriesId) + public RefreshSeriesCommand(int? seriesId, bool isNewSeries = false) { SeriesId = seriesId; + IsNewSeries = isNewSeries; } public override bool SendUpdatesToClient => true; public override bool UpdateScheduledTask => !SeriesId.HasValue; } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Tv/RefreshSeriesService.cs b/src/NzbDrone.Core/Tv/RefreshSeriesService.cs index 71eb6089f..37ef69072 100644 --- a/src/NzbDrone.Core/Tv/RefreshSeriesService.cs +++ b/src/NzbDrone.Core/Tv/RefreshSeriesService.cs @@ -5,6 +5,7 @@ using System.Linq; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Instrumentation.Extensions; +using NzbDrone.Core.Configuration; using NzbDrone.Core.DataAugmentation.DailySeries; using NzbDrone.Core.Exceptions; using NzbDrone.Core.MediaFiles; @@ -25,6 +26,7 @@ namespace NzbDrone.Core.Tv private readonly IDailySeriesService _dailySeriesService; private readonly IDiskScanService _diskScanService; private readonly ICheckIfSeriesShouldBeRefreshed _checkIfSeriesShouldBeRefreshed; + private readonly IConfigService _configService; private readonly Logger _logger; public RefreshSeriesService(IProvideSeriesInfo seriesInfo, @@ -34,6 +36,7 @@ namespace NzbDrone.Core.Tv IDailySeriesService dailySeriesService, IDiskScanService diskScanService, ICheckIfSeriesShouldBeRefreshed checkIfSeriesShouldBeRefreshed, + IConfigService configService, Logger logger) { _seriesInfo = seriesInfo; @@ -43,6 +46,7 @@ namespace NzbDrone.Core.Tv _dailySeriesService = dailySeriesService; _diskScanService = diskScanService; _checkIfSeriesShouldBeRefreshed = checkIfSeriesShouldBeRefreshed; + _configService = configService; _logger = logger; } @@ -50,17 +54,7 @@ namespace NzbDrone.Core.Tv { _logger.ProgressInfo("Updating {0}", series.Title); - Tuple> tuple; - - try - { - tuple = _seriesInfo.GetSeriesInfo(series.TvdbId); - } - catch (SeriesNotFoundException) - { - _logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId); - return; - } + var tuple = _seriesInfo.GetSeriesInfo(series.TvdbId); var seriesInfo = tuple.Item1; @@ -144,8 +138,32 @@ namespace NzbDrone.Core.Tv return seasons; } - private void RescanSeries(Series series) + private void RescanSeries(Series series, bool isNew, CommandTrigger trigger) { + var rescanAfterRefresh = _configService.RescanAfterRefresh; + var shouldRescan = true; + + if (isNew) + { + _logger.Trace("Forcing refresh of {0}. Reason: New series", series); + shouldRescan = true; + } + else if (rescanAfterRefresh == RescanAfterRefreshType.Never) + { + _logger.Trace("Skipping refresh of {0}. Reason: never recan after refresh", series); + shouldRescan = false; + } + else if (rescanAfterRefresh == RescanAfterRefreshType.AfterManual && trigger != CommandTrigger.Manual) + { + _logger.Trace("Skipping refresh of {0}. Reason: not after automatic scans", series); + shouldRescan = false; + } + + if (!shouldRescan) + { + return; + } + try { _diskScanService.Scan(series); @@ -158,7 +176,9 @@ namespace NzbDrone.Core.Tv public void Execute(RefreshSeriesCommand message) { - _eventAggregator.PublishEvent(new SeriesRefreshStartingEvent(message.Trigger == CommandTrigger.Manual)); + var trigger = message.Trigger; + var isNew = message.IsNewSeries; + _eventAggregator.PublishEvent(new SeriesRefreshStartingEvent(trigger == CommandTrigger.Manual)); if (message.SeriesId.HasValue) { @@ -167,11 +187,16 @@ namespace NzbDrone.Core.Tv try { RefreshSeriesInfo(series); + RescanSeries(series, isNew, trigger); + } + catch (SeriesNotFoundException) + { + _logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId); } catch (Exception e) { _logger.Error(e, "Couldn't refresh info for {0}", series); - RescanSeries(series); + RescanSeries(series, isNew, trigger); throw; } } @@ -181,23 +206,29 @@ namespace NzbDrone.Core.Tv foreach (var series in allSeries) { - if (message.Trigger == CommandTrigger.Manual || _checkIfSeriesShouldBeRefreshed.ShouldRefresh(series)) + if (trigger == CommandTrigger.Manual || _checkIfSeriesShouldBeRefreshed.ShouldRefresh(series)) { try { RefreshSeriesInfo(series); } + catch (SeriesNotFoundException) + { + _logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId); + continue; + } catch (Exception e) { _logger.Error(e, "Couldn't refresh info for {0}", series); - RescanSeries(series); } + + RescanSeries(series, false, trigger); } else { _logger.Info("Skipping refresh of series: {0}", series.Title); - RescanSeries(series); + RescanSeries(series, false, trigger); } } } diff --git a/src/NzbDrone.Core/Tv/SeriesAddedHandler.cs b/src/NzbDrone.Core/Tv/SeriesAddedHandler.cs index 1b8f59653..788fe59d8 100644 --- a/src/NzbDrone.Core/Tv/SeriesAddedHandler.cs +++ b/src/NzbDrone.Core/Tv/SeriesAddedHandler.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Commands; @@ -18,12 +18,12 @@ namespace NzbDrone.Core.Tv public void Handle(SeriesAddedEvent message) { - _commandQueueManager.Push(new RefreshSeriesCommand(message.Series.Id)); + _commandQueueManager.Push(new RefreshSeriesCommand(message.Series.Id, true)); } public void Handle(SeriesImportedEvent message) { - _commandQueueManager.PushMany(message.SeriesIds.Select(s => new RefreshSeriesCommand(s)).ToList()); + _commandQueueManager.PushMany(message.SeriesIds.Select(s => new RefreshSeriesCommand(s, true)).ToList()); } } } diff --git a/src/NzbDrone.Core/Tv/SeriesEditedService.cs b/src/NzbDrone.Core/Tv/SeriesEditedService.cs index 063537f18..c28641495 100644 --- a/src/NzbDrone.Core/Tv/SeriesEditedService.cs +++ b/src/NzbDrone.Core/Tv/SeriesEditedService.cs @@ -1,4 +1,4 @@ -using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Commands; using NzbDrone.Core.Tv.Events; @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Tv { if (message.Series.SeriesType != message.OldSeries.SeriesType) { - _commandQueueManager.Push(new RefreshSeriesCommand(message.Series.Id)); + _commandQueueManager.Push(new RefreshSeriesCommand(message.Series.Id, false)); } } } diff --git a/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs b/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs index 21e0c5301..048342923 100644 --- a/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs +++ b/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs @@ -12,6 +12,7 @@ namespace Sonarr.Api.V3.Config public bool CreateEmptySeriesFolders { get; set; } public bool DeleteEmptyFolders { get; set; } public FileDateType FileDate { get; set; } + public RescanAfterRefreshType RescanAfterRefresh { get; set; } public bool SetPermissionsLinux { get; set; } public string FileChmod { get; set; } @@ -38,6 +39,7 @@ namespace Sonarr.Api.V3.Config CreateEmptySeriesFolders = model.CreateEmptySeriesFolders, DeleteEmptyFolders = model.DeleteEmptyFolders, FileDate = model.FileDate, + RescanAfterRefresh = model.RescanAfterRefresh, SetPermissionsLinux = model.SetPermissionsLinux, FileChmod = model.FileChmod,