1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-09 04:22:30 +01:00

moved moving of episode files into their own service.

This commit is contained in:
kay.one 2013-03-07 13:49:00 +09:00
parent 9a8414edde
commit e635e816f6
11 changed files with 135 additions and 122 deletions

View File

@ -1,17 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Jobs.Implementations; using NzbDrone.Core.Jobs.Implementations;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.JobTests namespace NzbDrone.Core.Test.JobTests
@ -22,7 +17,7 @@ public class RenameSeasonJobFixture : TestBase
private ProgressNotification _testNotification; private ProgressNotification _testNotification;
private Series _series; private Series _series;
private IList<EpisodeFile> _episodeFiles; private IList<EpisodeFile> _episodeFiles;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
@ -47,24 +42,18 @@ public void Setup()
.Returns(_episodeFiles.ToList()); .Returns(_episodeFiles.ToList());
} }
private void WithMovedFiles()
{
Mocker.GetMock<DiskScanProvider>()
.Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), false))
.Returns(_episodeFiles.First());
}
[Test] [Test]
public void should_throw_if_seriesId_is_zero() public void should_throw_if_seriesId_is_zero()
{ {
Assert.Throws<ArgumentException>(() => Assert.Throws<ArgumentException>(() =>
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = 0, SeasonNumber = 10 })); Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = 0, SeasonNumber = 10 }));
} }
[Test] [Test]
public void should_throw_if_seasonId_is_less_than_zero() public void should_throw_if_seasonId_is_less_than_zero()
{ {
Assert.Throws<ArgumentException>(() => Assert.Throws<ArgumentException>(() =>
Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.Id, SeasonNumber = -10 })); Mocker.Resolve<RenameSeasonJob>().Start(_testNotification, new { SeriesId = _series.Id, SeasonNumber = -10 }));
} }
@ -76,6 +65,6 @@ public void should_log_warning_if_no_episode_files_are_found()
ExceptionVerification.ExpectedWarns(1); ExceptionVerification.ExpectedWarns(1);
} }
} }
} }

View File

@ -1,30 +1,20 @@
using System; using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Download;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests namespace NzbDrone.Core.Test.MediaFileTests
{ {
// ReSharper disable InconsistentNaming public class EpisodeFileMoverFixture : CoreTest<MoveEpisodeFiles>
public class MoveEpisodeFileFixture : CoreTest
{ {
[Test] [Test]
public void should_not_move_file_if_source_and_destination_are_the_same_path() public void should_not_move_file_if_source_and_destination_are_the_same_path()
@ -66,7 +56,7 @@ public void should_not_move_file_if_source_and_destination_are_the_same_path()
.Returns(fi); .Returns(fi);
//Act //Act
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, false); var result = Subject.MoveEpisodeFile(file, false);
//Assert //Assert
result.Should().BeNull(); result.Should().BeNull();
@ -119,7 +109,7 @@ public void should_use_EpisodeFiles_quality()
.Setup(s => s.FileExists(currentFilename)) .Setup(s => s.FileExists(currentFilename))
.Returns(true); .Returns(true);
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true); var result = Subject.MoveEpisodeFile(file, true);
} }
@ -167,7 +157,7 @@ public void should_log_error_and_return_null_when_source_file_does_not_exists()
.Setup(e => e.BuildFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".mkv")) .Setup(e => e.BuildFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".mkv"))
.Returns(fi); .Returns(fi);
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true); var result = Subject.MoveEpisodeFile(file, true);
result.Should().BeNull(); result.Should().BeNull();
ExceptionVerification.ExpectedErrors(1); ExceptionVerification.ExpectedErrors(1);

View File

@ -153,6 +153,7 @@
<Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" /> <Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" />
<Compile Include="MediaFileTests\GhostFileCleanupFixture.cs" /> <Compile Include="MediaFileTests\GhostFileCleanupFixture.cs" />
<Compile Include="MediaFileTests\MediaFileRepositoryFixture.cs" /> <Compile Include="MediaFileTests\MediaFileRepositoryFixture.cs" />
<Compile Include="MediaFileTests\EpisodeFileMoverFixture.cs" />
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" /> <Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" /> <Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" />
<Compile Include="ProviderTests\DownloadProviderTests\ContainsRecentEpisode.cs" /> <Compile Include="ProviderTests\DownloadProviderTests\ContainsRecentEpisode.cs" />
@ -217,7 +218,6 @@
<Compile Include="JobTests\SeriesSearchJobTest.cs" /> <Compile Include="JobTests\SeriesSearchJobTest.cs" />
<Compile Include="ProviderTests\EventClientProviderTest.cs" /> <Compile Include="ProviderTests\EventClientProviderTest.cs" />
<Compile Include="ProviderTests\XbmcProviderTest.cs" /> <Compile Include="ProviderTests\XbmcProviderTest.cs" />
<Compile Include="ProviderTests\DiskScanProviderTests\MoveEpisodeFileFixture.cs" />
<Compile Include="TvTests\EpisodeProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" /> <Compile Include="TvTests\EpisodeProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />
<Compile Include="ProviderTests\DiskScanProviderTests\ImportFileFixture.cs" /> <Compile Include="ProviderTests\DiskScanProviderTests\ImportFileFixture.cs" />
<Compile Include="FluentTest.cs" /> <Compile Include="FluentTest.cs" />

View File

@ -233,7 +233,7 @@ public void when_no_file_are_imported_and_folder_size_isnt_small_enought_folder_
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder)); Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes()); Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles); Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile()); Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder); Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
@ -298,7 +298,7 @@ public void when_files_are_imported_and_folder_is_small_enough_dir_should_be_del
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries); Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName)); Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName));
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile()); Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes()); Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(droppedFolder.FullName, true)); Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(droppedFolder.FullName, true));
Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true); Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true);
@ -330,7 +330,7 @@ public void all_imported_files_should_be_moved()
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder); Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
//Assert //Assert
Mocker.GetMock<DiskScanProvider>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true), Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true),
Times.Exactly(fakeEpisodeFiles.Count)); Times.Exactly(fakeEpisodeFiles.Count));
Mocker.VerifyAllMocks(); Mocker.VerifyAllMocks();
} }

View File

@ -136,7 +136,7 @@ public void should_move_file_if_imported()
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file); Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
//Assert //Assert
Mocker.GetMock<DiskScanProvider>().Verify(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true), Times.Once()); Mocker.GetMock<IMoveEpisodeFiles>().Verify(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true), Times.Once());
ExceptionVerification.IgnoreWarns(); ExceptionVerification.IgnoreWarns();
} }

View File

@ -6,7 +6,6 @@
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Jobs.Implementations namespace NzbDrone.Core.Jobs.Implementations
@ -14,19 +13,18 @@ namespace NzbDrone.Core.Jobs.Implementations
public class RenameSeasonJob : IJob public class RenameSeasonJob : IJob
{ {
private readonly IMediaFileService _mediaFileService; private readonly IMediaFileService _mediaFileService;
private readonly DiskScanProvider _diskScanProvider;
private readonly ISeriesRepository _seriesRepository; private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IMoveEpisodeFiles _episodeFilesMover;
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public RenameSeasonJob(IMediaFileService mediaFileService, DiskScanProvider diskScanProvider, public RenameSeasonJob(IMediaFileService mediaFileService, ISeriesRepository seriesRepository, IEventAggregator eventAggregator, IMoveEpisodeFiles episodeFilesMover)
ISeriesRepository seriesRepository, IEventAggregator eventAggregator)
{ {
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
_diskScanProvider = diskScanProvider;
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_episodeFilesMover = episodeFilesMover;
} }
public string Name public string Name
@ -68,7 +66,7 @@ public void Start(ProgressNotification notification, dynamic options)
try try
{ {
var oldFile = new EpisodeFile(episodeFile); var oldFile = new EpisodeFile(episodeFile);
var newFile = _diskScanProvider.MoveEpisodeFile(episodeFile); var newFile = _episodeFilesMover.MoveEpisodeFile(episodeFile);
if (newFile != null) if (newFile != null)
{ {

View File

@ -6,7 +6,6 @@
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Jobs.Implementations namespace NzbDrone.Core.Jobs.Implementations
@ -14,19 +13,18 @@ namespace NzbDrone.Core.Jobs.Implementations
public class RenameSeriesJob : IJob public class RenameSeriesJob : IJob
{ {
private readonly IMediaFileService _mediaFileService; private readonly IMediaFileService _mediaFileService;
private readonly DiskScanProvider _diskScanProvider;
private readonly ISeriesRepository _seriesRepository; private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IMoveEpisodeFiles _moveEpisodeFiles;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public RenameSeriesJob(IMediaFileService mediaFileService, DiskScanProvider diskScanProvider, public RenameSeriesJob(IMediaFileService mediaFileService, ISeriesRepository seriesRepository, IEventAggregator eventAggregator, IMoveEpisodeFiles moveEpisodeFiles)
ISeriesRepository seriesRepository,IEventAggregator eventAggregator)
{ {
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
_diskScanProvider = diskScanProvider;
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_moveEpisodeFiles = moveEpisodeFiles;
} }
public string Name public string Name
@ -50,10 +48,10 @@ public void Start(ProgressNotification notification, dynamic options)
else else
{ {
seriesToRename = new List<Series>{ _seriesRepository.Get((int)options.SeriesId) }; seriesToRename = new List<Series> { _seriesRepository.Get((int)options.SeriesId) };
} }
foreach(var series in seriesToRename) foreach (var series in seriesToRename)
{ {
notification.CurrentMessage = String.Format("Renaming episodes for '{0}'", series.Title); notification.CurrentMessage = String.Format("Renaming episodes for '{0}'", series.Title);
@ -74,7 +72,7 @@ public void Start(ProgressNotification notification, dynamic options)
try try
{ {
var oldFile = new EpisodeFile(episodeFile); var oldFile = new EpisodeFile(episodeFile);
var newFile = _diskScanProvider.MoveEpisodeFile(episodeFile); var newFile = _moveEpisodeFiles.MoveEpisodeFile(episodeFile);
if (newFile != null) if (newFile != null)
{ {

View File

@ -0,0 +1,97 @@
using System;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Download;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MediaFiles
{
public interface IMoveEpisodeFiles
{
EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = false);
}
public class MoveEpisodeFiles : IMoveEpisodeFiles
{
private readonly ISeriesRepository _seriesRepository;
private readonly IEpisodeService _episodeService;
private readonly IBuildFileNames _buildFileNames;
private readonly IMediaFileService _mediaFileService;
private readonly IEventAggregator _eventAggregator;
private readonly DiskProvider _diskProvider;
private readonly Logger _logger;
public MoveEpisodeFiles(ISeriesRepository seriesRepository, IEpisodeService episodeService, IBuildFileNames buildFileNames, IMediaFileService mediaFileService, IEventAggregator eventAggregator, DiskProvider diskProvider, Logger logger)
{
_seriesRepository = seriesRepository;
_episodeService = episodeService;
_buildFileNames = buildFileNames;
_mediaFileService = mediaFileService;
_eventAggregator = eventAggregator;
_diskProvider = diskProvider;
_logger = logger;
}
public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = false)
{
if (episodeFile == null)
throw new ArgumentNullException("episodeFile");
var series = _seriesRepository.Get(episodeFile.SeriesId);
var episodes = _episodeService.GetEpisodesByFileId(episodeFile.Id);
string newFileName = _buildFileNames.BuildFilename(episodes, series, episodeFile);
var newFile = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path));
//Only rename if existing and new filenames don't match
if (DiskProvider.PathEquals(episodeFile.Path, newFile))
{
_logger.Debug("Skipping file rename, source and destination are the same: {0}", episodeFile.Path);
return null;
}
if (!_diskProvider.FileExists(episodeFile.Path))
{
_logger.Error("Episode file path does not exist, {0}", episodeFile.Path);
return null;
}
_diskProvider.CreateDirectory(new FileInfo(newFile).DirectoryName);
_logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, newFile);
_diskProvider.MoveFile(episodeFile.Path, newFile);
//Wrapped in Try/Catch to prevent this from causing issues with remote NAS boxes, the move worked, which is more important.
try
{
_diskProvider.InheritFolderPermissions(newFile);
}
catch (UnauthorizedAccessException ex)
{
_logger.Debug("Unable to apply folder permissions to: ", newFile);
_logger.TraceException(ex.Message, ex);
}
episodeFile.Path = newFile;
_mediaFileService.Update(episodeFile);
var parseResult = Parser.ParsePath(episodeFile.Path);
parseResult.Series = series;
parseResult.Quality = new QualityModel { Quality = episodeFile.Quality, Proper = episodeFile.Proper };
parseResult.Episodes = episodes;
if (newDownload)
{
_eventAggregator.Publish(new EpisodeDownloadedEvent(parseResult));
}
return episodeFile;
}
}
}

View File

@ -250,6 +250,7 @@
<Compile Include="Lifecycle\AppRestartJob.cs" /> <Compile Include="Lifecycle\AppRestartJob.cs" />
<Compile Include="Lifecycle\IInitializable.cs" /> <Compile Include="Lifecycle\IInitializable.cs" />
<Compile Include="MediaCover\MediaCover.cs" /> <Compile Include="MediaCover\MediaCover.cs" />
<Compile Include="MediaFiles\EpisodeFileMovingService.cs" />
<Compile Include="MediaFiles\Events\EpisodeFileDeletedEvent.cs" /> <Compile Include="MediaFiles\Events\EpisodeFileDeletedEvent.cs" />
<Compile Include="MediaFiles\GhostFileCleanupService.cs" /> <Compile Include="MediaFiles\GhostFileCleanupService.cs" />
<Compile Include="MediaFiles\MediaFileRepository.cs" /> <Compile Include="MediaFiles\MediaFileRepository.cs" />

View File

@ -4,11 +4,7 @@
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
@ -22,24 +18,22 @@ public class DiskScanProvider
private readonly IEpisodeService _episodeService; private readonly IEpisodeService _episodeService;
private readonly ICleanGhostFiles _ghostFileCleaner; private readonly ICleanGhostFiles _ghostFileCleaner;
private readonly IMediaFileService _mediaFileService; private readonly IMediaFileService _mediaFileService;
private readonly IBuildFileNames _buildFileNames;
private readonly RecycleBinProvider _recycleBinProvider; private readonly RecycleBinProvider _recycleBinProvider;
private readonly MediaInfoProvider _mediaInfoProvider; private readonly MediaInfoProvider _mediaInfoProvider;
private readonly ISeriesRepository _seriesRepository; private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator; private readonly IMoveEpisodeFiles _moveEpisodeFiles;
public DiskScanProvider(DiskProvider diskProvider, IEpisodeService episodeService, ICleanGhostFiles ghostFileCleaner, IMediaFileService mediaFileService, IConfigService configService, IBuildFileNames buildFileNames, public DiskScanProvider(DiskProvider diskProvider, IEpisodeService episodeService, ICleanGhostFiles ghostFileCleaner, IMediaFileService mediaFileService,
RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider, ISeriesRepository seriesRepository, IEventAggregator eventAggregator) RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider, ISeriesRepository seriesRepository, IMoveEpisodeFiles moveEpisodeFiles)
{ {
_diskProvider = diskProvider; _diskProvider = diskProvider;
_episodeService = episodeService; _episodeService = episodeService;
_ghostFileCleaner = ghostFileCleaner; _ghostFileCleaner = ghostFileCleaner;
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
_buildFileNames = buildFileNames;
_recycleBinProvider = recycleBinProvider; _recycleBinProvider = recycleBinProvider;
_mediaInfoProvider = mediaInfoProvider; _mediaInfoProvider = mediaInfoProvider;
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
_eventAggregator = eventAggregator; _moveEpisodeFiles = moveEpisodeFiles;
} }
public DiskScanProvider() public DiskScanProvider()
@ -180,63 +174,6 @@ public virtual EpisodeFile ImportFile(Series series, string filePath)
return episodeFile; return episodeFile;
} }
public virtual EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = false)
{
if (episodeFile == null)
throw new ArgumentNullException("episodeFile");
var series = _seriesRepository.Get(episodeFile.SeriesId);
var episodes = _episodeService.GetEpisodesByFileId(episodeFile.Id);
string newFileName = _buildFileNames.BuildFilename(episodes, series, episodeFile);
var newFile = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path));
//Only rename if existing and new filenames don't match
if (DiskProvider.PathEquals(episodeFile.Path, newFile))
{
Logger.Debug("Skipping file rename, source and destination are the same: {0}", episodeFile.Path);
return null;
}
if (!_diskProvider.FileExists(episodeFile.Path))
{
Logger.Error("Episode file path does not exist, {0}", episodeFile.Path);
return null;
}
_diskProvider.CreateDirectory(new FileInfo(newFile).DirectoryName);
Logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, newFile);
_diskProvider.MoveFile(episodeFile.Path, newFile);
//Wrapped in Try/Catch to prevent this from causing issues with remote NAS boxes, the move worked, which is more important.
try
{
_diskProvider.InheritFolderPermissions(newFile);
}
catch (UnauthorizedAccessException ex)
{
Logger.Debug("Unable to apply folder permissions to: ", newFile);
Logger.TraceException(ex.Message, ex);
}
episodeFile.Path = newFile;
_mediaFileService.Update(episodeFile);
var parseResult = Parser.ParsePath(episodeFile.Path);
parseResult.Series = series;
parseResult.Quality = new QualityModel { Quality = episodeFile.Quality, Proper = episodeFile.Proper };
parseResult.Episodes = episodes;
if (newDownload)
{
_eventAggregator.Publish(new EpisodeDownloadedEvent(parseResult));
}
return episodeFile;
}
public virtual void CleanUpDropFolder(string path) public virtual void CleanUpDropFolder(string path)
{ {
@ -254,7 +191,7 @@ public virtual void CleanUpDropFolder(string path)
{ {
Logger.Trace("[{0}] was imported but not moved, moving it now", file); Logger.Trace("[{0}] was imported but not moved, moving it now", file);
MoveEpisodeFile(episodeFile, true); _moveEpisodeFiles.MoveEpisodeFile(episodeFile, true);
} }
} }

View File

@ -4,6 +4,7 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
@ -17,12 +18,14 @@ public class PostDownloadProvider
private readonly DiskProvider _diskProvider; private readonly DiskProvider _diskProvider;
private readonly DiskScanProvider _diskScanProvider; private readonly DiskScanProvider _diskScanProvider;
private readonly ISeriesRepository _seriesRepository; private readonly ISeriesRepository _seriesRepository;
private readonly IMoveEpisodeFiles _episodeFileMover;
public PostDownloadProvider(DiskProvider diskProvider, DiskScanProvider diskScanProvider, ISeriesRepository seriesRepository) public PostDownloadProvider(DiskProvider diskProvider, DiskScanProvider diskScanProvider, ISeriesRepository seriesRepository, IMoveEpisodeFiles episodeFileMover)
{ {
_diskProvider = diskProvider; _diskProvider = diskProvider;
_diskScanProvider = diskScanProvider; _diskScanProvider = diskScanProvider;
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
_episodeFileMover = episodeFileMover;
} }
public PostDownloadProvider() public PostDownloadProvider()
@ -101,7 +104,7 @@ public virtual void ProcessDownload(DirectoryInfo subfolderInfo)
_diskScanProvider.CleanUpDropFolder(subfolderInfo.FullName); _diskScanProvider.CleanUpDropFolder(subfolderInfo.FullName);
var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName); var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName);
importedFiles.ForEach(file => _diskScanProvider.MoveEpisodeFile(file, true)); importedFiles.ForEach(file => _episodeFileMover.MoveEpisodeFile(file, true));
//Delete the folder only if folder is small enough //Delete the folder only if folder is small enough
if (_diskProvider.GetDirectorySize(subfolderInfo.FullName) < Constants.IgnoreFileSize) if (_diskProvider.GetDirectorySize(subfolderInfo.FullName) < Constants.IgnoreFileSize)
@ -166,7 +169,7 @@ public virtual void ProcessVideoFile(string videoFile)
var episodeFile = _diskScanProvider.ImportFile(series, videoFile); var episodeFile = _diskScanProvider.ImportFile(series, videoFile);
if (episodeFile != null) if (episodeFile != null)
{ {
_diskScanProvider.MoveEpisodeFile(episodeFile, true); _episodeFileMover.MoveEpisodeFile(episodeFile, true);
} }
} }