From 07386f12e62be0088d7facd4393d80de500d8768 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 17 Nov 2013 22:28:40 -0800 Subject: [PATCH] New: Only clean XBMC Library when a file is being upgraded --- .../UpgradeMediaFileServiceFixture.cs | 17 +++++ .../Xbmc/OnDownloadFixture.cs | 73 +++++++++++++++++++ .../NzbDrone.Core.Test.csproj | 1 + .../MediaFiles/EpisodeFileMoveResult.cs | 16 ++++ .../EpisodeImport/ImportApprovedEpisodes.cs | 8 +- .../Events/EpisodeDownloadedEvent.cs | 9 ++- .../MediaFiles/UpgradeMediaFileService.cs | 10 ++- .../Notifications/DownloadMessage.cs | 20 +++++ .../Notifications/Email/Email.cs | 4 +- .../Notifications/Growl/Growl.cs | 4 +- .../Notifications/INotification.cs | 2 +- .../Notifications/NotificationBase.cs | 2 +- .../Notifications/NotificationService.cs | 8 +- .../NotifyMyAndroid/NotifyMyAndroid.cs | 4 +- .../Notifications/Plex/PlexClient.cs | 4 +- .../Notifications/Plex/PlexServer.cs | 2 +- .../Notifications/Prowl/Prowl.cs | 4 +- .../Notifications/PushBullet/PushBullet.cs | 4 +- .../Notifications/Pushover/Pushover.cs | 4 +- src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs | 13 ++-- src/NzbDrone.Core/NzbDrone.Core.csproj | 2 + 21 files changed, 178 insertions(+), 33 deletions(-) create mode 100644 src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs create mode 100644 src/NzbDrone.Core/MediaFiles/EpisodeFileMoveResult.cs create mode 100644 src/NzbDrone.Core/Notifications/DownloadMessage.cs diff --git a/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs index 6594a3c77..84761a0a5 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs @@ -1,5 +1,6 @@ using System.Linq; using FizzWare.NBuilder; +using FluentAssertions; using Marr.Data; using Moq; using NUnit.Framework; @@ -149,5 +150,21 @@ namespace NzbDrone.Core.Test.MediaFiles Mocker.GetMock().Verify(v => v.DeleteFile(It.IsAny()), Times.Never()); } + + [Test] + public void should_return_old_episode_file_in_oldFiles() + { + GivenSingleEpisodeWithSingleEpisodeFile(); + + Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode).OldFiles.Count.Should().Be(1); + } + + [Test] + public void should_return_old_episode_files_in_oldFiles() + { + GivenMultipleEpisodesWithMultipleEpisodeFiles(); + + Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode).OldFiles.Count.Should().Be(2); + } } } diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs new file mode 100644 index 000000000..fff54ac02 --- /dev/null +++ b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Notifications; +using NzbDrone.Core.Notifications.Xbmc; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.NotificationTests.Xbmc +{ + [TestFixture] + public class OnDownloadFixture : CoreTest + { + private DownloadMessage _downloadMessage; + + [SetUp] + public void Setup() + { + var series = Builder.CreateNew() + .Build(); + + var episodeFile = Builder.CreateNew() + .Build(); + + _downloadMessage = Builder.CreateNew() + .With(d => d.Series = series) + .With(d => d.EpisodeFile = episodeFile) + .With(d => d.OldFiles = new List()) + .Build(); + + Subject.Definition = new NotificationDefinition(); + Subject.Definition.Settings = new XbmcSettings + { + UpdateLibrary = true + }; + } + + private void GivenOldFiles() + { + _downloadMessage.OldFiles = Builder.CreateListOfSize(1) + .Build() + .ToList(); + + Subject.Definition.Settings = new XbmcSettings + { + UpdateLibrary = true, + CleanLibrary = true + }; + } + + [Test] + public void should_not_clean_if_no_episode_was_replaced() + { + Subject.OnDownload(_downloadMessage); + + Mocker.GetMock().Verify(v => v.Clean(It.IsAny()), Times.Never()); + } + + [Test] + public void should_clean_if_episode_was_replaced() + { + GivenOldFiles(); + Subject.OnDownload(_downloadMessage); + + Mocker.GetMock().Verify(v => v.Clean(It.IsAny()), Times.Once()); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index a8cf47045..23a7f3ea0 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -169,6 +169,7 @@ + diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeFileMoveResult.cs b/src/NzbDrone.Core/MediaFiles/EpisodeFileMoveResult.cs new file mode 100644 index 000000000..978d60930 --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/EpisodeFileMoveResult.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace NzbDrone.Core.MediaFiles +{ + public class EpisodeFileMoveResult + { + public EpisodeFileMoveResult() + { + OldFiles = new List(); + } + + public String Path { get; set; } + public List OldFiles { get; set; } + } +} diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index ce14d7054..325bf8223 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -44,6 +44,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport foreach (var importDecision in qualifiedImports.OrderByDescending(e => e.LocalEpisode.Size)) { var localEpisode = importDecision.LocalEpisode; + var oldFiles = new List(); try { @@ -65,11 +66,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport episodeFile.SeasonNumber = localEpisode.SeasonNumber; episodeFile.Episodes = localEpisode.Episodes; - if (newDownload) { episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath()); - episodeFile.Path = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); + var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode); + episodeFile.Path = moveResult.Path; + oldFiles = moveResult.OldFiles; } _mediaFileService.Add(episodeFile); @@ -78,7 +80,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport if (newDownload) { _eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile)); - _eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode)); + _eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode, episodeFile, oldFiles)); } } catch (Exception e) diff --git a/src/NzbDrone.Core/MediaFiles/Events/EpisodeDownloadedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/EpisodeDownloadedEvent.cs index b7b80e4fd..af22b63fb 100644 --- a/src/NzbDrone.Core/MediaFiles/Events/EpisodeDownloadedEvent.cs +++ b/src/NzbDrone.Core/MediaFiles/Events/EpisodeDownloadedEvent.cs @@ -1,4 +1,5 @@ -using NzbDrone.Common.Messaging; +using System.Collections.Generic; +using NzbDrone.Common.Messaging; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.MediaFiles.Events @@ -6,10 +7,14 @@ namespace NzbDrone.Core.MediaFiles.Events public class EpisodeDownloadedEvent : IEvent { public LocalEpisode Episode { get; private set; } + public EpisodeFile EpisodeFile { get; private set; } + public List OldFiles { get; private set; } - public EpisodeDownloadedEvent(LocalEpisode episode) + public EpisodeDownloadedEvent(LocalEpisode episode, EpisodeFile episodeFile, List oldFiles) { Episode = episode; + EpisodeFile = episodeFile; + OldFiles = oldFiles; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs b/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs index 75ee6869e..6a299d511 100644 --- a/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.MediaFiles { public interface IUpgradeMediaFiles { - string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); + EpisodeFileMoveResult UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); } public class UpgradeMediaFileService : IUpgradeMediaFiles @@ -31,8 +31,9 @@ namespace NzbDrone.Core.MediaFiles _logger = logger; } - public string UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) + public EpisodeFileMoveResult UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) { + var moveFileResult = new EpisodeFileMoveResult(); var existingFiles = localEpisode.Episodes .Where(e => e.EpisodeFileId > 0) .Select(e => e.EpisodeFile.Value) @@ -48,11 +49,14 @@ namespace NzbDrone.Core.MediaFiles _recycleBinProvider.DeleteFile(file.Path); } + moveFileResult.OldFiles.Add(file); _mediaFileService.Delete(file, true); } _logger.Trace("Moving episode file: {0}", episodeFile); - return _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode); + moveFileResult.Path = _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode); + + return moveFileResult; } } } diff --git a/src/NzbDrone.Core/Notifications/DownloadMessage.cs b/src/NzbDrone.Core/Notifications/DownloadMessage.cs new file mode 100644 index 000000000..5e5ba6768 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/DownloadMessage.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Notifications +{ + public class DownloadMessage + { + public String Message { get; set; } + public Series Series { get; set; } + public EpisodeFile EpisodeFile { get; set; } + public List OldFiles { get; set; } + + public override string ToString() + { + return Message; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Email/Email.cs b/src/NzbDrone.Core/Notifications/Email/Email.cs index 30a4e2d23..d92c21a18 100644 --- a/src/NzbDrone.Core/Notifications/Email/Email.cs +++ b/src/NzbDrone.Core/Notifications/Email/Email.cs @@ -25,10 +25,10 @@ namespace NzbDrone.Core.Notifications.Email _smtpProvider.SendEmail(Settings, subject, body); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string subject = "NzbDrone [TV] - Downloaded"; - var body = String.Format("{0} Downloaded and sorted.", message); + var body = String.Format("{0} Downloaded and sorted.", message.Message); _smtpProvider.SendEmail(Settings, subject, body); } diff --git a/src/NzbDrone.Core/Notifications/Growl/Growl.cs b/src/NzbDrone.Core/Notifications/Growl/Growl.cs index ac8bef299..9682a5acb 100644 --- a/src/NzbDrone.Core/Notifications/Growl/Growl.cs +++ b/src/NzbDrone.Core/Notifications/Growl/Growl.cs @@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.Growl _growlProvider.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string title = "Episode Downloaded"; - _growlProvider.SendNotification(title, message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password); + _growlProvider.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/INotification.cs b/src/NzbDrone.Core/Notifications/INotification.cs index 5b5fd5a13..97ee4dc0a 100644 --- a/src/NzbDrone.Core/Notifications/INotification.cs +++ b/src/NzbDrone.Core/Notifications/INotification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.Notifications string Link { get; } void OnGrab(string message); - void OnDownload(string message, Series series); + void OnDownload(DownloadMessage message); void AfterRename(Series series); } } diff --git a/src/NzbDrone.Core/Notifications/NotificationBase.cs b/src/NzbDrone.Core/Notifications/NotificationBase.cs index 22e992ded..61377a483 100644 --- a/src/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications public abstract string Link { get; } public abstract void OnGrab(string message); - public abstract void OnDownload(string message, Series series); + public abstract void OnDownload(DownloadMessage message); public abstract void AfterRename(Series series); protected TSettings Settings diff --git a/src/NzbDrone.Core/Notifications/NotificationService.cs b/src/NzbDrone.Core/Notifications/NotificationService.cs index f0b24a264..2c016b1f7 100644 --- a/src/NzbDrone.Core/Notifications/NotificationService.cs +++ b/src/NzbDrone.Core/Notifications/NotificationService.cs @@ -73,13 +73,17 @@ namespace NzbDrone.Core.Notifications public void Handle(EpisodeDownloadedEvent message) { - var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality); + var downloadMessage = new DownloadMessage(); + downloadMessage.Message = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality); + downloadMessage.Series = message.Episode.Series; + downloadMessage.EpisodeFile = message.EpisodeFile; + downloadMessage.OldFiles = message.OldFiles; foreach (var notification in _notificationFactory.OnDownloadEnabled()) { try { - notification.OnDownload(messageBody, message.Episode.Series); + notification.OnDownload(downloadMessage); } catch (Exception ex) diff --git a/src/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs b/src/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs index d1a10a8a6..ffc1aa6ab 100644 --- a/src/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs +++ b/src/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs @@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid _notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string title = "Episode Downloaded"; - _notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); + _notifyMyAndroidProxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/Plex/PlexClient.cs b/src/NzbDrone.Core/Notifications/Plex/PlexClient.cs index 72023baa0..322af1f06 100644 --- a/src/NzbDrone.Core/Notifications/Plex/PlexClient.cs +++ b/src/NzbDrone.Core/Notifications/Plex/PlexClient.cs @@ -22,10 +22,10 @@ namespace NzbDrone.Core.Notifications.Plex _plexProvider.Notify(Settings, header, message); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string header = "NzbDrone [TV] - Downloaded"; - _plexProvider.Notify(Settings, header, message); + _plexProvider.Notify(Settings, header, message.Message); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/Plex/PlexServer.cs b/src/NzbDrone.Core/Notifications/Plex/PlexServer.cs index 57d359880..31ff31aaf 100644 --- a/src/NzbDrone.Core/Notifications/Plex/PlexServer.cs +++ b/src/NzbDrone.Core/Notifications/Plex/PlexServer.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Plex { } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { UpdateIfEnabled(); } diff --git a/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs b/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs index f8cd93e9b..b5264412a 100644 --- a/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs +++ b/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs @@ -24,11 +24,11 @@ namespace NzbDrone.Core.Notifications.Prowl _prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string title = "Episode Downloaded"; - _prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority); + _prowlProvider.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs index db64a7445..5f3931075 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs @@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.PushBullet _pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string title = "Episode Downloaded"; - _pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId); + _pushBulletProxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.DeviceId); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs b/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs index 0a8f1d1c6..a9f447c0f 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs @@ -23,11 +23,11 @@ namespace NzbDrone.Core.Notifications.Pushover _pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority); } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string title = "Episode Downloaded"; - _pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority); + _pushoverProxy.SendNotification(title, message.Message, Settings.UserKey, (PushoverPriority)Settings.Priority); } public override void AfterRename(Series series) diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs index f6b3a6abe..f111ae7b4 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs @@ -1,4 +1,5 @@ -using NzbDrone.Core.Tv; +using System.Linq; +using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications.Xbmc { @@ -26,16 +27,16 @@ namespace NzbDrone.Core.Notifications.Xbmc } } - public override void OnDownload(string message, Series series) + public override void OnDownload(DownloadMessage message) { const string header = "NzbDrone [TV] - Downloaded"; if (Settings.Notify) { - _xbmcProvider.Notify(Settings, header, message); + _xbmcProvider.Notify(Settings, header, message.Message); } - UpdateAndClean(series); + UpdateAndClean(message.Series, message.OldFiles.Any()); } public override void AfterRename(Series series) @@ -43,14 +44,14 @@ namespace NzbDrone.Core.Notifications.Xbmc UpdateAndClean(series); } - private void UpdateAndClean(Series series) + private void UpdateAndClean(Series series, bool clean = true) { if (Settings.UpdateLibrary) { _xbmcProvider.Update(Settings, series); } - if (Settings.CleanLibrary) + if (clean && Settings.CleanLibrary) { _xbmcProvider.Clean(Settings); } diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 29835c0c1..1664adc77 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -275,6 +275,7 @@ + @@ -290,6 +291,7 @@ +