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

pull/6/head
Mark McDowall 12 years ago
parent 7381501775
commit de6304e628

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

@ -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());
}
}
}

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

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

@ -27,7 +27,13 @@ namespace NzbDrone.Core.MediaFiles
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly Logger _logger; 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; _seriesRepository = seriesRepository;
_episodeService = episodeService; _episodeService = episodeService;

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

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

@ -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);
}
}
}

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

Loading…
Cancel
Save