Relative episode file paths
This commit is contained in:
parent
10fc875715
commit
6671934c0f
|
@ -1,5 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
@ -7,6 +10,7 @@ using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
|
@ -15,16 +19,19 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||||
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public EpisodeModule(ICommandExecutor commandExecutor,
|
public EpisodeModule(ICommandExecutor commandExecutor,
|
||||||
IMediaFileService mediaFileService,
|
IMediaFileService mediaFileService,
|
||||||
IRecycleBinProvider recycleBinProvider,
|
IRecycleBinProvider recycleBinProvider,
|
||||||
|
ISeriesService seriesService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(commandExecutor)
|
: base(commandExecutor)
|
||||||
{
|
{
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
_recycleBinProvider = recycleBinProvider;
|
_recycleBinProvider = recycleBinProvider;
|
||||||
|
_seriesService = seriesService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
GetResourceById = GetEpisodeFile;
|
GetResourceById = GetEpisodeFile;
|
||||||
GetResourceAll = GetEpisodeFiles;
|
GetResourceAll = GetEpisodeFiles;
|
||||||
|
@ -34,7 +41,10 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||||
|
|
||||||
private EpisodeFileResource GetEpisodeFile(int id)
|
private EpisodeFileResource GetEpisodeFile(int id)
|
||||||
{
|
{
|
||||||
return _mediaFileService.Get(id).InjectTo<EpisodeFileResource>();
|
var episodeFile = _mediaFileService.Get(id);
|
||||||
|
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||||
|
|
||||||
|
return MapToResource(series, episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EpisodeFileResource> GetEpisodeFiles()
|
private List<EpisodeFileResource> GetEpisodeFiles()
|
||||||
|
@ -46,7 +56,10 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||||
throw new BadRequestException("seriesId is missing");
|
throw new BadRequestException("seriesId is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToListResource(() => _mediaFileService.GetFilesBySeries(seriesId.Value));
|
var series = _seriesService.GetSeries(seriesId.Value);
|
||||||
|
|
||||||
|
return _mediaFileService.GetFilesBySeries(seriesId.Value)
|
||||||
|
.Select(f => MapToResource(series, f)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetQuality(EpisodeFileResource episodeFileResource)
|
private void SetQuality(EpisodeFileResource episodeFileResource)
|
||||||
|
@ -59,12 +72,22 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||||
private void DeleteEpisodeFile(int id)
|
private void DeleteEpisodeFile(int id)
|
||||||
{
|
{
|
||||||
var episodeFile = _mediaFileService.Get(id);
|
var episodeFile = _mediaFileService.Get(id);
|
||||||
|
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||||
|
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
_logger.Info("Deleting episode file: {0}", episodeFile.Path);
|
_logger.Info("Deleting episode file: {0}", fullPath);
|
||||||
_recycleBinProvider.DeleteFile(episodeFile.Path);
|
_recycleBinProvider.DeleteFile(fullPath);
|
||||||
_mediaFileService.Delete(episodeFile);
|
_mediaFileService.Delete(episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static EpisodeFileResource MapToResource(Core.Tv.Series series, EpisodeFile episodeFile)
|
||||||
|
{
|
||||||
|
var resource = episodeFile.InjectTo<EpisodeFileResource>();
|
||||||
|
resource.Path = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeFileAddedEvent message)
|
public void Handle(EpisodeFileAddedEvent message)
|
||||||
{
|
{
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
|
@ -9,6 +8,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
public Int32 SeriesId { get; set; }
|
public Int32 SeriesId { get; set; }
|
||||||
public Int32 SeasonNumber { get; set; }
|
public Int32 SeasonNumber { get; set; }
|
||||||
|
public String RelativePath { get; set; }
|
||||||
public String Path { get; set; }
|
public String Path { get; set; }
|
||||||
public Int64 Size { get; set; }
|
public Int64 Size { get; set; }
|
||||||
public DateTime DateAdded { get; set; }
|
public DateTime DateAdded { get; set; }
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace NzbDrone.Api.Series
|
||||||
ISceneMappingService sceneMappingService,
|
ISceneMappingService sceneMappingService,
|
||||||
IMapCoversToLocal coverMapper,
|
IMapCoversToLocal coverMapper,
|
||||||
RootFolderValidator rootFolderValidator,
|
RootFolderValidator rootFolderValidator,
|
||||||
PathExistsValidator pathExistsValidator,
|
|
||||||
SeriesPathValidator seriesPathValidator,
|
SeriesPathValidator seriesPathValidator,
|
||||||
SeriesExistsValidator seriesExistsValidator,
|
SeriesExistsValidator seriesExistsValidator,
|
||||||
DroneFactoryValidator droneFactoryValidator,
|
DroneFactoryValidator droneFactoryValidator,
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NLog;
|
||||||
using NzbDrone.Common.EnsureThat;
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Disk
|
namespace NzbDrone.Common.Disk
|
||||||
{
|
{
|
||||||
|
@ -192,7 +193,7 @@ namespace NzbDrone.Common.Disk
|
||||||
Ensure.That(source, () => source).IsValidPath();
|
Ensure.That(source, () => source).IsValidPath();
|
||||||
Ensure.That(target, () => target).IsValidPath();
|
Ensure.That(target, () => target).IsValidPath();
|
||||||
|
|
||||||
Logger.Debug("{0} {1} -> {2}", transferAction, source, target);
|
Logger.ProgressDebug("{0} {1} -> {2}", transferAction, source, target);
|
||||||
|
|
||||||
var sourceFolder = new DirectoryInfo(source);
|
var sourceFolder = new DirectoryInfo(source);
|
||||||
var targetFolder = new DirectoryInfo(target);
|
var targetFolder = new DirectoryInfo(target);
|
||||||
|
@ -211,7 +212,7 @@ namespace NzbDrone.Common.Disk
|
||||||
{
|
{
|
||||||
var destFile = Path.Combine(target, sourceFile.Name);
|
var destFile = Path.Combine(target, sourceFile.Name);
|
||||||
|
|
||||||
Logger.Debug("{0} {1} -> {2}", transferAction, sourceFile, destFile);
|
Logger.ProgressDebug("{0} {1} -> {2}", transferAction, sourceFile, destFile);
|
||||||
|
|
||||||
switch (transferAction)
|
switch (transferAction)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Instrumentation.Extensions
|
namespace NzbDrone.Common.Instrumentation.Extensions
|
||||||
{
|
{
|
||||||
public static class LoggerExtensions
|
public static class LoggerExtensions
|
||||||
{
|
{
|
|
@ -118,6 +118,7 @@
|
||||||
<Compile Include="IEnumerableExtensions.cs" />
|
<Compile Include="IEnumerableExtensions.cs" />
|
||||||
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
|
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
|
||||||
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
||||||
|
<Compile Include="Instrumentation\Extensions\LoggerProgressExtensions.cs" />
|
||||||
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
|
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
|
||||||
<Compile Include="Instrumentation\LogEventExtensions.cs" />
|
<Compile Include="Instrumentation\LogEventExtensions.cs" />
|
||||||
<Compile Include="Instrumentation\LogglyTarget.cs" />
|
<Compile Include="Instrumentation\LogglyTarget.cs" />
|
||||||
|
|
|
@ -86,14 +86,10 @@ namespace NzbDrone.Core.Test.Datastore
|
||||||
|
|
||||||
Db.Insert(episode);
|
Db.Insert(episode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var loadedEpisodeFile = Db.Single<Episode>().EpisodeFile.Value;
|
var loadedEpisodeFile = Db.Single<Episode>().EpisodeFile.Value;
|
||||||
|
|
||||||
loadedEpisodeFile.Should().NotBeNull();
|
loadedEpisodeFile.Should().NotBeNull();
|
||||||
loadedEpisodeFile.ShouldHave().AllProperties().But(c => c.DateAdded).EqualTo(episodeFile);
|
loadedEpisodeFile.ShouldHave().AllProperties().But(c => c.DateAdded).But(c => c.Path).EqualTo(episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -102,9 +102,9 @@ namespace NzbDrone.Core.Test.InstrumentationTests
|
||||||
public void null_string_as_arg_should_not_fail()
|
public void null_string_as_arg_should_not_fail()
|
||||||
{
|
{
|
||||||
var epFile = new EpisodeFile();
|
var epFile = new EpisodeFile();
|
||||||
_logger.Debug("File {0} no longer exists on disk. removing from database.", epFile.Path);
|
_logger.Debug("File {0} no longer exists on disk. removing from database.", epFile.RelativePath);
|
||||||
|
|
||||||
epFile.Path.Should().BeNull();
|
epFile.RelativePath.Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeFileMovingServiceTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
.With(f => f.Path = @"C:\Test\File.avi")
|
.With(f => f.Path = null)
|
||||||
|
.With(f => f.RelativePath = @"Season 1\File.avi")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||||
|
@ -44,7 +45,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeFileMovingServiceTests
|
||||||
|
|
||||||
Mocker.GetMock<IBuildFileNames>()
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
.Setup(s => s.BuildFilePath(It.IsAny<Series>(), It.IsAny<Int32>(), It.IsAny<String>(), It.IsAny<String>()))
|
.Setup(s => s.BuildFilePath(It.IsAny<Series>(), It.IsAny<Int32>(), It.IsAny<String>(), It.IsAny<String>()))
|
||||||
.Returns(@"C:\Test\File Name.avi");
|
.Returns(@"C:\Test\TV\Series\File Name.avi");
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(s => s.FileExists(It.IsAny<String>()))
|
.Setup(s => s.FileExists(It.IsAny<String>()))
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<Series>()))
|
||||||
.Returns(_videoFiles);
|
.Returns(_videoFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<int>()))
|
.Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny<Series>()))
|
||||||
.Returns(_videoFiles);
|
.Returns(_videoFiles);
|
||||||
|
|
||||||
Subject.GetImportDecisions(_videoFiles, _series, false);
|
Subject.GetImportDecisions(_videoFiles, _series, false);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
@ -31,6 +32,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
var series = Builder<Series>.CreateNew()
|
||||||
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
|
.With(s => s.Path = @"C:\Test\TV\30 Rock".AsOsAgnostic())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(5)
|
var episodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
@ -48,7 +50,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
Series = series,
|
Series = series,
|
||||||
Episodes = new List<Episode> {episode},
|
Episodes = new List<Episode> {episode},
|
||||||
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilot.avi".AsOsAgnostic(),
|
Path = Path.Combine(series.Path, "30 Rock - S01E01 - Pilot.avi"),
|
||||||
Quality = new QualityModel(Quality.Bluray720p),
|
Quality = new QualityModel(Quality.Bluray720p),
|
||||||
ParsedEpisodeInfo = new ParsedEpisodeInfo
|
ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@ using NUnit.Framework;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles
|
namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -6,20 +7,24 @@ using NUnit.Framework;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles
|
namespace NzbDrone.Core.Test.MediaFiles.MediaFileServiceTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class MediaFileServiceTest : CoreTest<MediaFileService>
|
public class FilterFixture : CoreTest<MediaFileService>
|
||||||
{
|
{
|
||||||
|
private Series _series;
|
||||||
|
|
||||||
[Test]
|
[SetUp]
|
||||||
[TestCase("Law & Order: Criminal Intent - S10E07 - Icarus [HDTV-720p]",
|
public void Setup()
|
||||||
"Law & Order- Criminal Intent - S10E07 - Icarus [HDTV-720p]")]
|
|
||||||
public void CleanFileName(string name, string expectedName)
|
|
||||||
{
|
{
|
||||||
FileNameBuilder.CleanFileName(name).Should().Be(expectedName);
|
_series = new Series
|
||||||
|
{
|
||||||
|
Id = 10,
|
||||||
|
Path = @"C:\".AsOsAgnostic()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -27,9 +32,9 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\file1.avi".AsOsAgnostic(),
|
"C:\\file1.avi".AsOsAgnostic(),
|
||||||
"c:\\file2.avi".AsOsAgnostic(),
|
"C:\\file2.avi".AsOsAgnostic(),
|
||||||
"c:\\file3.avi".AsOsAgnostic()
|
"C:\\file3.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
|
@ -37,26 +42,25 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(new List<EpisodeFile>());
|
.Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().BeEquivalentTo(files);
|
Subject.FilterExistingFiles(files, _series).Should().BeEquivalentTo(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void filter_should_return_none_if_all_files_exist()
|
public void filter_should_return_none_if_all_files_exist()
|
||||||
{
|
{
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\file1.avi".AsOsAgnostic(),
|
"C:\\file1.avi".AsOsAgnostic(),
|
||||||
"c:\\file2.avi".AsOsAgnostic(),
|
"C:\\file2.avi".AsOsAgnostic(),
|
||||||
"c:\\file3.avi".AsOsAgnostic()
|
"C:\\file3.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
||||||
.Returns(files.Select(f => new EpisodeFile { Path = f }).ToList());
|
.Returns(files.Select(f => new EpisodeFile { RelativePath = Path.GetFileName(f) }).ToList());
|
||||||
|
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().BeEmpty();
|
Subject.FilterExistingFiles(files, _series).Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -64,21 +68,21 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\file1.avi".AsOsAgnostic(),
|
"C:\\file1.avi".AsOsAgnostic(),
|
||||||
"c:\\file2.avi".AsOsAgnostic(),
|
"C:\\file2.avi".AsOsAgnostic(),
|
||||||
"c:\\file3.avi".AsOsAgnostic()
|
"C:\\file3.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
||||||
.Returns(new List<EpisodeFile>
|
.Returns(new List<EpisodeFile>
|
||||||
{
|
{
|
||||||
new EpisodeFile{Path = "c:\\file2.avi".AsOsAgnostic()}
|
new EpisodeFile{ RelativePath = "file2.avi".AsOsAgnostic()}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().HaveCount(2);
|
Subject.FilterExistingFiles(files, _series).Should().HaveCount(2);
|
||||||
Subject.FilterExistingFiles(files, 10).Should().NotContain("c:\\file2.avi".AsOsAgnostic());
|
Subject.FilterExistingFiles(files, _series).Should().NotContain("C:\\file2.avi".AsOsAgnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -88,21 +92,21 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\file1.avi".AsOsAgnostic(),
|
"C:\\file1.avi".AsOsAgnostic(),
|
||||||
"c:\\FILE2.avi".AsOsAgnostic(),
|
"C:\\FILE2.avi".AsOsAgnostic(),
|
||||||
"c:\\file3.avi".AsOsAgnostic()
|
"C:\\file3.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
||||||
.Returns(new List<EpisodeFile>
|
.Returns(new List<EpisodeFile>
|
||||||
{
|
{
|
||||||
new EpisodeFile{Path = "c:\\file2.avi".AsOsAgnostic()}
|
new EpisodeFile{ RelativePath = "file2.avi".AsOsAgnostic()}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().HaveCount(2);
|
Subject.FilterExistingFiles(files, _series).Should().HaveCount(2);
|
||||||
Subject.FilterExistingFiles(files, 10).Should().NotContain("c:\\file2.avi".AsOsAgnostic());
|
Subject.FilterExistingFiles(files, _series).Should().NotContain("C:\\file2.avi".AsOsAgnostic());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -112,19 +116,19 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
|
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\file1.avi".AsOsAgnostic(),
|
"C:\\file1.avi".AsOsAgnostic(),
|
||||||
"c:\\FILE2.avi".AsOsAgnostic(),
|
"C:\\FILE2.avi".AsOsAgnostic(),
|
||||||
"c:\\file3.avi".AsOsAgnostic()
|
"C:\\file3.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
||||||
.Returns(new List<EpisodeFile>
|
.Returns(new List<EpisodeFile>
|
||||||
{
|
{
|
||||||
new EpisodeFile{Path = "c:\\file2.avi".AsOsAgnostic()}
|
new EpisodeFile{ RelativePath = "file2.avi".AsOsAgnostic()}
|
||||||
});
|
});
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().HaveCount(3);
|
Subject.FilterExistingFiles(files, _series).Should().HaveCount(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -132,16 +136,16 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
var files = new List<string>()
|
var files = new List<string>()
|
||||||
{
|
{
|
||||||
"c:\\FILE1.avi".AsOsAgnostic()
|
"C:\\FILE1.avi".AsOsAgnostic()
|
||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileRepository>()
|
Mocker.GetMock<IMediaFileRepository>()
|
||||||
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
.Setup(c => c.GetFilesBySeries(It.IsAny<int>()))
|
||||||
.Returns(new List<EpisodeFile>());
|
.Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
Subject.FilterExistingFiles(files, 10).Should().HaveCount(1);
|
Subject.FilterExistingFiles(files, _series).Should().HaveCount(1);
|
||||||
Subject.FilterExistingFiles(files, 10).Should().NotContain(files.First().ToLower());
|
Subject.FilterExistingFiles(files, _series).Should().NotContain(files.First().ToLower());
|
||||||
Subject.FilterExistingFiles(files, 10).Should().Contain(files.First());
|
Subject.FilterExistingFiles(files, _series).Should().Contain(files.First());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
.Returns(Builder<Series>.CreateNew().Build());
|
.Returns(Builder<Series>.CreateNew().Build());
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(e => e.FileExists(It.Is<String>(c => c != DELETED_PATH)))
|
.Setup(e => e.FileExists(It.Is<String>(c => !c.Contains(DELETED_PATH))))
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
|
@ -68,18 +68,18 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_delete_none_existing_files()
|
public void should_delete_non_existent_files()
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
||||||
.Random(2)
|
.Random(2)
|
||||||
.With(c => c.Path = DELETED_PATH)
|
.With(c => c.RelativePath = DELETED_PATH)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
GivenEpisodeFiles(episodeFiles);
|
GivenEpisodeFiles(episodeFiles);
|
||||||
|
|
||||||
Subject.Execute(new CleanMediaFileDb(0));
|
Subject.Execute(new CleanMediaFileDb(0));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(c => c.Delete(It.Is<EpisodeFile>(e => e.Path == DELETED_PATH), false), Times.Exactly(2));
|
Mocker.GetMock<IMediaFileService>().Verify(c => c.Delete(It.Is<EpisodeFile>(e => e.RelativePath == DELETED_PATH), false), Times.Exactly(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
||||||
.Random(10)
|
.Random(10)
|
||||||
.With(c => c.Path = "ExistingPath")
|
.With(c => c.RelativePath = "ExistingPath")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
GivenEpisodeFiles(episodeFiles);
|
GivenEpisodeFiles(episodeFiles);
|
||||||
|
@ -98,21 +98,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(c => c.Delete(It.IsAny<EpisodeFile>(), false), Times.Exactly(10));
|
Mocker.GetMock<IMediaFileService>().Verify(c => c.Delete(It.IsAny<EpisodeFile>(), false), Times.Exactly(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_delete_files_that_do_not_belong_to_the_series_path()
|
|
||||||
{
|
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
|
||||||
.Random(10)
|
|
||||||
.With(c => c.Path = "ExistingPath")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
GivenEpisodeFiles(episodeFiles);
|
|
||||||
|
|
||||||
Subject.Execute(new CleanMediaFileDb(0));
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(c => c.Delete(It.IsAny<EpisodeFile>(), false), Times.Exactly(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_unlink_episode_when_episodeFile_does_not_exist()
|
public void should_unlink_episode_when_episodeFile_does_not_exist()
|
||||||
{
|
{
|
||||||
|
@ -128,7 +113,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(10)
|
||||||
.Random(10)
|
.Random(10)
|
||||||
.With(c => c.Path = "ExistingPath")
|
.With(c => c.RelativePath = "ExistingPath")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
GivenEpisodeFiles(episodeFiles);
|
GivenEpisodeFiles(episodeFiles);
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
using FizzWare.NBuilder;
|
using System.IO;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Lifecycle;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class UpdateMediaInfoServiceFixture : CoreTest<UpdateMediaInfoService>
|
public class UpdateMediaInfoServiceFixture : CoreTest<UpdateMediaInfoService>
|
||||||
{
|
{
|
||||||
|
private Series _series;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_series = new Series
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Path = @"C:\series".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenFileExists()
|
private void GivenFileExists()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
@ -44,7 +54,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(3)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(3)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
.With(v => v.MediaInfo = new MediaInfoModel())
|
.With(v => v.MediaInfo = new MediaInfoModel())
|
||||||
.BuildList();
|
.BuildList();
|
||||||
|
@ -56,10 +66,10 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
GivenFileExists();
|
GivenFileExists();
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
Subject.Handle(new SeriesScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Exactly(2));
|
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(2));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(2));
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(2));
|
||||||
|
@ -70,7 +80,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
@ -79,10 +89,10 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
|
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
Subject.Handle(new SeriesScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Never());
|
.Verify(v => v.GetMediaInfo("media.mkv"), Times.Never());
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Never());
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Never());
|
||||||
|
@ -93,9 +103,9 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.Path = @"C:\series\media.mkv".AsOsAgnostic())
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
.With(v => v.Path = @"C:\series\media2.mkv".AsOsAgnostic())
|
.With(v => v.RelativePath = "media2.mkv")
|
||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
|
@ -104,12 +114,12 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
||||||
|
|
||||||
GivenFileExists();
|
GivenFileExists();
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
GivenFailedScan(@"C:\series\media2.mkv".AsOsAgnostic());
|
GivenFailedScan(Path.Combine(_series.Path, "media2.mkv"));
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(new Tv.Series { Id = 1 }));
|
Subject.Handle(new SeriesScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(@"C:\series\media.mkv".AsOsAgnostic()), Times.Exactly(1));
|
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(1));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(1));
|
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(1));
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles
|
namespace NzbDrone.Core.Test.MediaFiles
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,10 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_localEpisode = new LocalEpisode();
|
_localEpisode = new LocalEpisode();
|
||||||
|
_localEpisode.Series = new Series
|
||||||
|
{
|
||||||
|
Path = @"C:\Test\TV\Series".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
_episodeFile = Builder<EpisodeFile>
|
_episodeFile = Builder<EpisodeFile>
|
||||||
.CreateNew()
|
.CreateNew()
|
||||||
|
@ -42,7 +47,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
new EpisodeFile
|
new EpisodeFile
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
|
RelativePath = @"Season 01\30.rock.s01e01.avi",
|
||||||
}))
|
}))
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -57,7 +62,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
new EpisodeFile
|
new EpisodeFile
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
|
RelativePath = @"Season 01\30.rock.s01e01.avi",
|
||||||
}))
|
}))
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -71,14 +76,14 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
new EpisodeFile
|
new EpisodeFile
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e01.avi",
|
RelativePath = @"Season 01\30.rock.s01e01.avi",
|
||||||
}))
|
}))
|
||||||
.TheNext(1)
|
.TheNext(1)
|
||||||
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
|
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
|
||||||
new EpisodeFile
|
new EpisodeFile
|
||||||
{
|
{
|
||||||
Id = 2,
|
Id = 2,
|
||||||
Path = @"C:\Test\30 Rock\Season 01\30.rock.s01e02.avi",
|
RelativePath = @"Season 01\30.rock.s01e02.avi",
|
||||||
}))
|
}))
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
@ -188,7 +188,8 @@
|
||||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" />
|
<Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" />
|
<Compile Include="MediaFiles\ImportApprovedEpisodesFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
<Compile Include="MediaFiles\MediaFileRepositoryFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileServiceTest.cs" />
|
<Compile Include="OrganizerTests\CleanFixture.cs" />
|
||||||
|
<Compile Include="MediaFiles\MediaFileServiceTests\FilterFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileTableCleanupServiceFixture.cs" />
|
<Compile Include="MediaFiles\MediaFileTableCleanupServiceFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\UpdateMediaInfoServiceFixture.cs" />
|
<Compile Include="MediaFiles\MediaInfo\UpdateMediaInfoServiceFixture.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReaderFixture.cs" />
|
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReaderFixture.cs" />
|
||||||
|
@ -262,6 +263,7 @@
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithoutFilesFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithoutFilesFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
|
||||||
|
<Compile Include="TvTests\MoveSeriesServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\RefreshSeriesServiceFixture.cs" />
|
<Compile Include="TvTests\RefreshSeriesServiceFixture.cs" />
|
||||||
<Compile Include="TvTests\SeriesRepositoryTests\SeriesRepositoryFixture.cs" />
|
<Compile Include="TvTests\SeriesRepositoryTests\SeriesRepositoryFixture.cs" />
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CleanFixture : CoreTest
|
||||||
|
{
|
||||||
|
[TestCase("Law & Order: Criminal Intent - S10E07 - Icarus [HDTV-720p]",
|
||||||
|
"Law & Order- Criminal Intent - S10E07 - Icarus [HDTV-720p]")]
|
||||||
|
public void CleanFileName(string name, string expectedName)
|
||||||
|
{
|
||||||
|
FileNameBuilder.CleanFileName(name).Should().Be(expectedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,8 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
_episodeFile.Quality.Proper = true;
|
_episodeFile.Quality.Proper = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_replace_Series_space_Title()
|
public void should_replace_Series_space_Title()
|
||||||
{
|
{
|
||||||
|
@ -227,10 +229,10 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
public void use_file_name_when_sceneName_is_null()
|
public void use_file_name_when_sceneName_is_null()
|
||||||
{
|
{
|
||||||
_namingConfig.RenameEpisodes = false;
|
_namingConfig.RenameEpisodes = false;
|
||||||
_episodeFile.Path = @"C:\Test\TV\30 Rock - S01E01 - Test";
|
_episodeFile.RelativePath = "30 Rock - S01E01 - Test";
|
||||||
|
|
||||||
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
||||||
.Should().Be(Path.GetFileNameWithoutExtension(_episodeFile.Path));
|
.Should().Be(Path.GetFileNameWithoutExtension(_episodeFile.RelativePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -238,7 +240,7 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
{
|
{
|
||||||
_namingConfig.RenameEpisodes = false;
|
_namingConfig.RenameEpisodes = false;
|
||||||
_episodeFile.SceneName = "30.Rock.S01E01.xvid-LOL";
|
_episodeFile.SceneName = "30.Rock.S01E01.xvid-LOL";
|
||||||
_episodeFile.Path = @"C:\Test\TV\30 Rock - S01E01 - Test";
|
_episodeFile.RelativePath = "30 Rock - S01E01 - Test";
|
||||||
|
|
||||||
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
||||||
.Should().Be("30.Rock.S01E01.xvid-LOL");
|
.Should().Be("30.Rock.S01E01.xvid-LOL");
|
||||||
|
@ -378,7 +380,7 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
_namingConfig.StandardEpisodeFormat = "{Series Title} - {Original Title}";
|
_namingConfig.StandardEpisodeFormat = "{Series Title} - {Original Title}";
|
||||||
|
|
||||||
_episodeFile.SceneName = "30.Rock.S01E01.xvid-LOL";
|
_episodeFile.SceneName = "30.Rock.S01E01.xvid-LOL";
|
||||||
_episodeFile.Path = @"C:\Test\TV\30 Rock - S01E01 - Test";
|
_episodeFile.RelativePath = "30 Rock - S01E01 - Test";
|
||||||
|
|
||||||
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
||||||
.Should().Be("30 Rock - 30.Rock.S01E01.xvid-LOL");
|
.Should().Be("30 Rock - 30.Rock.S01E01.xvid-LOL");
|
||||||
|
|
|
@ -67,9 +67,9 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
new QualitiesBelowCutoff(profile.Id, new[] {Quality.SDTV.Id})
|
new QualitiesBelowCutoff(profile.Id, new[] {Quality.SDTV.Id})
|
||||||
};
|
};
|
||||||
|
|
||||||
var qualityMet = new EpisodeFile { Path = "a", Quality = new QualityModel { Quality = Quality.WEBDL480p } };
|
var qualityMet = new EpisodeFile { RelativePath = "a", Quality = new QualityModel { Quality = Quality.WEBDL480p } };
|
||||||
var qualityUnmet = new EpisodeFile { Path = "b", Quality = new QualityModel { Quality = Quality.SDTV } };
|
var qualityUnmet = new EpisodeFile { RelativePath = "b", Quality = new QualityModel { Quality = Quality.SDTV } };
|
||||||
var qualityRawHD = new EpisodeFile { Path = "c", Quality = new QualityModel { Quality = Quality.RAWHD } };
|
var qualityRawHD = new EpisodeFile { RelativePath = "c", Quality = new QualityModel { Quality = Quality.RAWHD } };
|
||||||
|
|
||||||
MediaFileRepository fileRepository = Mocker.Resolve<MediaFileRepository>();
|
MediaFileRepository fileRepository = Mocker.Resolve<MediaFileRepository>();
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
public void should_only_contain_episodes_for_the_given_series()
|
public void should_only_contain_episodes_for_the_given_series()
|
||||||
{
|
{
|
||||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
.With(f => f.Path = "another path")
|
.With(f => f.RelativePath = "another path")
|
||||||
.With(c => c.Quality = new QualityModel())
|
.With(c => c.Quality = new QualityModel())
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Tv.Commands;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.TvTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class MoveSeriesServiceFixture : CoreTest<MoveSeriesService>
|
||||||
|
{
|
||||||
|
private Series _series;
|
||||||
|
private MoveSeriesCommand _command;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_series = Builder<Series>
|
||||||
|
.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_command = new MoveSeriesCommand
|
||||||
|
{
|
||||||
|
SeriesId = 1,
|
||||||
|
SourcePath = @"C:\Test\TV\Series".AsOsAgnostic(),
|
||||||
|
DestinationPath = @"C:\Test\TV2\Series".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Setup(s => s.GetSeries(It.IsAny<Int32>()))
|
||||||
|
.Returns(_series);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenFailedMove()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(s => s.MoveFolder(It.IsAny<String>(), It.IsAny<String>()))
|
||||||
|
.Throws<IOException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_log_error_when_move_throws_an_exception()
|
||||||
|
{
|
||||||
|
GivenFailedMove();
|
||||||
|
|
||||||
|
Assert.Throws<IOException>(() => Subject.Execute(_command));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_no_update_series_path_on_error()
|
||||||
|
{
|
||||||
|
GivenFailedMove();
|
||||||
|
|
||||||
|
Assert.Throws<IOException>(() => Subject.Execute(_command));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_build_new_path_when_root_folder_is_provided()
|
||||||
|
{
|
||||||
|
_command.DestinationPath = null;
|
||||||
|
_command.DestinationRootFolder = @"C:\Test\TV3".AsOsAgnostic();
|
||||||
|
|
||||||
|
var expectedPath = @"C:\Test\TV3\Series".AsOsAgnostic();
|
||||||
|
|
||||||
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
|
.Setup(s => s.GetSeriesFolder(It.IsAny<Series>(), null))
|
||||||
|
.Returns("Series");
|
||||||
|
|
||||||
|
Subject.Execute(_command);
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Path == expectedPath)), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_destination_path_if_destination_root_folder_is_blank()
|
||||||
|
{
|
||||||
|
Subject.Execute(_command);
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Path == _command.DestinationPath)), Times.Once());
|
||||||
|
|
||||||
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
|
.Verify(v => v.GetSeriesFolder(It.IsAny<Series>(), null), Times.Never());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,8 @@ using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Backup
|
namespace NzbDrone.Core.Backup
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System.Data;
|
||||||
|
using System.IO;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(57)]
|
||||||
|
public class convert_episode_file_path_to_relative : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Create.Column("RelativePath").OnTable("EpisodeFiles").AsString().Nullable();
|
||||||
|
|
||||||
|
//TODO: Add unique contraint for series ID and Relative Path
|
||||||
|
//TODO: Warn if multiple series share the same path
|
||||||
|
|
||||||
|
Execute.WithConnection(UpdateRelativePaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRelativePaths(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
getSeriesCmd.Transaction = tran;
|
||||||
|
getSeriesCmd.CommandText = @"SELECT Id, Path FROM Series";
|
||||||
|
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (seriesReader.Read())
|
||||||
|
{
|
||||||
|
var seriesId = seriesReader.GetInt32(0);
|
||||||
|
var seriesPath = seriesReader.GetString(1) + Path.DirectorySeparatorChar;
|
||||||
|
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "UPDATE EpisodeFiles SET RelativePath = REPLACE(Path, ?, '') WHERE SeriesId = ?";
|
||||||
|
updateCmd.AddParameter(seriesPath);
|
||||||
|
updateCmd.AddParameter(seriesId);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(58)]
|
||||||
|
public class drop_episode_file_path : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
SqLiteAlter.DropColumns("EpisodeFiles", new [] { "Path" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,241 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.SQLite;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
|
||||||
{
|
|
||||||
public interface ISQLiteMigrationHelper
|
|
||||||
{
|
|
||||||
Dictionary<String, SQLiteMigrationHelper.SQLiteColumn> GetColumns(string tableName);
|
|
||||||
void CreateTable(string tableName, IEnumerable<SQLiteMigrationHelper.SQLiteColumn> values, IEnumerable<SQLiteMigrationHelper.SQLiteIndex> indexes);
|
|
||||||
void CopyData(string sourceTable, string destinationTable, IEnumerable<SQLiteMigrationHelper.SQLiteColumn> columns);
|
|
||||||
void DropTable(string tableName);
|
|
||||||
void RenameTable(string tableName, string newName);
|
|
||||||
List<T> GetDuplicates<T>(string tableName, string columnName);
|
|
||||||
SQLiteTransaction BeginTransaction();
|
|
||||||
List<SQLiteMigrationHelper.SQLiteIndex> GetIndexes(string tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SQLiteMigrationHelper : ISQLiteMigrationHelper
|
|
||||||
{
|
|
||||||
private readonly SQLiteConnection _connection;
|
|
||||||
|
|
||||||
private static readonly Regex SchemaRegex = new Regex(@"['\""\[](?<name>\w+)['\""\]]\s(?<schema>[\w-\s]+)",
|
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
|
||||||
|
|
||||||
private static readonly Regex IndexRegex = new Regex(@"\(""(?<col>.*)""\s(?<direction>ASC|DESC)\)$",
|
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
|
||||||
|
|
||||||
public SQLiteMigrationHelper(IConnectionStringFactory connectionStringFactory, Logger logger)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_connection = new SQLiteConnection(connectionStringFactory.MainDbConnectionString);
|
|
||||||
_connection.Open();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.ErrorException("Couldn't open database " + connectionStringFactory.MainDbConnectionString, e);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetOriginalSql(string tableName)
|
|
||||||
{
|
|
||||||
var command =
|
|
||||||
new SQLiteCommand(string.Format("SELECT sql FROM sqlite_master WHERE type='table' AND name ='{0}'",
|
|
||||||
tableName));
|
|
||||||
|
|
||||||
command.Connection = _connection;
|
|
||||||
|
|
||||||
return (string)command.ExecuteScalar();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<String, SQLiteColumn> GetColumns(string tableName)
|
|
||||||
{
|
|
||||||
var originalSql = GetOriginalSql(tableName);
|
|
||||||
|
|
||||||
var matches = SchemaRegex.Matches(originalSql);
|
|
||||||
|
|
||||||
return matches.Cast<Match>().ToDictionary(
|
|
||||||
match => match.Groups["name"].Value.Trim(),
|
|
||||||
match => new SQLiteColumn
|
|
||||||
{
|
|
||||||
Name = match.Groups["name"].Value.Trim(),
|
|
||||||
Schema = match.Groups["schema"].Value.Trim()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static IEnumerable<T> ReadArray<T>(SQLiteDataReader reader)
|
|
||||||
{
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
yield return (T)Convert.ChangeType(reader[0], typeof(T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SQLiteIndex> GetIndexes(string tableName)
|
|
||||||
{
|
|
||||||
var command = new SQLiteCommand(string.Format("SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name ='{0}'", tableName));
|
|
||||||
command.Connection = _connection;
|
|
||||||
|
|
||||||
var reader = command.ExecuteReader();
|
|
||||||
var sqls = ReadArray<string>(reader).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
var indexes = new List<SQLiteIndex>();
|
|
||||||
|
|
||||||
foreach (var indexSql in sqls)
|
|
||||||
{
|
|
||||||
var newIndex = new SQLiteIndex();
|
|
||||||
var matches = IndexRegex.Match(indexSql);
|
|
||||||
|
|
||||||
newIndex.Column = matches.Groups["col"].Value;
|
|
||||||
newIndex.Unique = indexSql.Contains("UNIQUE");
|
|
||||||
newIndex.Table = tableName;
|
|
||||||
|
|
||||||
indexes.Add(newIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateTable(string tableName, IEnumerable<SQLiteColumn> values, IEnumerable<SQLiteIndex> indexes)
|
|
||||||
{
|
|
||||||
var columns = String.Join(",", values.Select(c => c.ToString()));
|
|
||||||
|
|
||||||
ExecuteNonQuery("CREATE TABLE [{0}] ({1})", tableName, columns);
|
|
||||||
|
|
||||||
foreach (var index in indexes)
|
|
||||||
{
|
|
||||||
ExecuteNonQuery("DROP INDEX {0}", index.IndexName);
|
|
||||||
ExecuteNonQuery(index.CreateSql(tableName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyData(string sourceTable, string destinationTable, IEnumerable<SQLiteColumn> columns)
|
|
||||||
{
|
|
||||||
var originalCount = GetRowCount(sourceTable);
|
|
||||||
|
|
||||||
var columnsToTransfer = String.Join(",", columns.Select(c => c.Name));
|
|
||||||
|
|
||||||
var transferCommand = BuildCommand("INSERT INTO {0} SELECT {1} FROM {2};", destinationTable, columnsToTransfer, sourceTable);
|
|
||||||
|
|
||||||
transferCommand.ExecuteNonQuery();
|
|
||||||
|
|
||||||
var transferredRows = GetRowCount(destinationTable);
|
|
||||||
|
|
||||||
|
|
||||||
if (transferredRows != originalCount)
|
|
||||||
{
|
|
||||||
throw new ApplicationException(string.Format("Expected {0} rows to be copied from [{1}] to [{2}]. But only copied {3}", originalCount, sourceTable, destinationTable, transferredRows));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void DropTable(string tableName)
|
|
||||||
{
|
|
||||||
var dropCommand = BuildCommand("DROP TABLE {0};", tableName);
|
|
||||||
dropCommand.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void RenameTable(string tableName, string newName)
|
|
||||||
{
|
|
||||||
var renameCommand = BuildCommand("ALTER TABLE {0} RENAME TO {1};", tableName, newName);
|
|
||||||
renameCommand.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<int,T> GetDuplicates<T>(string tableName, string columnName)
|
|
||||||
{
|
|
||||||
var dupCommand = BuildCommand("select id, {0} from {1}", columnName, tableName);
|
|
||||||
|
|
||||||
var result = new Dictionary<int, T>();
|
|
||||||
using (var reader = dupCommand.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ReadArray<T>().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetRowCount(string tableName)
|
|
||||||
{
|
|
||||||
var countCommand = BuildCommand("SELECT COUNT(*) FROM {0};", tableName);
|
|
||||||
return Convert.ToInt32(countCommand.ExecuteScalar());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public SQLiteTransaction BeginTransaction()
|
|
||||||
{
|
|
||||||
return _connection.BeginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SQLiteCommand BuildCommand(string format, params string[] args)
|
|
||||||
{
|
|
||||||
var command = new SQLiteCommand(string.Format(format, args));
|
|
||||||
command.Connection = _connection;
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void ExecuteNonQuery(string command, params string[] args)
|
|
||||||
{
|
|
||||||
var sqLiteCommand = new SQLiteCommand(string.Format(command, args))
|
|
||||||
{
|
|
||||||
Connection = _connection
|
|
||||||
};
|
|
||||||
|
|
||||||
sqLiteCommand.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class SQLiteColumn
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Schema { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return string.Format("[{0}] {1}", Name, Schema);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SQLiteIndex
|
|
||||||
{
|
|
||||||
public string Column { get; set; }
|
|
||||||
public string Table { get; set; }
|
|
||||||
public bool Unique { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return string.Format("[{0}] Unique: {1}", Column, Unique);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string IndexName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return string.Format("IX_{0}_{1}", Table, Column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string CreateSql(string tableName)
|
|
||||||
{
|
|
||||||
return string.Format(@"CREATE UNIQUE INDEX ""{2}"" ON ""{0}"" (""{1}"" ASC)", tableName, Column, IndexName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -56,16 +56,17 @@ namespace NzbDrone.Core.Datastore
|
||||||
.Relationship()
|
.Relationship()
|
||||||
.HasOne(s => s.Profile, s => s.ProfileId);
|
.HasOne(s => s.Profile, s => s.ProfileId);
|
||||||
|
|
||||||
|
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles")
|
||||||
|
.Ignore(f => f.Path)
|
||||||
|
.Relationships.AutoMapICollectionOrComplexProperties();
|
||||||
|
|
||||||
Mapper.Entity<Episode>().RegisterModel("Episodes")
|
Mapper.Entity<Episode>().RegisterModel("Episodes")
|
||||||
.Ignore(e => e.SeriesTitle)
|
.Ignore(e => e.SeriesTitle)
|
||||||
.Ignore(e => e.Series)
|
.Ignore(e => e.Series)
|
||||||
.Ignore(e => e.HasFile)
|
.Ignore(e => e.HasFile)
|
||||||
.Relationship()
|
.Relationship()
|
||||||
.HasOne(episode => episode.EpisodeFile, episode => episode.EpisodeFileId);
|
.HasOne(episode => episode.EpisodeFile, episode => episode.EpisodeFileId);
|
||||||
|
|
||||||
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles")
|
|
||||||
.Relationships.AutoMapICollectionOrComplexProperties();
|
|
||||||
|
|
||||||
Mapper.Entity<Profile>().RegisterModel("Profiles");
|
Mapper.Entity<Profile>().RegisterModel("Profiles");
|
||||||
Mapper.Entity<QualityDefinition>().RegisterModel("QualityDefinitions");
|
Mapper.Entity<QualityDefinition>().RegisterModel("QualityDefinitions");
|
||||||
Mapper.Entity<Log>().RegisterModel("Logs");
|
Mapper.Entity<Log>().RegisterModel("Logs");
|
||||||
|
|
|
@ -3,12 +3,11 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine
|
namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnsureThat;
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
@ -169,7 +170,7 @@ namespace NzbDrone.Core.History
|
||||||
//Won't have a value since we publish this event before saving to DB.
|
//Won't have a value since we publish this event before saving to DB.
|
||||||
//history.Data.Add("FileId", message.ImportedEpisode.Id.ToString());
|
//history.Data.Add("FileId", message.ImportedEpisode.Id.ToString());
|
||||||
history.Data.Add("DroppedPath", message.EpisodeInfo.Path);
|
history.Data.Add("DroppedPath", message.EpisodeInfo.Path);
|
||||||
history.Data.Add("ImportedPath", message.ImportedEpisode.Path);
|
history.Data.Add("ImportedPath", Path.Combine(message.EpisodeInfo.Series.Path, message.ImportedEpisode.RelativePath));
|
||||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||||
history.Data.Add("DownloadClientId", message.DownloadClientId);
|
history.Data.Add("DownloadClientId", message.DownloadClientId);
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Queue;
|
using NzbDrone.Core.Queue;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
|
@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
namespace NzbDrone.Core.IndexerSearch
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Pending;
|
using NzbDrone.Core.Download.Pending;
|
||||||
using NzbDrone.Core.IndexerSearch;
|
using NzbDrone.Core.IndexerSearch;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.MediaFiles.Commands;
|
using NzbDrone.Core.MediaFiles.Commands;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
|
|
@ -8,20 +8,26 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
public class EpisodeFile : ModelBase
|
public class EpisodeFile : ModelBase
|
||||||
{
|
{
|
||||||
public int SeriesId { get; set; }
|
public Int32 SeriesId { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public Int32 SeasonNumber { get; set; }
|
||||||
public string Path { get; set; }
|
public String RelativePath { get; set; }
|
||||||
public long Size { get; set; }
|
public String Path { get; set; }
|
||||||
|
public Int64 Size { get; set; }
|
||||||
public DateTime DateAdded { get; set; }
|
public DateTime DateAdded { get; set; }
|
||||||
public string SceneName { get; set; }
|
public String SceneName { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public String ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MediaInfoModel MediaInfo { get; set; }
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
public LazyList<Episode> Episodes { get; set; }
|
public LazyList<Episode> Episodes { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override String ToString()
|
||||||
{
|
{
|
||||||
return String.Format("[{0}] {1}", Id, Path);
|
return String.Format("[{0}] {1}", Id, RelativePath);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// public String Path(Series series)
|
||||||
|
// {
|
||||||
|
// return System.IO.Path.Combine(series.Path, RelativePath);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,7 +50,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
var episodes = _episodeService.GetEpisodesByFileId(episodeFile.Id);
|
var episodes = _episodeService.GetEpisodesByFileId(episodeFile.Id);
|
||||||
var newFileName = _buildFileNames.BuildFileName(episodes, series, episodeFile);
|
var newFileName = _buildFileNames.BuildFileName(episodes, series, episodeFile);
|
||||||
var filePath = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path));
|
var filePath = _buildFileNames.BuildFilePath(series, episodes.First().SeasonNumber, newFileName, Path.GetExtension(episodeFile.RelativePath));
|
||||||
|
|
||||||
_logger.Debug("Renaming episode file: {0} to {1}", episodeFile, filePath);
|
_logger.Debug("Renaming episode file: {0} to {1}", episodeFile, filePath);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
||||||
{
|
{
|
||||||
var newFileName = _buildFileNames.BuildFileName(localEpisode.Episodes, localEpisode.Series, episodeFile);
|
var newFileName = _buildFileNames.BuildFileName(localEpisode.Episodes, localEpisode.Series, episodeFile);
|
||||||
var filePath = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path));
|
var filePath = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(localEpisode.Path));
|
||||||
|
|
||||||
_logger.Debug("Moving episode file: {0} to {1}", episodeFile, filePath);
|
_logger.Debug("Moving episode file: {0} to {1}", episodeFile, filePath);
|
||||||
|
|
||||||
|
@ -70,27 +70,29 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public EpisodeFile CopyEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
public EpisodeFile CopyEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode)
|
||||||
{
|
{
|
||||||
var newFileName = _buildFileNames.BuildFileName(localEpisode.Episodes, localEpisode.Series, episodeFile);
|
var newFileName = _buildFileNames.BuildFileName(localEpisode.Episodes, localEpisode.Series, episodeFile);
|
||||||
var filePath = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path));
|
var filePath = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(localEpisode.Path));
|
||||||
|
|
||||||
_logger.Debug("Copying episode file: {0} to {1}", episodeFile, filePath);
|
_logger.Debug("Copying episode file: {0} to {1}", episodeFile, filePath);
|
||||||
|
|
||||||
return TransferFile(episodeFile, localEpisode.Series, localEpisode.Episodes, filePath, true);
|
return TransferFile(episodeFile, localEpisode.Series, localEpisode.Episodes, filePath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EpisodeFile TransferFile(EpisodeFile episodeFile, Series series, List<Episode> episodes, string destinationFilename, bool copyOnly)
|
private EpisodeFile TransferFile(EpisodeFile episodeFile, Series series, List<Episode> episodes, String destinationFilename, Boolean copyOnly)
|
||||||
{
|
{
|
||||||
Ensure.That(episodeFile, () => episodeFile).IsNotNull();
|
Ensure.That(episodeFile, () => episodeFile).IsNotNull();
|
||||||
Ensure.That(series,() => series).IsNotNull();
|
Ensure.That(series,() => series).IsNotNull();
|
||||||
Ensure.That(destinationFilename, () => destinationFilename).IsValidPath();
|
Ensure.That(destinationFilename, () => destinationFilename).IsValidPath();
|
||||||
|
|
||||||
if (!_diskProvider.FileExists(episodeFile.Path))
|
var episodeFilePath = episodeFile.Path ?? Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
|
if (!_diskProvider.FileExists(episodeFilePath))
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException("Episode file path does not exist", episodeFile.Path);
|
throw new FileNotFoundException("Episode file path does not exist", episodeFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeFile.Path.PathEquals(destinationFilename))
|
if (episodeFilePath.PathEquals(destinationFilename))
|
||||||
{
|
{
|
||||||
throw new SameFilenameException("File not moved, source and destination are the same", episodeFile.Path);
|
throw new SameFilenameException("File not moved, source and destination are the same", episodeFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
var directoryName = new FileInfo(destinationFilename).DirectoryName;
|
var directoryName = new FileInfo(destinationFilename).DirectoryName;
|
||||||
|
@ -116,15 +118,16 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
if (copyOnly)
|
if (copyOnly)
|
||||||
{
|
{
|
||||||
_logger.Debug("Copying [{0}] > [{1}]", episodeFile.Path, destinationFilename);
|
_logger.Debug("Copying [{0}] > [{1}]", episodeFilePath, destinationFilename);
|
||||||
_diskProvider.CopyFile(episodeFile.Path, destinationFilename);
|
_diskProvider.CopyFile(episodeFilePath, destinationFilename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, destinationFilename);
|
_logger.Debug("Moving [{0}] > [{1}]", episodeFilePath, destinationFilename);
|
||||||
_diskProvider.MoveFile(episodeFile.Path, destinationFilename);
|
_diskProvider.MoveFile(episodeFilePath, destinationFilename);
|
||||||
}
|
}
|
||||||
episodeFile.Path = destinationFilename;
|
|
||||||
|
episodeFile.RelativePath = series.Path.GetRelativePath(destinationFilename);
|
||||||
|
|
||||||
_updateEpisodeFileService.ChangeFileDateForFile(episodeFile, series, episodes);
|
_updateEpisodeFileService.ChangeFileDateForFile(episodeFile, series, episodes);
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,11 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
oldFiles = moveResult.OldFiles;
|
oldFiles = moveResult.OldFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
episodeFile.RelativePath = localEpisode.Series.Path.GetRelativePath(episodeFile.Path);
|
||||||
|
}
|
||||||
|
|
||||||
_mediaFileService.Add(episodeFile);
|
_mediaFileService.Add(episodeFile);
|
||||||
imported.Add(importDecision);
|
imported.Add(importDecision);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, bool sceneSource, QualityModel quality = null)
|
||||||
{
|
{
|
||||||
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series.Id);
|
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series);
|
||||||
|
|
||||||
_logger.Debug("Analyzing {0}/{1} files.", newFiles.Count, videoFiles.Count());
|
_logger.Debug("Analyzing {0}/{1} files.", newFiles.Count, videoFiles.Count());
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
|
||||||
|
@ -16,7 +18,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
List<EpisodeFile> GetFilesBySeries(int seriesId);
|
||||||
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
||||||
List<EpisodeFile> GetFilesWithoutMediaInfo();
|
List<EpisodeFile> GetFilesWithoutMediaInfo();
|
||||||
List<string> FilterExistingFiles(List<string> files, int seriesId);
|
List<string> FilterExistingFiles(List<string> files, Series series);
|
||||||
EpisodeFile Get(int id);
|
EpisodeFile Get(int id);
|
||||||
List<EpisodeFile> Get(IEnumerable<int> ids);
|
List<EpisodeFile> Get(IEnumerable<int> ids);
|
||||||
}
|
}
|
||||||
|
@ -68,9 +70,9 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return _mediaFileRepository.GetFilesWithoutMediaInfo();
|
return _mediaFileRepository.GetFilesWithoutMediaInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> FilterExistingFiles(List<string> files, int seriesId)
|
public List<string> FilterExistingFiles(List<string> files, Series series)
|
||||||
{
|
{
|
||||||
var seriesFiles = GetFilesBySeries(seriesId).Select(f => f.Path).ToList();
|
var seriesFiles = GetFilesBySeries(series.Id).Select(f => Path.Combine(series.Path, f.RelativePath)).ToList();
|
||||||
|
|
||||||
if (!seriesFiles.Any()) return files;
|
if (!seriesFiles.Any()) return files;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
@ -39,25 +40,20 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
foreach (var episodeFile in seriesFile)
|
foreach (var episodeFile in seriesFile)
|
||||||
{
|
{
|
||||||
|
var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_diskProvider.FileExists(episodeFile.Path))
|
if (!_diskProvider.FileExists(episodeFilePath))
|
||||||
{
|
{
|
||||||
_logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFile.Path);
|
_logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFilePath);
|
||||||
_mediaFileService.Delete(episodeFile);
|
_mediaFileService.Delete(episodeFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!series.Path.IsParentPath(episodeFile.Path))
|
|
||||||
{
|
|
||||||
_logger.Debug("File [{0}] does not belong to this series, removing from db", episodeFile.Path);
|
|
||||||
_mediaFileService.Delete(episodeFile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!episodes.Any(e => e.EpisodeFileId == episodeFile.Id))
|
if (!episodes.Any(e => e.EpisodeFileId == episodeFile.Id))
|
||||||
{
|
{
|
||||||
_logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFile.Path);
|
_logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFilePath);
|
||||||
_mediaFileService.Delete(episodeFile);
|
_mediaFileService.Delete(episodeFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using NLog;
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Lifecycle;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
{
|
{
|
||||||
|
@ -29,11 +27,11 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMediaInfo(List<EpisodeFile> mediaFiles)
|
private void UpdateMediaInfo(Series series, List<EpisodeFile> mediaFiles)
|
||||||
{
|
{
|
||||||
foreach (var mediaFile in mediaFiles)
|
foreach (var mediaFile in mediaFiles)
|
||||||
{
|
{
|
||||||
var path = mediaFile.Path;
|
var path = Path.Combine(series.Path, mediaFile.RelativePath);
|
||||||
|
|
||||||
if (!_diskProvider.FileExists(path))
|
if (!_diskProvider.FileExists(path))
|
||||||
{
|
{
|
||||||
|
@ -57,7 +55,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
.Where(c => c.MediaInfo == null)
|
.Where(c => c.MediaInfo == null)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
UpdateMediaInfo(mediaFiles);
|
UpdateMediaInfo(message.Series, mediaFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.MediaFiles.Commands;
|
using NzbDrone.Core.MediaFiles.Commands;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
@ -77,18 +77,19 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
{
|
{
|
||||||
var file = f;
|
var file = f;
|
||||||
var episodesInFile = episodes.Where(e => e.EpisodeFileId == file.Id).ToList();
|
var episodesInFile = episodes.Where(e => e.EpisodeFileId == file.Id).ToList();
|
||||||
|
var episodeFilePath = Path.Combine(series.Path, file.RelativePath);
|
||||||
|
|
||||||
if (!episodesInFile.Any())
|
if (!episodesInFile.Any())
|
||||||
{
|
{
|
||||||
_logger.Warn("File ({0}) is not linked to any episodes", file.Path);
|
_logger.Warn("File ({0}) is not linked to any episodes", episodeFilePath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var seasonNumber = episodesInFile.First().SeasonNumber;
|
var seasonNumber = episodesInFile.First().SeasonNumber;
|
||||||
var newName = _filenameBuilder.BuildFileName(episodesInFile, series, file);
|
var newName = _filenameBuilder.BuildFileName(episodesInFile, series, file);
|
||||||
var newPath = _filenameBuilder.BuildFilePath(series, seasonNumber, newName, Path.GetExtension(file.Path));
|
var newPath = _filenameBuilder.BuildFilePath(series, seasonNumber, newName, Path.GetExtension(episodeFilePath));
|
||||||
|
|
||||||
if (!file.Path.PathEquals(newPath))
|
if (!episodeFilePath.PathEquals(newPath))
|
||||||
{
|
{
|
||||||
yield return new RenameEpisodeFilePreview
|
yield return new RenameEpisodeFilePreview
|
||||||
{
|
{
|
||||||
|
@ -96,7 +97,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
SeasonNumber = seasonNumber,
|
SeasonNumber = seasonNumber,
|
||||||
EpisodeNumbers = episodesInFile.Select(e => e.EpisodeNumber).ToList(),
|
EpisodeNumbers = episodesInFile.Select(e => e.EpisodeNumber).ToList(),
|
||||||
EpisodeFileId = file.Id,
|
EpisodeFileId = file.Id,
|
||||||
ExistingPath = series.Path.GetRelativePath(file.Path),
|
ExistingPath = file.RelativePath,
|
||||||
NewPath = series.Path.GetRelativePath(newPath)
|
NewPath = series.Path.GetRelativePath(newPath)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -109,6 +110,8 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
foreach (var episodeFile in episodeFiles)
|
foreach (var episodeFile in episodeFiles)
|
||||||
{
|
{
|
||||||
|
var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Debug("Renaming episode file: {0}", episodeFile);
|
_logger.Debug("Renaming episode file: {0}", episodeFile);
|
||||||
|
@ -125,7 +128,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Failed to rename file: " + episodeFile.Path, ex);
|
_logger.ErrorException("Failed to rename file: " + episodeFilePath, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -43,6 +44,8 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
private bool ChangeFileDate(EpisodeFile episodeFile, Series series, List<Episode> episodes)
|
private bool ChangeFileDate(EpisodeFile episodeFile, Series series, List<Episode> episodes)
|
||||||
{
|
{
|
||||||
|
var episodeFilePath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
switch (_configService.FileDate)
|
switch (_configService.FileDate)
|
||||||
{
|
{
|
||||||
case FileDateType.LocalAirDate:
|
case FileDateType.LocalAirDate:
|
||||||
|
@ -55,7 +58,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChangeFileDateToLocalAirDate(episodeFile.Path, airDate, airTime);
|
return ChangeFileDateToLocalAirDate(episodeFilePath, airDate, airTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
case FileDateType.UtcAirDate:
|
case FileDateType.UtcAirDate:
|
||||||
|
@ -67,7 +70,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChangeFileDateToUtcAirDate(episodeFile.Path, airDateUtc.Value);
|
return ChangeFileDateToUtcAirDate(episodeFilePath, airDateUtc.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
@ -43,11 +44,12 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
foreach (var existingFile in existingFiles)
|
foreach (var existingFile in existingFiles)
|
||||||
{
|
{
|
||||||
var file = existingFile.First();
|
var file = existingFile.First();
|
||||||
|
var episodeFilePath = Path.Combine(localEpisode.Series.Path, file.RelativePath);
|
||||||
|
|
||||||
if (_diskProvider.FileExists(file.Path))
|
if (_diskProvider.FileExists(episodeFilePath))
|
||||||
{
|
{
|
||||||
_logger.Debug("Removing existing episode file: {0}", file);
|
_logger.Debug("Removing existing episode file: {0}", file);
|
||||||
_recycleBinProvider.DeleteFile(file.Path);
|
_recycleBinProvider.DeleteFile(episodeFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveFileResult.OldFiles.Add(file);
|
moveFileResult.OldFiles.Add(file);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Messaging.Commands
|
namespace NzbDrone.Core.Messaging.Commands
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,12 +49,12 @@ namespace NzbDrone.Core.Metadata.Consumers.Roksbox
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.EpisodeImage)
|
if (metadataFile.Type == MetadataType.EpisodeImage)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeImageFilename(episodeFile.Path);
|
newFilename = GetEpisodeImageFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeMetadataFilename(episodeFile.Path);
|
newFilename = GetEpisodeMetadataFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -64,6 +64,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Roksbox
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
||||||
|
newFilename = Path.Combine(series.Path, newFilename);
|
||||||
|
|
||||||
if (!newFilename.PathEquals(existingFilename))
|
if (!newFilename.PathEquals(existingFilename))
|
||||||
{
|
{
|
||||||
|
@ -159,8 +160,8 @@ namespace NzbDrone.Core.Metadata.Consumers.Roksbox
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Generating Episode Metadata for: {0}", episodeFile.Path);
|
_logger.Debug("Generating Episode Metadata for: {0}", episodeFile.RelativePath);
|
||||||
|
|
||||||
var xmlResult = String.Empty;
|
var xmlResult = String.Empty;
|
||||||
foreach (var episode in episodeFile.Episodes.Value)
|
foreach (var episode in episodeFile.Episodes.Value)
|
||||||
|
@ -191,7 +192,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Roksbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MetadataFileResult(GetEpisodeMetadataFilename(episodeFile.Path), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
return new MetadataFileResult(GetEpisodeMetadataFilename(episodeFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> SeriesImages(Series series)
|
public override List<ImageFileResult> SeriesImages(Series series)
|
||||||
|
@ -244,7 +245,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Roksbox
|
||||||
return new List<ImageFileResult>();
|
return new List<ImageFileResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<ImageFileResult> {new ImageFileResult(GetEpisodeImageFilename(episodeFile.Path), screenshot.Url)};
|
return new List<ImageFileResult> {new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url)};
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetEpisodeMetadataFilename(string episodeFilePath)
|
private string GetEpisodeMetadataFilename(string episodeFilePath)
|
||||||
|
|
|
@ -48,12 +48,12 @@ namespace NzbDrone.Core.Metadata.Consumers.Wdtv
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.EpisodeImage)
|
if (metadataFile.Type == MetadataType.EpisodeImage)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeImageFilename(episodeFile.Path);
|
newFilename = GetEpisodeImageFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeMetadataFilename(episodeFile.Path);
|
newFilename = GetEpisodeMetadataFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -63,6 +63,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Wdtv
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
||||||
|
newFilename = Path.Combine(series.Path, newFilename);
|
||||||
|
|
||||||
if (!newFilename.PathEquals(existingFilename))
|
if (!newFilename.PathEquals(existingFilename))
|
||||||
{
|
{
|
||||||
|
@ -151,7 +152,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Wdtv
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Generating Episode Metadata for: {0}", episodeFile.Path);
|
_logger.Debug("Generating Episode Metadata for: {0}", Path.Combine(series.Path, episodeFile.RelativePath));
|
||||||
|
|
||||||
var xmlResult = String.Empty;
|
var xmlResult = String.Empty;
|
||||||
foreach (var episode in episodeFile.Episodes.Value)
|
foreach (var episode in episodeFile.Episodes.Value)
|
||||||
|
@ -190,7 +191,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Wdtv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filename = GetEpisodeMetadataFilename(episodeFile.Path);
|
var filename = GetEpisodeMetadataFilename(episodeFile.RelativePath);
|
||||||
|
|
||||||
return new MetadataFileResult(filename, xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
return new MetadataFileResult(filename, xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
||||||
}
|
}
|
||||||
|
@ -264,7 +265,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Wdtv
|
||||||
return new List<ImageFileResult>();
|
return new List<ImageFileResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<ImageFileResult>{ new ImageFileResult(GetEpisodeImageFilename(episodeFile.Path), screenshot.Url) };
|
return new List<ImageFileResult>{ new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url) };
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetEpisodeMetadataFilename(string episodeFilePath)
|
private string GetEpisodeMetadataFilename(string episodeFilePath)
|
||||||
|
|
|
@ -50,12 +50,12 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
|
|
||||||
if (metadataFile.Type == MetadataType.EpisodeImage)
|
if (metadataFile.Type == MetadataType.EpisodeImage)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeImageFilename(episodeFile.Path);
|
newFilename = GetEpisodeImageFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
else if (metadataFile.Type == MetadataType.EpisodeMetadata)
|
||||||
{
|
{
|
||||||
newFilename = GetEpisodeNfoFilename(episodeFile.Path);
|
newFilename = GetEpisodeNfoFilename(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -65,6 +65,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
var existingFilename = Path.Combine(series.Path, metadataFile.RelativePath);
|
||||||
|
newFilename = Path.Combine(series.Path, newFilename);
|
||||||
|
|
||||||
if (!newFilename.PathEquals(existingFilename))
|
if (!newFilename.PathEquals(existingFilename))
|
||||||
{
|
{
|
||||||
|
@ -214,7 +215,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Generating Episode Metadata for: {0}", episodeFile.Path);
|
_logger.Debug("Generating Episode Metadata for: {0}", Path.Combine(series.Path, episodeFile.RelativePath));
|
||||||
|
|
||||||
var xmlResult = String.Empty;
|
var xmlResult = String.Empty;
|
||||||
foreach (var episode in episodeFile.Episodes.Value)
|
foreach (var episode in episodeFile.Episodes.Value)
|
||||||
|
@ -265,7 +266,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MetadataFileResult(GetEpisodeNfoFilename(episodeFile.Path), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
return new MetadataFileResult(GetEpisodeNfoFilename(episodeFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<ImageFileResult> SeriesImages(Series series)
|
public override List<ImageFileResult> SeriesImages(Series series)
|
||||||
|
@ -305,7 +306,7 @@ namespace NzbDrone.Core.Metadata.Consumers.Xbmc
|
||||||
|
|
||||||
return new List<ImageFileResult>
|
return new List<ImageFileResult>
|
||||||
{
|
{
|
||||||
new ImageFileResult(GetEpisodeImageFilename(episodeFile.Path), screenshot.Url)
|
new ImageFileResult(GetEpisodeImageFilename(episodeFile.RelativePath), screenshot.Url)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,18 +174,18 @@ namespace NzbDrone.Core.Metadata
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var relativePath = series.Path.GetRelativePath(episodeMetadata.Path);
|
var fullPath = Path.Combine(series.Path, episodeMetadata.Path);
|
||||||
|
|
||||||
var existingMetadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeMetadata &&
|
var existingMetadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeMetadata &&
|
||||||
c.EpisodeFileId == episodeFile.Id);
|
c.EpisodeFileId == episodeFile.Id);
|
||||||
|
|
||||||
if (existingMetadata != null)
|
if (existingMetadata != null)
|
||||||
{
|
{
|
||||||
var fullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
||||||
if (!episodeMetadata.Path.PathEquals(fullPath))
|
if (!episodeMetadata.Path.PathEquals(existingFullPath))
|
||||||
{
|
{
|
||||||
_diskProvider.MoveFile(fullPath, episodeMetadata.Path);
|
_diskProvider.MoveFile(existingFullPath, fullPath);
|
||||||
existingMetadata.RelativePath = relativePath;
|
existingMetadata.RelativePath = episodeMetadata.Path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ namespace NzbDrone.Core.Metadata
|
||||||
EpisodeFileId = episodeFile.Id,
|
EpisodeFileId = episodeFile.Id,
|
||||||
Consumer = consumer.GetType().Name,
|
Consumer = consumer.GetType().Name,
|
||||||
Type = MetadataType.EpisodeMetadata,
|
Type = MetadataType.EpisodeMetadata,
|
||||||
RelativePath = relativePath
|
RelativePath = episodeMetadata.Path
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hash == metadata.Hash)
|
if (hash == metadata.Hash)
|
||||||
|
@ -206,8 +206,8 @@ namespace NzbDrone.Core.Metadata
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Writing Episode Metadata to: {0}", episodeMetadata.Path);
|
_logger.Debug("Writing Episode Metadata to: {0}", fullPath);
|
||||||
_diskProvider.WriteAllText(episodeMetadata.Path, episodeMetadata.Contents);
|
_diskProvider.WriteAllText(fullPath, episodeMetadata.Contents);
|
||||||
|
|
||||||
metadata.Hash = hash;
|
metadata.Hash = hash;
|
||||||
|
|
||||||
|
@ -289,24 +289,24 @@ namespace NzbDrone.Core.Metadata
|
||||||
|
|
||||||
foreach (var image in consumer.EpisodeImages(series, episodeFile))
|
foreach (var image in consumer.EpisodeImages(series, episodeFile))
|
||||||
{
|
{
|
||||||
|
var fullPath = Path.Combine(series.Path, image.Path);
|
||||||
|
|
||||||
if (_diskProvider.FileExists(image.Path))
|
if (_diskProvider.FileExists(image.Path))
|
||||||
{
|
{
|
||||||
_logger.Debug("Episode image already exists: {0}", image.Path);
|
_logger.Debug("Episode image already exists: {0}", image.Path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var relativePath = series.Path.GetRelativePath(image.Path);
|
|
||||||
|
|
||||||
var existingMetadata = existingMetadataFiles.FirstOrDefault(c => c.Type == MetadataType.EpisodeImage &&
|
var existingMetadata = existingMetadataFiles.FirstOrDefault(c => c.Type == MetadataType.EpisodeImage &&
|
||||||
c.EpisodeFileId == episodeFile.Id);
|
c.EpisodeFileId == episodeFile.Id);
|
||||||
|
|
||||||
if (existingMetadata != null)
|
if (existingMetadata != null)
|
||||||
{
|
{
|
||||||
var fullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
||||||
if (!image.Path.PathEquals(fullPath))
|
if (!fullPath.PathEquals(existingFullPath))
|
||||||
{
|
{
|
||||||
_diskProvider.MoveFile(fullPath, image.Path);
|
_diskProvider.MoveFile(fullPath, fullPath);
|
||||||
existingMetadata.RelativePath = relativePath;
|
existingMetadata.RelativePath = image.Path;
|
||||||
|
|
||||||
return new List<MetadataFile>{ existingMetadata };
|
return new List<MetadataFile>{ existingMetadata };
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,8 @@
|
||||||
<Compile Include="Datastore\Migration\054_rename_profiles.cs" />
|
<Compile Include="Datastore\Migration\054_rename_profiles.cs" />
|
||||||
<Compile Include="Datastore\Migration\055_drop_old_profile_columns.cs" />
|
<Compile Include="Datastore\Migration\055_drop_old_profile_columns.cs" />
|
||||||
<Compile Include="Datastore\Migration\056_add_mediainfo_to_episodefile.cs" />
|
<Compile Include="Datastore\Migration\056_add_mediainfo_to_episodefile.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\057_convert_episode_file_path_to_relative.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\058_drop_epsiode_file_path.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
||||||
|
@ -427,7 +429,6 @@
|
||||||
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
||||||
<Compile Include="Instrumentation\DatabaseTarget.cs" />
|
<Compile Include="Instrumentation\DatabaseTarget.cs" />
|
||||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||||
<Compile Include="Instrumentation\Extensions\LoggerProgressExtensions.cs" />
|
|
||||||
<Compile Include="Instrumentation\Log.cs" />
|
<Compile Include="Instrumentation\Log.cs" />
|
||||||
<Compile Include="Instrumentation\LogRepository.cs" />
|
<Compile Include="Instrumentation\LogRepository.cs" />
|
||||||
<Compile Include="Instrumentation\LogService.cs" />
|
<Compile Include="Instrumentation\LogService.cs" />
|
||||||
|
@ -701,6 +702,7 @@
|
||||||
<Compile Include="ThingiProvider\ProviderFactory.cs" />
|
<Compile Include="ThingiProvider\ProviderFactory.cs" />
|
||||||
<Compile Include="ThingiProvider\ProviderRepository.cs" />
|
<Compile Include="ThingiProvider\ProviderRepository.cs" />
|
||||||
<Compile Include="Tv\Actor.cs" />
|
<Compile Include="Tv\Actor.cs" />
|
||||||
|
<Compile Include="Tv\Commands\MoveSeriesCommand.cs" />
|
||||||
<Compile Include="Tv\Commands\RefreshSeriesCommand.cs" />
|
<Compile Include="Tv\Commands\RefreshSeriesCommand.cs" />
|
||||||
<Compile Include="Tv\Episode.cs" />
|
<Compile Include="Tv\Episode.cs" />
|
||||||
<Compile Include="Tv\EpisodeCutoffService.cs" />
|
<Compile Include="Tv\EpisodeCutoffService.cs" />
|
||||||
|
@ -714,8 +716,10 @@
|
||||||
<Compile Include="Tv\Events\SeriesAddedEvent.cs" />
|
<Compile Include="Tv\Events\SeriesAddedEvent.cs" />
|
||||||
<Compile Include="Tv\Events\SeriesDeletedEvent.cs" />
|
<Compile Include="Tv\Events\SeriesDeletedEvent.cs" />
|
||||||
<Compile Include="Tv\Events\SeriesEditedEvent.cs" />
|
<Compile Include="Tv\Events\SeriesEditedEvent.cs" />
|
||||||
|
<Compile Include="Tv\Events\SeriesMovedEvent.cs" />
|
||||||
<Compile Include="Tv\Events\SeriesRefreshStartingEvent.cs" />
|
<Compile Include="Tv\Events\SeriesRefreshStartingEvent.cs" />
|
||||||
<Compile Include="Tv\Events\SeriesUpdatedEvent.cs" />
|
<Compile Include="Tv\Events\SeriesUpdatedEvent.cs" />
|
||||||
|
<Compile Include="Tv\MoveSeriesService.cs" />
|
||||||
<Compile Include="Tv\Ratings.cs" />
|
<Compile Include="Tv\Ratings.cs" />
|
||||||
<Compile Include="Tv\RefreshEpisodeService.cs" />
|
<Compile Include="Tv\RefreshEpisodeService.cs" />
|
||||||
<Compile Include="Tv\RefreshSeriesService.cs" />
|
<Compile Include="Tv\RefreshSeriesService.cs" />
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -77,7 +78,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
{
|
{
|
||||||
if (episodeFile.SceneName.IsNullOrWhiteSpace())
|
if (episodeFile.SceneName.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return Path.GetFileNameWithoutExtension(episodeFile.Path);
|
return Path.GetFileNameWithoutExtension(episodeFile.RelativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return episodeFile.SceneName;
|
return episodeFile.SceneName;
|
||||||
|
@ -204,6 +205,8 @@ namespace NzbDrone.Core.Organizer
|
||||||
|
|
||||||
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
|
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
|
||||||
{
|
{
|
||||||
|
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
|
||||||
|
|
||||||
string path = series.Path;
|
string path = series.Path;
|
||||||
|
|
||||||
if (series.SeasonFolder)
|
if (series.SeasonFolder)
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
_singleEpisodeFile = new EpisodeFile
|
_singleEpisodeFile = new EpisodeFile
|
||||||
{
|
{
|
||||||
Quality = new QualityModel(Quality.HDTV720p),
|
Quality = new QualityModel(Quality.HDTV720p),
|
||||||
Path = @"C:\Test\Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv",
|
RelativePath = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv",
|
||||||
ReleaseGroup = "RlsGrp",
|
ReleaseGroup = "RlsGrp",
|
||||||
MediaInfo = mediaInfo
|
MediaInfo = mediaInfo
|
||||||
};
|
};
|
||||||
|
@ -101,7 +101,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
_multiEpisodeFile = new EpisodeFile
|
_multiEpisodeFile = new EpisodeFile
|
||||||
{
|
{
|
||||||
Quality = new QualityModel(Quality.HDTV720p),
|
Quality = new QualityModel(Quality.HDTV720p),
|
||||||
Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv",
|
RelativePath = "Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv",
|
||||||
ReleaseGroup = "RlsGrp",
|
ReleaseGroup = "RlsGrp",
|
||||||
MediaInfo = mediaInfo
|
MediaInfo = mediaInfo
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
_dailyEpisodeFile = new EpisodeFile
|
_dailyEpisodeFile = new EpisodeFile
|
||||||
{
|
{
|
||||||
Quality = new QualityModel(Quality.HDTV720p),
|
Quality = new QualityModel(Quality.HDTV720p),
|
||||||
Path = @"C:\Test\Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv",
|
RelativePath = "Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv",
|
||||||
ReleaseGroup = "RlsGrp",
|
ReleaseGroup = "RlsGrp",
|
||||||
MediaInfo = mediaInfo
|
MediaInfo = mediaInfo
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
_animeEpisodeFile = new EpisodeFile
|
_animeEpisodeFile = new EpisodeFile
|
||||||
{
|
{
|
||||||
Quality = new QualityModel(Quality.HDTV720p),
|
Quality = new QualityModel(Quality.HDTV720p),
|
||||||
Path = @"C:\Test\Series.Title.001.HDTV.x264-EVOLVE.mkv",
|
RelativePath = "Series.Title.001.HDTV.x264-EVOLVE.mkv",
|
||||||
ReleaseGroup = "RlsGrp",
|
ReleaseGroup = "RlsGrp",
|
||||||
MediaInfo = mediaInfoAnime
|
MediaInfo = mediaInfoAnime
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,6 @@ using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ProgressMessaging
|
namespace NzbDrone.Core.ProgressMessaging
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ProgressMessageTarget : Target, IHandle<ApplicationStartedEvent>
|
public class ProgressMessageTarget : Target, IHandle<ApplicationStartedEvent>
|
||||||
{
|
{
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Tv.Commands
|
||||||
|
{
|
||||||
|
public class MoveSeriesCommand : Command
|
||||||
|
{
|
||||||
|
public Int32 SeriesId { get; set; }
|
||||||
|
public String SourcePath { get; set; }
|
||||||
|
public String DestinationPath { get; set; }
|
||||||
|
public String DestinationRootFolder { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -199,7 +199,7 @@ namespace NzbDrone.Core.Tv
|
||||||
foreach (var episode in message.EpisodeFile.Episodes.Value)
|
foreach (var episode in message.EpisodeFile.Episodes.Value)
|
||||||
{
|
{
|
||||||
_episodeRepository.SetFileId(episode.Id, message.EpisodeFile.Id);
|
_episodeRepository.SetFileId(episode.Id, message.EpisodeFile.Id);
|
||||||
_logger.Debug("Linking [{0}] > [{1}]", message.EpisodeFile.Path, episode);
|
_logger.Debug("Linking [{0}] > [{1}]", message.EpisodeFile.RelativePath, episode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Messaging;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Tv.Events
|
||||||
|
{
|
||||||
|
public class SeriesMovedEvent : IEvent
|
||||||
|
{
|
||||||
|
public Series Series { get; set; }
|
||||||
|
public String SourcePath { get; set; }
|
||||||
|
public String DestinationPath { get; set; }
|
||||||
|
|
||||||
|
public SeriesMovedEvent(Series series, string sourcePath, string destinationPath)
|
||||||
|
{
|
||||||
|
Series = series;
|
||||||
|
SourcePath = sourcePath;
|
||||||
|
DestinationPath = destinationPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Tv.Commands;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Tv
|
||||||
|
{
|
||||||
|
public class MoveSeriesService : IExecute<MoveSeriesCommand>
|
||||||
|
{
|
||||||
|
private readonly ISeriesService _seriesService;
|
||||||
|
private readonly IBuildFileNames _filenameBuilder;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public MoveSeriesService(ISeriesService seriesService,
|
||||||
|
IBuildFileNames filenameBuilder,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
|
IEventAggregator eventAggregator,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_seriesService = seriesService;
|
||||||
|
_filenameBuilder = filenameBuilder;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(MoveSeriesCommand message)
|
||||||
|
{
|
||||||
|
var series = _seriesService.GetSeries(message.SeriesId);
|
||||||
|
var source = message.SourcePath;
|
||||||
|
var destination = message.DestinationPath;
|
||||||
|
|
||||||
|
if (!message.DestinationRootFolder.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
_logger.Debug("Buiding destination path using root folder: {0} and the series title", message.DestinationRootFolder);
|
||||||
|
destination = Path.Combine(message.DestinationRootFolder, _filenameBuilder.GetSeriesFolder(series));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.ProgressInfo("Moving {0} from '{1}' to '{2}'", series.Title, source, destination);
|
||||||
|
|
||||||
|
//TODO: Move to transactional disk operations
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_diskProvider.MoveFolder(source, destination);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
var errorMessage = String.Format("Unable to move series from '{0}' to '{1}'", source, destination);
|
||||||
|
|
||||||
|
_logger.ErrorException(errorMessage, ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.ProgressInfo("{0} moved successfully to {1}", series.Title, series.Path);
|
||||||
|
|
||||||
|
//Update the series path to the new path
|
||||||
|
series.Path = destination;
|
||||||
|
series = _seriesService.UpdateSeries(series);
|
||||||
|
|
||||||
|
_eventAggregator.PublishEvent(new SeriesMovedEvent(series, source, destination));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
|
@ -16,8 +16,6 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
public void Handle(SeriesEditedEvent message)
|
public void Handle(SeriesEditedEvent message)
|
||||||
{
|
{
|
||||||
//TODO: Refresh if path has changed (also move files)
|
|
||||||
|
|
||||||
if (message.Series.SeriesType != message.OldSeries.SeriesType)
|
if (message.Series.SeriesType != message.OldSeries.SeriesType)
|
||||||
{
|
{
|
||||||
_commandExecutor.PublishCommandAsync(new RefreshSeriesCommand(message.Series.Id));
|
_commandExecutor.PublishCommandAsync(new RefreshSeriesCommand(message.Series.Id));
|
||||||
|
|
|
@ -5,10 +5,10 @@ using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Common.Processes;
|
using NzbDrone.Common.Processes;
|
||||||
using NzbDrone.Core.Backup;
|
using NzbDrone.Core.Backup;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Update.Commands;
|
using NzbDrone.Core.Update.Commands;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Update
|
namespace NzbDrone.Core.Update
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue