Lower quality episodes are deleted on import (from disk and db)

This commit is contained in:
Mark McDowall 2013-07-15 19:56:46 -07:00
parent 7381501775
commit de6304e628
9 changed files with 214 additions and 20 deletions

View File

@ -94,8 +94,8 @@ namespace NzbDrone.Core.Test.MediaFileTests
{
Subject.Import(new List<ImportDecision> {_approvedDecisions.First()}, true);
Mocker.GetMock<IMoveEpisodeFiles>()
.Verify(v => v.MoveEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode),
Mocker.GetMock<IUpgradeMediaFiles>()
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode),
Times.Once());
}
@ -113,8 +113,8 @@ namespace NzbDrone.Core.Test.MediaFileTests
{
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() });
Mocker.GetMock<IMoveEpisodeFiles>()
.Verify(v => v.MoveEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode),
Mocker.GetMock<IUpgradeMediaFiles>()
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode),
Times.Never());
}

View File

@ -0,0 +1,125 @@
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaFileTests
{
public class UpgradeMediaFileServiceFixture : CoreTest<UpgradeMediaFileService>
{
private EpisodeFile _episodeFile;
private LocalEpisode _localEpisode;
[SetUp]
public void Setup()
{
_localEpisode = new LocalEpisode();
_episodeFile = Builder<EpisodeFile>
.CreateNew()
.Build();
}
private void GivenSingleEpisodeWithSingleEpisodeFile()
{
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
.All()
.With(e => e.EpisodeFileId = 1)
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile
{
Id = 1,
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
}))
.Build()
.ToList();
}
private void GivenMultipleEpisodesWithSingleEpisodeFile()
{
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(e => e.EpisodeFileId = 1)
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile
{
Id = 1,
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
}))
.Build()
.ToList();
}
private void GivenMultipleEpisodesWithMultipleEpisodeFiles()
{
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(2)
.TheFirst(1)
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile
{
Id = 1,
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
}))
.TheNext(1)
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
new EpisodeFile
{
Id = 2,
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e02.avi",
}))
.Build()
.ToList();
}
[Test]
public void should_delete_single_episode_file_once()
{
GivenSingleEpisodeWithSingleEpisodeFile();
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Once());
}
[Test]
public void should_delete_the_same_episode_file_only_once()
{
GivenMultipleEpisodesWithSingleEpisodeFile();
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Once());
}
[Test]
public void should_delete_multiple_different_episode_files()
{
GivenMultipleEpisodesWithMultipleEpisodeFiles();
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Exactly(2));
}
[Test]
public void should_delete_episode_file_from_database()
{
GivenSingleEpisodeWithSingleEpisodeFile();
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IMediaFileService>().Verify(v => v.Delete(It.IsAny<EpisodeFile>()), Times.Once());
}
}
}

View File

@ -147,6 +147,7 @@
<Compile Include="JobTests\TestJobs.cs" />
<Compile Include="MediaCoverTests\CoverExistsSpecificationFixture.cs" />
<Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" />
<Compile Include="MediaFileTests\UpgradeMediaFileServiceFixture.cs" />
<Compile Include="MediaFileTests\EpisodeImportTests\NotExistingFileSpecificationFixture.cs" />
<Compile Include="MediaFileTests\ImportApprovedEpisodesFixture.cs" />
<Compile Include="MediaFileTests\EpisodeImportTests\UpgradeSpecificationFixture.cs" />

View File

@ -12,9 +12,12 @@ namespace NzbDrone.Core.MediaFiles
public long Size { get; set; }
public DateTime DateAdded { get; set; }
public string SceneName { get; set; }
public QualityModel Quality { get; set; }
public LazyList<Episode> Episodes { get; set; }
public override string ToString()
{
return String.Format("[{0}] {1}", Id, Path);
}
}
}

View File

@ -27,7 +27,13 @@ namespace NzbDrone.Core.MediaFiles
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
public MoveEpisodeFiles(ISeriesRepository seriesRepository, IEpisodeService episodeService, IBuildFileNames buildFileNames, IMediaFileService mediaFileService, IMessageAggregator messageAggregator, IDiskProvider diskProvider, Logger logger)
public MoveEpisodeFiles(ISeriesRepository seriesRepository,
IEpisodeService episodeService,
IBuildFileNames buildFileNames,
IMediaFileService mediaFileService,
IMessageAggregator messageAggregator,
IDiskProvider diskProvider,
Logger logger)
{
_seriesRepository = seriesRepository;
_episodeService = episodeService;

View File

@ -17,19 +17,19 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
public class ImportApprovedEpisodes : IImportApprovedEpisodes
{
private readonly IMoveEpisodeFiles _episodeFileMover;
private readonly IUpgradeMediaFiles _episodeFileUpgrader;
private readonly IMediaFileService _mediaFileService;
private readonly IDiskProvider _diskProvider;
private readonly IMessageAggregator _messageAggregator;
private readonly Logger _logger;
public ImportApprovedEpisodes(IMoveEpisodeFiles episodeFileMover,
public ImportApprovedEpisodes(IUpgradeMediaFiles episodeFileUpgrader,
IMediaFileService mediaFileService,
IDiskProvider diskProvider,
IMessageAggregator messageAggregator,
Logger logger)
{
_episodeFileMover = episodeFileMover;
_episodeFileUpgrader = episodeFileUpgrader;
_mediaFileService = mediaFileService;
_diskProvider = diskProvider;
_messageAggregator = messageAggregator;
@ -68,7 +68,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
if (newDownload)
{
episodeFile = _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode);
episodeFile = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode);
_messageAggregator.PublishEvent(new EpisodeImportedEvent(episodeFile));
}

View File

@ -9,7 +9,15 @@ using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.MediaFiles
{
public class RecycleBinProvider : IHandleAsync<SeriesDeletedEvent>, IExecute<CleanUpRecycleBinCommand>
public interface IRecycleBinProvider
{
void DeleteFolder(string path);
void DeleteFile(string path);
void Empty();
void Cleanup();
}
public class RecycleBinProvider : IHandleAsync<SeriesDeletedEvent>, IExecute<CleanUpRecycleBinCommand>, IRecycleBinProvider
{
private readonly IDiskProvider _diskProvider;
private readonly IConfigService _configService;
@ -22,11 +30,7 @@ namespace NzbDrone.Core.MediaFiles
_configService = configService;
}
public RecycleBinProvider()
{
}
public virtual void DeleteFolder(string path)
public void DeleteFolder(string path)
{
logger.Trace("Attempting to send '{0}' to recycling bin", path);
var recyclingBin = _configService.RecycleBin;
@ -56,7 +60,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
public virtual void DeleteFile(string path)
public void DeleteFile(string path)
{
logger.Trace("Attempting to send '{0}' to recycling bin", path);
var recyclingBin = _configService.RecycleBin;
@ -79,7 +83,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
public virtual void Empty()
public void Empty()
{
if (String.IsNullOrWhiteSpace(_configService.RecycleBin))
{
@ -102,7 +106,7 @@ namespace NzbDrone.Core.MediaFiles
logger.Trace("Recycling Bin has been emptied.");
}
public virtual void Cleanup()
public void Cleanup()
{
if (String.IsNullOrWhiteSpace(_configService.RecycleBin))
{

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles
{
public interface IUpgradeMediaFiles
{
EpisodeFile UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode);
}
public class UpgradeMediaFileService : IUpgradeMediaFiles
{
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly IMediaFileService _mediaFileService;
private readonly IMoveEpisodeFiles _episodeFileMover;
private readonly Logger _logger;
public UpgradeMediaFileService(IRecycleBinProvider recycleBinProvider,
IMediaFileService mediaFileService,
IMoveEpisodeFiles episodeFileMover,
Logger logger)
{
_recycleBinProvider = recycleBinProvider;
_mediaFileService = mediaFileService;
_episodeFileMover = episodeFileMover;
_logger = logger;
}
public EpisodeFile UpgradeEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
{
var existingFiles = localEpisode.Episodes
.Where(e => e.EpisodeFileId > 0)
.Select(e => e.EpisodeFile.Value)
.GroupBy(e => e.Id);
foreach (var existingFile in existingFiles)
{
var file = existingFile.First();
_logger.Trace("Removing existing episode file: {0}", file);
_recycleBinProvider.DeleteFile(file.Path);
_mediaFileService.Delete(file);
}
_logger.Trace("Moving episode file: {0}", episodeFile);
return _episodeFileMover.MoveEpisodeFile(episodeFile, localEpisode);
}
}
}

View File

@ -287,6 +287,7 @@
<Compile Include="MediaFiles\Events\EpisodeDownloadedEvent.cs" />
<Compile Include="Download\EpisodeGrabbedEvent.cs" />
<Compile Include="Download\SeriesRenamedEvent.cs" />
<Compile Include="MediaFiles\UpgradeMediaFileService.cs" />
<Compile Include="Notifications\Email\TestEmailCommand.cs" />
<Compile Include="Notifications\Growl\GrowlSettings.cs" />
<Compile Include="Notifications\Growl\TestGrowlCommand.cs" />