mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
commit
dfe2746bc6
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Api.Series;
|
||||
|
||||
namespace NzbDrone.Api.Blacklist
|
||||
{
|
||||
@ -12,5 +13,7 @@ public class BlacklistResource : RestResource
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public SeriesResource Series { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ private RootFolderResource GetRootFolder(int id)
|
||||
|
||||
private int CreateRootFolder(RootFolderResource rootFolderResource)
|
||||
{
|
||||
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
|
||||
}
|
||||
|
||||
private List<RootFolderResource> GetRootFolders()
|
||||
|
@ -52,15 +52,17 @@
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WebDriver">
|
||||
<HintPath>..\packages\Selenium.WebDriver.2.37.0\lib\net40\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support">
|
||||
<HintPath>..\packages\Selenium.Support.2.37.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions">
|
||||
<HintPath>..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver, Version=2.41.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Selenium.WebDriver.2.41.0\lib\net40\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support, Version=2.41.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Selenium.Support.2.41.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AutomationTestAttribute.cs" />
|
||||
|
@ -3,6 +3,6 @@
|
||||
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="2.6.2" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="2.37.0" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="2.37.0" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="2.41.0" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="2.41.0" targetFramework="net40" />
|
||||
</packages>
|
@ -10,30 +10,26 @@ namespace NzbDrone.Common.Test.DiskProviderTests
|
||||
{
|
||||
public class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
||||
{
|
||||
DirectoryInfo _binFolder;
|
||||
DirectoryInfo _binFolderCopy;
|
||||
DirectoryInfo _binFolderMove;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_binFolder = new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||
_binFolderCopy = new DirectoryInfo(Path.Combine(_binFolder.Parent.FullName, "bin_copy"));
|
||||
_binFolderMove = new DirectoryInfo(Path.Combine(_binFolder.Parent.FullName, "bin_move"));
|
||||
|
||||
if (_binFolderCopy.Exists)
|
||||
{
|
||||
foreach (var file in _binFolderCopy.GetFiles("*", SearchOption.AllDirectories))
|
||||
{
|
||||
file.Attributes = FileAttributes.Normal;
|
||||
}
|
||||
_binFolderCopy.Delete(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (_binFolderMove.Exists)
|
||||
{
|
||||
_binFolderMove.Delete(true);
|
||||
}
|
||||
public DirectoryInfo GetFilledTempFolder()
|
||||
{
|
||||
var tempFolder = GetTempFilePath();
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
File.WriteAllText(Path.Combine(tempFolder, Path.GetRandomFileName()), "RootFile");
|
||||
|
||||
var subDir = Path.Combine(tempFolder, Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(subDir);
|
||||
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile1");
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile2");
|
||||
|
||||
return new DirectoryInfo(tempFolder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -57,79 +53,94 @@ public void directory_exist_should_not_be_able_to_find_none_existing_folder()
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void moveFile_should_overwrite_existing_file()
|
||||
public void MoveFile_should_overwrite_existing_file()
|
||||
{
|
||||
var source1 = GetTempFilePath();
|
||||
var source2 = GetTempFilePath();
|
||||
var destination = GetTempFilePath();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
File.WriteAllText(source1, "SourceFile1");
|
||||
File.WriteAllText(source2, "SourceFile2");
|
||||
|
||||
var targetPath = Path.Combine(_binFolderCopy.FullName, "file.move");
|
||||
Subject.MoveFile(source1, destination);
|
||||
Subject.MoveFile(source2, destination);
|
||||
|
||||
Subject.MoveFile(_binFolderCopy.GetFiles("*.dll", SearchOption.AllDirectories).First().FullName, targetPath);
|
||||
Subject.MoveFile(_binFolderCopy.GetFiles("*.pdb", SearchOption.AllDirectories).First().FullName, targetPath);
|
||||
|
||||
File.Exists(targetPath).Should().BeTrue();
|
||||
File.Exists(destination).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void moveFile_should_not_move_overwrite_itself()
|
||||
public void MoveFile_should_not_move_overwrite_itself()
|
||||
{
|
||||
var source = GetTempFilePath();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
File.WriteAllText(source, "SourceFile1");
|
||||
|
||||
var targetPath = _binFolderCopy.GetFiles("*.dll", SearchOption.AllDirectories).First().FullName;
|
||||
Subject.MoveFile(source, source);
|
||||
|
||||
Subject.MoveFile(targetPath, targetPath);
|
||||
|
||||
File.Exists(targetPath).Should().BeTrue();
|
||||
File.Exists(source).Should().BeTrue();
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
VerifyCopy();
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
|
||||
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
//Delete Random File
|
||||
_binFolderCopy.Refresh();
|
||||
_binFolderCopy.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
destination.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
VerifyCopy();
|
||||
[Test]
|
||||
public void MoveFolder_should_move_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
Subject.CopyFolder(original.FullName, destination.FullName);
|
||||
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderCopy.FullName);
|
||||
Subject.CopyFolder(_binFolder.FullName, _binFolderMove.FullName);
|
||||
VerifyCopy();
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
|
||||
Subject.MoveFolder(_binFolderCopy.FullName, _binFolderMove.FullName);
|
||||
|
||||
|
||||
VerifyMove();
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void move_read_only_file()
|
||||
{
|
||||
var source = GetTestFilePath();
|
||||
var destination = GetTestFilePath();
|
||||
var source = GetTempFilePath();
|
||||
var destination = GetTempFilePath();
|
||||
|
||||
Subject.WriteAllText(source, "SourceFile");
|
||||
Subject.WriteAllText(destination, "DestinationFile");
|
||||
@ -150,23 +161,25 @@ public void empty_folder_should_return_folder_modified_date()
|
||||
[Test]
|
||||
public void folder_should_return_correct_value_for_last_write()
|
||||
{
|
||||
var testDir = Path.Combine(SandboxFolder, "LastWrite");
|
||||
var testDir = GetTempFilePath();
|
||||
var testFile = Path.Combine(testDir, Path.GetRandomFileName());
|
||||
|
||||
Directory.CreateDirectory(testDir);
|
||||
|
||||
Subject.FolderSetLastWriteTimeUtc(TempFolder, DateTime.UtcNow.AddMinutes(-5));
|
||||
|
||||
TestLogger.Info("Path is: {0}", testFile);
|
||||
|
||||
Subject.WriteAllText(testFile, "Test");
|
||||
|
||||
Subject.FolderGetLastWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||
Subject.FolderGetLastWrite(SandboxFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1));
|
||||
Subject.FolderGetLastWrite(TempFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1));
|
||||
Subject.FolderGetLastWrite(TempFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.IsFileLocked(testFile).Should().BeFalse();
|
||||
@ -175,7 +188,7 @@ public void should_return_false_for_unlocked_file()
|
||||
[Test]
|
||||
public void should_return_false_for_unlocked_and_readonly_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
File.SetAttributes(testFile, FileAttributes.ReadOnly);
|
||||
@ -186,7 +199,7 @@ public void should_return_false_for_unlocked_and_readonly_file()
|
||||
[Test]
|
||||
public void should_return_true_for_unlocked_file()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
using (var file = File.OpenWrite(testFile))
|
||||
@ -198,7 +211,7 @@ public void should_return_true_for_unlocked_file()
|
||||
[Test]
|
||||
public void should_be_able_to_set_permission_from_parrent()
|
||||
{
|
||||
var testFile = GetTestFilePath();
|
||||
var testFile = GetTempFilePath();
|
||||
Subject.WriteAllText(testFile, new Guid().ToString());
|
||||
|
||||
Subject.InheritFolderPermissions(testFile);
|
||||
@ -208,33 +221,26 @@ public void should_be_able_to_set_permission_from_parrent()
|
||||
[Explicit]
|
||||
public void check_last_write()
|
||||
{
|
||||
Console.WriteLine(Subject.FolderGetLastWrite(_binFolder.FullName));
|
||||
Console.WriteLine(_binFolder.LastWriteTimeUtc);
|
||||
Console.WriteLine(Subject.FolderGetLastWrite(GetFilledTempFolder().FullName));
|
||||
Console.WriteLine(GetFilledTempFolder().LastWriteTimeUtc);
|
||||
}
|
||||
|
||||
private void VerifyCopy()
|
||||
private void VerifyCopy(string source, string destination)
|
||||
{
|
||||
_binFolder.Refresh();
|
||||
_binFolderCopy.Refresh();
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
_binFolderCopy.GetFiles("*.*", SearchOption.AllDirectories)
|
||||
.Should().HaveSameCount(_binFolder.GetFiles("*.*", SearchOption.AllDirectories));
|
||||
|
||||
_binFolderCopy.GetDirectories().Should().HaveSameCount(_binFolder.GetDirectories());
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
|
||||
private void VerifyMove()
|
||||
private void VerifyMove(string source, string from, string destination)
|
||||
{
|
||||
_binFolder.Refresh();
|
||||
_binFolderCopy.Refresh();
|
||||
_binFolderMove.Refresh();
|
||||
Directory.Exists(from).Should().BeFalse();
|
||||
|
||||
_binFolderCopy.Exists.Should().BeFalse();
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
_binFolderMove.GetFiles("*.*", SearchOption.AllDirectories)
|
||||
.Should().HaveSameCount(_binFolder.GetFiles("*.*", SearchOption.AllDirectories));
|
||||
|
||||
_binFolderMove.GetDirectories().Should().HaveSameCount(_binFolder.GetDirectories());
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
@ -61,7 +62,17 @@ public void should_throw_if_drive_doesnt_exist()
|
||||
{
|
||||
WindowsOnly();
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
||||
// Find a drive that doesn't exist.
|
||||
for (char driveletter = 'Z'; driveletter > 'D' ; driveletter--)
|
||||
{
|
||||
if (new DriveInfo(driveletter.ToString()).IsReady)
|
||||
continue;
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(driveletter + @":\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Inconclusive("No drive available for testing.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -120,7 +120,7 @@ public void get_actual_casing_for_none_existing_folder_return_partially_fixed_re
|
||||
public void get_actual_casing_should_return_actual_casing_for_local_file_in_windows()
|
||||
{
|
||||
WindowsOnly();
|
||||
var path = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var path = Environment.ExpandEnvironmentVariables("%SystemRoot%\\System32");
|
||||
path.ToUpper().GetActualCasing().Should().Be(path);
|
||||
path.ToLower().GetActualCasing().Should().Be(path);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="ArchiveProvider.cs" />
|
||||
<Compile Include="Cache\Cached.cs" />
|
||||
<Compile Include="Cache\CacheManger.cs" />
|
||||
<Compile Include="Cache\CacheManager.cs" />
|
||||
<Compile Include="Cache\ICached.cs" />
|
||||
<Compile Include="Composition\Container.cs" />
|
||||
<Compile Include="Composition\IContainer.cs" />
|
||||
|
@ -5,7 +5,7 @@
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore
|
||||
|
@ -1,10 +1,10 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtenstionsTests
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtensionsTests
|
||||
{
|
||||
public class PagingOffsetFixture
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtenstionsTests
|
||||
namespace NzbDrone.Core.Test.Datastore.PagingSpecExtensionsTests
|
||||
{
|
||||
public class ToSortDirectionFixture
|
||||
{
|
@ -48,7 +48,7 @@ public void Setup()
|
||||
Series = series,
|
||||
Release = new ReleaseInfo(),
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.SDTV, true) },
|
||||
Episodes = new List<Episode> { new Episode() }
|
||||
Episodes = new List<Episode> { new Episode() { Id = 2 } }
|
||||
|
||||
};
|
||||
|
||||
@ -59,13 +59,21 @@ public void Setup()
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>().Setup(s => s.Get(Quality.SDTV)).Returns(qualityType);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(new List<Episode>() {
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode(),
|
||||
new Episode(), new Episode(), new Episode(), new Episode() { Id = 2 }, new Episode() });
|
||||
}
|
||||
|
||||
private void GivenLastEpisode()
|
||||
{
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(true);
|
||||
s => s.GetEpisodesBySeason(It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(new List<Episode>() {
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode(),
|
||||
new Episode(), new Episode(), new Episode(), new Episode(), new Episode() { Id = 2 } });
|
||||
}
|
||||
|
||||
[TestCase(30, 50, false)]
|
||||
@ -110,10 +118,6 @@ public void multi_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||
parseResultMulti.Series = series;
|
||||
parseResultMulti.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(false);
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultMulti, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
@ -129,10 +133,6 @@ public void multiset_episode(int runtime, int sizeInMegaBytes, bool expectedResu
|
||||
parseResultMultiSet.Series = series;
|
||||
parseResultMultiSet.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>().Setup(
|
||||
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
|
||||
.Returns(false);
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultMultiSet, null).Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
@ -22,10 +23,11 @@ public void WithDefault_success(string actual, object defaultValue, string resul
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void WithDefault_Fail()
|
||||
{
|
||||
"test".WithDefault(null);
|
||||
Assert.Throws<ArgumentNullException>(() => "test".WithDefault(null));
|
||||
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -103,8 +103,8 @@
|
||||
<Compile Include="Datastore\DatabaseRelationshipFixture.cs" />
|
||||
<Compile Include="Datastore\MappingExtentionFixture.cs" />
|
||||
<Compile Include="Datastore\ObjectDatabaseFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtenstionsTests\ToSortDirectionFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtenstionsTests\PagingOffsetFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\ToSortDirectionFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\PagingOffsetFixture.cs" />
|
||||
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\AlterFixture.cs" />
|
||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\DuplicateFixture.cs" />
|
||||
|
@ -25,6 +25,7 @@ public class DailyEpisodeParserFixture : CoreTest
|
||||
[TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 13)]
|
||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)]
|
||||
[TestCase("Series Title - 2013-10-30 - Episode Title (1) [HDTV-720p]", "Series Title", 2013, 10, 30)]
|
||||
[TestCase("The_Voice_US_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 2014, 4, 28)]
|
||||
public void should_parse_daily_episode(string postTitle, string title, int year, int month, int day)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
@ -55,6 +55,7 @@ public void should_parse_sdtv_quality(string title, bool proper)
|
||||
[TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", false)]
|
||||
[TestCase("The.Girls.Next.Door.S03E06.DVD.Rip.XviD-WiDE", false)]
|
||||
[TestCase("the.shield.1x13.circles.ws.xvidvd-tns", false)]
|
||||
[TestCase("the_x-files.9x18.sunshine_days.ac3.ws_dvdrip_xvid-fov.avi", false)]
|
||||
public void should_parse_dvd_quality(string title, bool proper)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.DVD, proper);
|
||||
|
@ -9,8 +9,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
public class ReleaseGroupParserFixture : CoreTest
|
||||
{
|
||||
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")]
|
||||
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")]
|
||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")]
|
||||
[TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "DRONE")]
|
||||
[TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "DRONE")]
|
||||
[TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")]
|
||||
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")]
|
||||
[TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")]
|
||||
@ -18,6 +18,7 @@ public class ReleaseGroupParserFixture : CoreTest
|
||||
[TestCase("The Office - S01E01 - Pilot [HTDV-720p]", "DRONE")]
|
||||
[TestCase("The Office - S01E01 - Pilot [HTDV-1080p]", "DRONE")]
|
||||
[TestCase("The.Walking.Dead.S04E13.720p.WEB-DL.AAC2.0.H.264-Cyphanix", "Cyphanix")]
|
||||
[TestCase("Arrow.S02E01.720p.WEB-DL.DD5.1.H.264.mkv", "DRONE")]
|
||||
public void should_parse_release_group(string title, string expected)
|
||||
{
|
||||
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
|
||||
|
@ -83,6 +83,7 @@ public class SingleEpisodeParserFixture : CoreTest
|
||||
[TestCase("Homeland - 2x12 - The Choice [HDTV-1080p].mkv", "Homeland", 2, 12)]
|
||||
[TestCase("Homeland - 2x4 - New Car Smell [HDTV-1080p].mkv", "Homeland", 2, 4)]
|
||||
[TestCase("Top Gear - 06x11 - 2005.08.07", "Top Gear", 6, 11)]
|
||||
[TestCase("The_Voice_US_s06e19_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 6, 19)]
|
||||
public void should_parse_single_episode(string postTitle, string title, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
@ -13,12 +13,10 @@ public class ArchiveProviderFixture : TestBase<ArchiveService>
|
||||
[Test]
|
||||
public void Should_extract_to_correct_folder()
|
||||
{
|
||||
var destination = Path.Combine(TempFolder, "destination");
|
||||
var destinationFolder = new DirectoryInfo(GetTempFilePath());
|
||||
var testArchive = OsInfo.IsWindows ? "TestArchive.zip" : "TestArchive.tar.gz";
|
||||
|
||||
Subject.Extract(GetTestFilePath(testArchive), destination);
|
||||
|
||||
var destinationFolder = new DirectoryInfo(destination);
|
||||
Subject.Extract(Path.Combine("Files", testArchive), destinationFolder.FullName);
|
||||
|
||||
destinationFolder.Exists.Should().BeTrue();
|
||||
destinationFolder.GetDirectories().Should().HaveCount(1);
|
||||
|
@ -128,7 +128,7 @@ public void when_no_updates_are_available_should_return_without_error_or_warning
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
|
||||
ExceptionVerification.AssertNoUnexcpectedLogs();
|
||||
ExceptionVerification.AssertNoUnexpectedLogs();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -2,12 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public class Blacklist : ModelBase
|
||||
{
|
||||
public Int32 SeriesId { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public List<Int32> EpisodeIds { get; set; }
|
||||
public String SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
@ -27,5 +29,12 @@ public List<Blacklist> BlacklistedBySeries(int seriesId)
|
||||
{
|
||||
return Query.Where(b => b.SeriesId == seriesId);
|
||||
}
|
||||
|
||||
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
|
||||
{
|
||||
var baseQuery = query.Join<Blacklist, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id);
|
||||
|
||||
return base.GetPagedQuery(baseQuery, pagingSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
using Marr.Data.Mapping;
|
||||
using NzbDrone.Common.Reflection;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class MappingExtensions
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class PagingSpecExtensions
|
||||
{
|
@ -4,7 +4,7 @@
|
||||
using Marr.Data;
|
||||
using Marr.Data.Mapping;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Extentions
|
||||
namespace NzbDrone.Core.Datastore.Extensions
|
||||
{
|
||||
public static class RelationshipExtensions
|
||||
{
|
@ -7,7 +7,7 @@
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
@ -66,10 +67,27 @@ public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase sear
|
||||
//Multiply maxSize by Series.Runtime
|
||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
||||
//Check if there was only one episode parsed and it is the first
|
||||
if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.First().Id))
|
||||
if (subject.Episodes.Count == 1)
|
||||
{
|
||||
maxSize = maxSize * 2;
|
||||
Episode episode = subject.Episodes.First();
|
||||
List<Episode> seasonEpisodes;
|
||||
|
||||
var seasonSearchCriteria = searchCriteria as SeasonSearchCriteria;
|
||||
if (seasonSearchCriteria != null && !seasonSearchCriteria.Series.UseSceneNumbering && seasonSearchCriteria.Episodes.Any(v => v.Id == episode.Id))
|
||||
{
|
||||
seasonEpisodes = (searchCriteria as SeasonSearchCriteria).Episodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
seasonEpisodes = _episodeService.GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber);
|
||||
}
|
||||
|
||||
//Ensure that this is either the first episode
|
||||
//or is the last episode in a season that has 10 or more episodes
|
||||
if (seasonEpisodes.First().Id == episode.Id || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().Id == episode.Id))
|
||||
{
|
||||
maxSize = maxSize * 2;
|
||||
}
|
||||
}
|
||||
|
||||
//If the parsed size is greater than maxSize we don't want it
|
||||
|
@ -100,6 +100,9 @@ public void Handle(ApplicationStartedEvent message)
|
||||
|
||||
public void Handle(CommandExecutedEvent message)
|
||||
{
|
||||
if (message.Command.GetType().Name == "BroadcastSignalRMessage")
|
||||
return;
|
||||
|
||||
var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.GetType().FullName);
|
||||
|
||||
if (scheduledTask != null)
|
||||
|
@ -138,9 +138,9 @@
|
||||
<Compile Include="Datastore\DbFactory.cs" />
|
||||
<Compile Include="Datastore\Converters\EnumIntConverter.cs" />
|
||||
<Compile Include="Datastore\Events\ModelEvent.cs" />
|
||||
<Compile Include="Datastore\Extentions\MappingExtensions.cs" />
|
||||
<Compile Include="Datastore\Extentions\PagingSpecExtensions.cs" />
|
||||
<Compile Include="Datastore\Extentions\RelationshipExtensions.cs" />
|
||||
<Compile Include="Datastore\Extensions\MappingExtensions.cs" />
|
||||
<Compile Include="Datastore\Extensions\PagingSpecExtensions.cs" />
|
||||
<Compile Include="Datastore\Extensions\RelationshipExtensions.cs" />
|
||||
<Compile Include="Datastore\IEmbeddedDocument.cs" />
|
||||
<Compile Include="Datastore\LazyList.cs" />
|
||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||
|
@ -24,15 +24,15 @@ public static class Parser
|
||||
|
||||
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
|
||||
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))(?<title>.+?)(?:(?:\W|_)+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
|
||||
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:\s|\.)(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.|$)+)+",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Anime - [SubGroup] Title Absolute Episode Number
|
||||
new Regex(@"^\[(?<subgroup>.+?)\](?:_|-|\s|\.)?(?<title>.+?)(?:(?:\W|_)+(?<absoluteepisode>\d{2,}))+",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Multi-Part episodes without a title (S01E05.S01E06)
|
||||
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}",
|
||||
@ -60,7 +60,7 @@ public static class Parser
|
||||
|
||||
//Anime - Title Absolute Episode Number [SubGroup]
|
||||
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{3}(?!\d+)))+(?:.+?)\[(?<subgroup>.+?)\](?:\.|$)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Supports 103/113 naming
|
||||
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+)\d{1})(?<episode>\d{2}(?!\w|\d+)))+",
|
||||
@ -97,7 +97,7 @@ public static class Parser
|
||||
|
||||
//Anime - Title Absolute Episode Number
|
||||
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+e(?<absoluteepisode>\d{2,3}))+",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled)
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled)
|
||||
};
|
||||
|
||||
private static readonly Regex[] RejectHashedReleasesRegex = new Regex[]
|
||||
@ -113,10 +113,16 @@ public static class Parser
|
||||
private static readonly Regex ReversedTitleRegex = new Regex(@"\.p027\.|\.p0801\.|\.\d{2}E\d{2}S\.", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex NormalizeRegex = new Regex(@"((?:\b|_)(?<!^)(a|an|the|and|or|of)(?:\b|_))|\W|_",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex SimpleTitleRegex = new Regex(@"480[i|p]|720[i|p]|1080[i|p]|[xh][\W_]?264|DD\W?5\W1|\<|\>|\?|\*|\:|\|",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex AirDateRegex = new Regex(@"^(.*?)(?<!\d)((?<airyear>\d{4})[_.-](?<airmonth>[0-1][0-9])[_.-](?<airday>[0-3][0-9])|(?<airmonth>[0-1][0-9])[_.-](?<airday>[0-3][0-9])[_.-](?<airyear>\d{4}))(?!\d)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?<releasegroup>[a-z0-9]+)\b(?<!WEB-DL|480p|720p|1080p)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex MultiPartCleanupRegex = new Regex(@"\(\d+\)$", RegexOptions.Compiled);
|
||||
|
||||
@ -124,14 +130,14 @@ public static class Parser
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex YearInTitleRegex = new Regex(@"^(?<title>.+?)(?:\W|_)?(?<year>\d{4})",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex WordDelimiterRegex = new Regex(@"(\s|\.|,|_|-|=|\|)+", RegexOptions.Compiled);
|
||||
private static readonly Regex PunctuationRegex = new Regex(@"[^\w\s]", RegexOptions.Compiled);
|
||||
private static readonly Regex CommonWordRegex = new Regex(@"\b(a|an|the|and|or|of)\b\s?",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
private static readonly Regex SpecialEpisodeWordRegex = new Regex(@"\b(part|special|edition)\b\s?",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
public static ParsedEpisodeInfo ParsePath(string path)
|
||||
{
|
||||
@ -180,6 +186,12 @@ public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
|
||||
var simpleTitle = SimpleTitleRegex.Replace(title, String.Empty);
|
||||
|
||||
var airDateMatch = AirDateRegex.Match(simpleTitle);
|
||||
if (airDateMatch.Success)
|
||||
{
|
||||
simpleTitle = airDateMatch.Groups[1].Value + airDateMatch.Groups["airyear"].Value + "." + airDateMatch.Groups["airmonth"].Value + "." + airDateMatch.Groups["airday"].Value;
|
||||
}
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(simpleTitle);
|
||||
@ -272,24 +284,13 @@ public static string ParseReleaseGroup(string title)
|
||||
|
||||
title = title.TrimEnd("-RP");
|
||||
|
||||
var index = title.LastIndexOf('-');
|
||||
|
||||
if (index < 0)
|
||||
index = title.LastIndexOf(' ');
|
||||
|
||||
if (index < 0)
|
||||
return defaultReleaseGroup;
|
||||
|
||||
var group = title.Substring(index + 1);
|
||||
|
||||
if (group.Length == title.Length)
|
||||
return String.Empty;
|
||||
|
||||
group = group.Trim('-', ' ', '[', ']');
|
||||
|
||||
if (group.ToLower() == "480p" ||
|
||||
group.ToLower() == "720p" ||
|
||||
group.ToLower() == "1080p")
|
||||
string group;
|
||||
var matches = ReleaseGroupRegex.Matches(title);
|
||||
if (matches.Count != 0)
|
||||
{
|
||||
group = matches.OfType<Match>().Last().Groups["releasegroup"].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return defaultReleaseGroup;
|
||||
}
|
||||
|
@ -13,37 +13,50 @@ public class QualityParser
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static readonly Regex SourceRegex = new Regex(@"(?<bluray>BluRay)|
|
||||
private static readonly Regex SourceRegex = new Regex(@"\b(?:
|
||||
(?<bluray>BluRay)|
|
||||
(?<webdl>WEB-DL|WEBDL|WEB\sDL|WEB\-DL|WebRip)|
|
||||
(?<hdtv>HDTV)|
|
||||
(?<bdrip>BDRiP)|(?<brrip>BRRip)|(?<dvd>\b(?:DVD|DVDRip|NTSC|PAL|xvidvd)\b)|
|
||||
(?<dsr>WS\sDSR|WS_DSR|WS\.DSR|DSR)|(?<pdtv>PDTV)|(?<sdtv>SDTV)",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
(?<bdrip>BDRiP)|
|
||||
(?<brrip>BRRip)|
|
||||
(?<dvd>DVD|DVDRip|NTSC|PAL|xvidvd)|
|
||||
(?<dsr>WS\sDSR|WS_DSR|WS\.DSR|DSR)|
|
||||
(?<pdtv>PDTV)|
|
||||
(?<sdtv>SDTV)
|
||||
)\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
private static readonly Regex ResolutionRegex = new Regex(@"(?<_480p>480p)|(?<_720p>720p)|(?<_1080p>1080p)",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex RawHDRegex = new Regex(@"\b(?<rawhd>TrollHD|RawHD)\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex CodecRegex = new Regex(@"(?<x264>x264)|(?<h264>h264)|(?<xvidhd>XvidHD)|(?<xvid>Xvid)|(?<divx>divx)",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex ProperRegex = new Regex(@"\b(?<proper>proper|repack)\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex ResolutionRegex = new Regex(@"\b(?:(?<_480p>480p)|(?<_720p>720p)|(?<_1080p>1080p))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<x264>x264)|(?<h264>h264)|(?<xvidhd>XvidHD)|(?<xvid>Xvid)|(?<divx>divx))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static QualityModel ParseQuality(string name)
|
||||
{
|
||||
Logger.Debug("Trying to parse quality for {0}", name);
|
||||
|
||||
name = name.Trim();
|
||||
var normalizedName = name.CleanSeriesTitle();
|
||||
var normalizedName = name.Replace('_', ' ').Trim().ToLower();
|
||||
var result = new QualityModel { Quality = Quality.Unknown };
|
||||
result.Proper = (normalizedName.Contains("proper") || normalizedName.Contains("repack"));
|
||||
|
||||
if (normalizedName.Contains("trollhd") || normalizedName.Contains("rawhd"))
|
||||
result.Proper = ProperRegex.IsMatch(normalizedName);
|
||||
|
||||
if (RawHDRegex.IsMatch(normalizedName))
|
||||
{
|
||||
result.Quality = Quality.RAWHD;
|
||||
return result;
|
||||
}
|
||||
|
||||
var sourceMatch = SourceRegex.Match(name);
|
||||
var resolution = ParseResolution(name);
|
||||
var codecRegex = CodecRegex.Match(name);
|
||||
|
||||
var sourceMatch = SourceRegex.Match(normalizedName);
|
||||
var resolution = ParseResolution(normalizedName);
|
||||
var codecRegex = CodecRegex.Match(normalizedName);
|
||||
|
||||
if (sourceMatch.Groups["bluray"].Success)
|
||||
{
|
||||
@ -111,9 +124,27 @@ public static QualityModel ParseQuality(string name)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sourceMatch.Groups["dvd"].Success ||
|
||||
sourceMatch.Groups["bdrip"].Success ||
|
||||
if (sourceMatch.Groups["bdrip"].Success ||
|
||||
sourceMatch.Groups["brrip"].Success)
|
||||
{
|
||||
if (resolution == Resolution._720p)
|
||||
{
|
||||
result.Quality = Quality.Bluray720p;
|
||||
return result;
|
||||
}
|
||||
else if (resolution == Resolution._1080p)
|
||||
{
|
||||
result.Quality = Quality.Bluray1080p;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Quality = Quality.DVD;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceMatch.Groups["dvd"].Success)
|
||||
{
|
||||
result.Quality = Quality.DVD;
|
||||
return result;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using System;
|
||||
using NzbDrone.Common.Cache;
|
||||
|
||||
namespace NzbDrone.Core.Qualities
|
||||
{
|
||||
@ -17,22 +18,31 @@ public interface IQualityDefinitionService
|
||||
public class QualityDefinitionService : IQualityDefinitionService, IHandle<ApplicationStartedEvent>
|
||||
{
|
||||
private readonly IQualityDefinitionRepository _qualityDefinitionRepository;
|
||||
private readonly ICached<Dictionary<Quality, QualityDefinition>> _cache;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public QualityDefinitionService(IQualityDefinitionRepository qualityDefinitionRepository, Logger logger)
|
||||
public QualityDefinitionService(IQualityDefinitionRepository qualityDefinitionRepository, ICacheManager cacheManager, Logger logger)
|
||||
{
|
||||
_qualityDefinitionRepository = qualityDefinitionRepository;
|
||||
_cache = cacheManager.GetCache<Dictionary<Quality, QualityDefinition>>(this.GetType());
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private Dictionary<Quality, QualityDefinition> GetAll()
|
||||
{
|
||||
return _cache.Get("all", () => _qualityDefinitionRepository.All().ToDictionary(v => v.Quality), TimeSpan.FromSeconds(5.0));
|
||||
}
|
||||
|
||||
public void Update(QualityDefinition qualityDefinition)
|
||||
{
|
||||
_qualityDefinitionRepository.Update(qualityDefinition);
|
||||
|
||||
_cache.Clear();
|
||||
}
|
||||
|
||||
public List<QualityDefinition> All()
|
||||
{
|
||||
return _qualityDefinitionRepository.All().ToList();
|
||||
return GetAll().Values.ToList();
|
||||
}
|
||||
|
||||
public QualityDefinition Get(Quality quality)
|
||||
@ -40,7 +50,7 @@ public QualityDefinition Get(Quality quality)
|
||||
if (quality == Quality.Unknown)
|
||||
return new QualityDefinition(Quality.Unknown);
|
||||
|
||||
return _qualityDefinitionRepository.GetByQualityId((int)quality);
|
||||
return GetAll()[quality];
|
||||
}
|
||||
|
||||
public void InsertMissingDefinitions(List<QualityDefinition> allDefinitions)
|
||||
@ -89,10 +99,12 @@ public void InsertMissingDefinitions(List<QualityDefinition> allDefinitions)
|
||||
_qualityDefinitionRepository.Update(existingDefinitions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_cache.Clear();
|
||||
}
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
{
|
||||
_logger.Debug("Setting up default quality config");
|
||||
|
||||
InsertMissingDefinitions(Quality.DefaultQualityDefinitions.ToList());
|
||||
|
@ -5,7 +5,7 @@
|
||||
using Marr.Data.QGen;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extentions;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
@ -27,7 +27,6 @@ public interface IEpisodeService
|
||||
List<Episode> GetEpisodesByFileId(int episodeFileId);
|
||||
void UpdateEpisode(Episode episode);
|
||||
void SetEpisodeMonitored(int episodeId, bool monitored);
|
||||
bool IsFirstOrLastEpisodeOfSeason(int episodeId);
|
||||
void UpdateEpisodes(List<Episode> episodes);
|
||||
List<Episode> EpisodesBetweenDates(DateTime start, DateTime end);
|
||||
void InsertMany(List<Episode> episodes);
|
||||
@ -141,19 +140,6 @@ public void SetEpisodeMonitoredBySeason(int seriesId, int seasonNumber, bool mon
|
||||
_episodeRepository.SetMonitoredBySeason(seriesId, seasonNumber, monitored);
|
||||
}
|
||||
|
||||
public bool IsFirstOrLastEpisodeOfSeason(int episodeId)
|
||||
{
|
||||
var episode = GetEpisode(episodeId);
|
||||
var seasonEpisodes = GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber);
|
||||
|
||||
//Ensure that this is either the first episode
|
||||
//or is the last episode in a season that has 10 or more episodes
|
||||
if (seasonEpisodes.First().EpisodeNumber == episode.EpisodeNumber || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().EpisodeNumber == episode.EpisodeNumber))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UpdateEpisodes(List<Episode> episodes)
|
||||
{
|
||||
_episodeRepository.UpdateMany(episodes);
|
||||
|
@ -4,6 +4,7 @@
|
||||
namespace NzbDrone.Mono.Test.DiskProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Mono")]
|
||||
public class DiskProviderFixture : DiskProviderFixtureBase<DiskProvider>
|
||||
{
|
||||
public DiskProviderFixture()
|
||||
|
@ -4,6 +4,7 @@
|
||||
namespace NzbDrone.Mono.Test.DiskProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Mono")]
|
||||
public class FreeSpaceFixture : FreeSpaceFixtureBase<DiskProvider>
|
||||
{
|
||||
public FreeSpaceFixture()
|
||||
|
@ -13,15 +13,13 @@ namespace NzbDrone.Mono.Test
|
||||
[TestFixture]
|
||||
public class ServiceFactoryFixture : TestBase<ServiceFactory>
|
||||
{
|
||||
[SetUp]
|
||||
public void setup()
|
||||
{
|
||||
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new StartupContext()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void event_handlers_should_be_unique()
|
||||
{
|
||||
MonoOnly();
|
||||
|
||||
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new StartupContext()));
|
||||
|
||||
var handlers = Subject.BuildAll<IHandle<ApplicationShutdownRequested>>()
|
||||
.Select(c => c.GetType().FullName);
|
||||
|
||||
|
@ -26,7 +26,7 @@ public static void Reset()
|
||||
_logs = new List<LogEventInfo>();
|
||||
}
|
||||
|
||||
public static void AssertNoUnexcpectedLogs()
|
||||
public static void AssertNoUnexpectedLogs()
|
||||
{
|
||||
ExpectedFatals(0);
|
||||
ExpectedErrors(0);
|
||||
|
@ -50,7 +50,7 @@ public void LoggingDownBase()
|
||||
//https://bugs.launchpad.net/nunitv2/+bug/1076932
|
||||
if (BuildInfo.IsDebug && TestContext.CurrentContext.Result.State == TestState.Success)
|
||||
{
|
||||
ExceptionVerification.AssertNoUnexcpectedLogs();
|
||||
ExceptionVerification.AssertNoUnexpectedLogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@
|
||||
<Compile Include="LoggingTest.cs" />
|
||||
<Compile Include="MockerExtensions.cs" />
|
||||
<Compile Include="NzbDroneRunner.cs" />
|
||||
<Compile Include="ObjectExtentions.cs" />
|
||||
<Compile Include="ObjectExtensions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReflectionExtensions.cs" />
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace NzbDrone.Test.Common
|
||||
{
|
||||
public static class ObjectExtentions
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
public static T JsonClone<T>(this T source) where T : new()
|
||||
{
|
@ -109,9 +109,15 @@ public void TestBaseTearDown()
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(TempFolder))
|
||||
var tempFolder = new DirectoryInfo(TempFolder);
|
||||
if (tempFolder.Exists)
|
||||
{
|
||||
Directory.Delete(TempFolder, true);
|
||||
foreach (var file in tempFolder.GetFiles("*", SearchOption.AllDirectories))
|
||||
{
|
||||
file.IsReadOnly = false;
|
||||
}
|
||||
|
||||
tempFolder.Delete(true);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
@ -119,7 +125,6 @@ public void TestBaseTearDown()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected IAppFolderInfo TestFolderInfo { get; private set; }
|
||||
|
||||
protected void WindowsOnly()
|
||||
@ -148,26 +153,11 @@ protected void WithTempAsAppPath()
|
||||
TestFolderInfo = Mocker.GetMock<IAppFolderInfo>().Object;
|
||||
}
|
||||
|
||||
protected string GetTestFilePath(string fileName)
|
||||
protected string GetTempFilePath()
|
||||
{
|
||||
return Path.Combine(SandboxFolder, fileName);
|
||||
return Path.Combine(TempFolder, Path.GetRandomFileName());
|
||||
}
|
||||
|
||||
protected string GetTestFilePath()
|
||||
{
|
||||
return GetTestFilePath(Path.GetRandomFileName());
|
||||
}
|
||||
|
||||
protected string SandboxFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
var folder = Path.Combine(Directory.GetCurrentDirectory(), "Files");
|
||||
Directory.CreateDirectory(folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
}
|
||||
protected void VerifyEventPublished<TEvent>() where TEvent : class, IEvent
|
||||
{
|
||||
VerifyEventPublished<TEvent>(Times.Once());
|
||||
|
@ -4,6 +4,7 @@
|
||||
namespace NzbDrone.Windows.Test.DiskProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Win")]
|
||||
public class DiskProviderFixture : DiskProviderFixtureBase<DiskProvider>
|
||||
{
|
||||
public DiskProviderFixture()
|
||||
|
@ -4,6 +4,7 @@
|
||||
namespace NzbDrone.Windows.Test.DiskProviderTests
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Win")]
|
||||
public class FreeSpaceFixture : FreeSpaceFixtureBase<DiskProvider>
|
||||
{
|
||||
public FreeSpaceFixture()
|
||||
|
@ -1,4 +1,4 @@
|
||||
<fieldset class="advanced-setting">
|
||||
<fieldset>
|
||||
<legend>File Management</legend>
|
||||
|
||||
<div class="control-group">
|
||||
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="control-group advanced-setting">
|
||||
<label class="control-label">Download Propers</label>
|
||||
|
||||
<div class="controls">
|
||||
@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="control-group advanced-setting">
|
||||
<label class="control-label">Change File Date</label>
|
||||
|
||||
<div class="controls">
|
||||
|
Loading…
Reference in New Issue
Block a user