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);
|
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…
Reference in New Issue