Lower quality episodes are deleted on import (from disk and db)
This commit is contained in:
parent
7381501775
commit
de6304e628
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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="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" />
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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="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" />
|
||||
|
|
Loading…
Reference in New Issue