mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-05 15:47:20 +02:00
Fixed: Some Tests and Added New Ones
This commit is contained in:
parent
a3f72bd4a0
commit
612d948eba
11
build.sh
11
build.sh
@ -52,15 +52,6 @@ CleanFolder()
|
|||||||
find $path -depth -empty -type d -exec rm -r "{}" \;
|
find $path -depth -empty -type d -exec rm -r "{}" \;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AddJsonNet()
|
|
||||||
{
|
|
||||||
rm $outputFolder/Newtonsoft.Json.*
|
|
||||||
cp $sourceFolder/packages/Newtonsoft.Json.*/lib/net35/*.dll $outputFolder
|
|
||||||
cp $sourceFolder/packages/Newtonsoft.Json.*/lib/net35/*.dll $outputFolder/NzbDrone.Update
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildWithMSBuild()
|
BuildWithMSBuild()
|
||||||
{
|
{
|
||||||
export PATH=$msBuild:$PATH
|
export PATH=$msBuild:$PATH
|
||||||
@ -115,8 +106,6 @@ Build()
|
|||||||
|
|
||||||
CleanFolder $outputFolder false
|
CleanFolder $outputFolder false
|
||||||
|
|
||||||
AddJsonNet
|
|
||||||
|
|
||||||
echo "Removing Mono.Posix.dll"
|
echo "Removing Mono.Posix.dll"
|
||||||
rm $outputFolder/Mono.Posix.dll
|
rm $outputFolder/Mono.Posix.dll
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using FluentAssertions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Common.Test.DiskTests
|
namespace NzbDrone.Common.Test.DiskTests
|
||||||
{
|
{
|
||||||
@ -16,6 +18,7 @@ public class DiskTransferServiceFixture : TestBase<DiskTransferService>
|
|||||||
private readonly string _targetPath = @"C:\target\my.video.mkv".AsOsAgnostic();
|
private readonly string _targetPath = @"C:\target\my.video.mkv".AsOsAgnostic();
|
||||||
private readonly string _backupPath = @"C:\source\my.video.mkv.backup~".AsOsAgnostic();
|
private readonly string _backupPath = @"C:\source\my.video.mkv.backup~".AsOsAgnostic();
|
||||||
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
||||||
|
private readonly string _nfsFile = ".nfs01231232";
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
@ -237,7 +240,7 @@ public void mode_none_should_throw_if_existing_target_when_not_overwriting()
|
|||||||
|
|
||||||
WithExistingFile(_targetPath);
|
WithExistingFile(_targetPath);
|
||||||
|
|
||||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move, false));
|
Assert.Throws<DestinationAlreadyExistsException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move, false));
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Verify(v => v.DeleteFile(_targetPath), Times.Never());
|
.Verify(v => v.DeleteFile(_targetPath), Times.Never());
|
||||||
@ -642,6 +645,21 @@ public void CopyFolder_should_overwrite_existing_folder()
|
|||||||
VerifyCopyFolder(source.FullName, destination.FullName);
|
VerifyCopyFolder(source.FullName, destination.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CopyFolder_should_ignore_nfs_temp_file()
|
||||||
|
{
|
||||||
|
WithRealDiskProvider();
|
||||||
|
|
||||||
|
var source = GetFilledTempFolder();
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(source.FullName, _nfsFile), "SubFile1");
|
||||||
|
|
||||||
|
var destination = new DirectoryInfo(GetTempFilePath());
|
||||||
|
|
||||||
|
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Copy);
|
||||||
|
|
||||||
|
File.Exists(Path.Combine(destination.FullName, _nfsFile)).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MoveFolder_should_move_folder()
|
public void MoveFolder_should_move_folder()
|
||||||
@ -704,6 +722,26 @@ public void MirrorFolder_should_remove_additional_files()
|
|||||||
destination.GetFileSystemInfos().Should().BeEmpty();
|
destination.GetFileSystemInfos().Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MirrorFolder_should_not_remove_nfs_files()
|
||||||
|
{
|
||||||
|
WithRealDiskProvider();
|
||||||
|
|
||||||
|
var original = GetFilledTempFolder();
|
||||||
|
var source = new DirectoryInfo(GetTempFilePath());
|
||||||
|
var destination = new DirectoryInfo(GetTempFilePath());
|
||||||
|
|
||||||
|
source.Create();
|
||||||
|
Subject.TransferFolder(original.FullName, destination.FullName, TransferMode.Copy);
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(destination.FullName, _nfsFile), "SubFile1");
|
||||||
|
|
||||||
|
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||||
|
|
||||||
|
count.Should().Equals(0);
|
||||||
|
destination.GetFileSystemInfos().Should().HaveCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MirrorFolder_should_add_new_files()
|
public void MirrorFolder_should_add_new_files()
|
||||||
{
|
{
|
||||||
@ -721,6 +759,24 @@ public void MirrorFolder_should_add_new_files()
|
|||||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MirrorFolder_should_ignore_nfs_temp_file()
|
||||||
|
{
|
||||||
|
WithRealDiskProvider();
|
||||||
|
|
||||||
|
var source = GetFilledTempFolder();
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(source.FullName, _nfsFile), "SubFile1");
|
||||||
|
|
||||||
|
var destination = new DirectoryInfo(GetTempFilePath());
|
||||||
|
|
||||||
|
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||||
|
|
||||||
|
count.Should().Equals(3);
|
||||||
|
|
||||||
|
File.Exists(Path.Combine(destination.FullName, _nfsFile)).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MirrorFolder_should_not_touch_equivalent_files()
|
public void MirrorFolder_should_not_touch_equivalent_files()
|
||||||
{
|
{
|
||||||
@ -740,6 +796,75 @@ public void MirrorFolder_should_not_touch_equivalent_files()
|
|||||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TransferFolder_should_use_movefolder_if_on_same_mount()
|
||||||
|
{
|
||||||
|
WithEmulatedDiskProvider();
|
||||||
|
|
||||||
|
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
|
||||||
|
var dst = @"C:\Base1\TestDir2".AsOsAgnostic();
|
||||||
|
|
||||||
|
WithMockMount(@"C:\Base1".AsOsAgnostic());
|
||||||
|
WithExistingFile(@"C:\Base1\TestDir1\test.file.txt".AsOsAgnostic());
|
||||||
|
|
||||||
|
Subject.TransferFolder(src, dst, TransferMode.Move);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.MoveFolder(src, dst, false), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TransferFolder_should_not_use_movefolder_if_on_same_mount_but_target_already_exists()
|
||||||
|
{
|
||||||
|
WithEmulatedDiskProvider();
|
||||||
|
|
||||||
|
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
|
||||||
|
var dst = @"C:\Base1\TestDir2".AsOsAgnostic();
|
||||||
|
|
||||||
|
WithMockMount(@"C:\Base1".AsOsAgnostic());
|
||||||
|
WithExistingFile(@"C:\Base1\TestDir1\test.file.txt".AsOsAgnostic());
|
||||||
|
WithExistingFolder(dst);
|
||||||
|
|
||||||
|
Subject.TransferFolder(src, dst, TransferMode.Move);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.MoveFolder(src, dst, false), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TransferFolder_should_not_use_movefolder_if_on_same_mount_but_transactional()
|
||||||
|
{
|
||||||
|
WithEmulatedDiskProvider();
|
||||||
|
|
||||||
|
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
|
||||||
|
var dst = @"C:\Base1\TestDir2".AsOsAgnostic();
|
||||||
|
|
||||||
|
WithMockMount(@"C:\Base1".AsOsAgnostic());
|
||||||
|
WithExistingFile(@"C:\Base1\TestDir1\test.file.txt".AsOsAgnostic());
|
||||||
|
|
||||||
|
Subject.TransferFolder(src, dst, TransferMode.Move, DiskTransferVerificationMode.Transactional);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.MoveFolder(src, dst, false), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TransferFolder_should_not_use_movefolder_if_on_different_mount()
|
||||||
|
{
|
||||||
|
WithEmulatedDiskProvider();
|
||||||
|
|
||||||
|
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
|
||||||
|
var dst = @"C:\Base2\TestDir2".AsOsAgnostic();
|
||||||
|
|
||||||
|
WithMockMount(@"C:\Base1".AsOsAgnostic());
|
||||||
|
WithMockMount(@"C:\Base2".AsOsAgnostic());
|
||||||
|
|
||||||
|
Subject.TransferFolder(src, dst, TransferMode.Move);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.MoveFolder(src, dst, false), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
public DirectoryInfo GetFilledTempFolder()
|
public DirectoryInfo GetFilledTempFolder()
|
||||||
{
|
{
|
||||||
var tempFolder = GetTempFilePath();
|
var tempFolder = GetTempFilePath();
|
||||||
@ -756,8 +881,23 @@ public DirectoryInfo GetFilledTempFolder()
|
|||||||
return new DirectoryInfo(tempFolder);
|
return new DirectoryInfo(tempFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WithExistingFolder(string path, bool exists = true)
|
||||||
|
{
|
||||||
|
var dir = Path.GetDirectoryName(path);
|
||||||
|
if (exists && dir.IsNotNullOrWhiteSpace())
|
||||||
|
WithExistingFolder(dir);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.FolderExists(path))
|
||||||
|
.Returns(exists);
|
||||||
|
}
|
||||||
|
|
||||||
private void WithExistingFile(string path, bool exists = true, int size = 1000)
|
private void WithExistingFile(string path, bool exists = true, int size = 1000)
|
||||||
{
|
{
|
||||||
|
var dir = Path.GetDirectoryName(path);
|
||||||
|
if (exists && dir.IsNotNullOrWhiteSpace())
|
||||||
|
WithExistingFolder(dir);
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(v => v.FileExists(path))
|
.Setup(v => v.FileExists(path))
|
||||||
.Returns(exists);
|
.Returns(exists);
|
||||||
@ -809,6 +949,45 @@ private void WithEmulatedDiskProvider()
|
|||||||
{
|
{
|
||||||
WithExistingFile(v, false);
|
WithExistingFile(v, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.FolderExists(It.IsAny<string>()))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.CreateFolder(It.IsAny<string>()))
|
||||||
|
.Callback<string>((f) =>
|
||||||
|
{
|
||||||
|
WithExistingFolder(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.MoveFolder(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||||
|
.Callback<string, string, bool>((s, d, b) =>
|
||||||
|
{
|
||||||
|
WithExistingFolder(s, false);
|
||||||
|
WithExistingFolder(d);
|
||||||
|
// Note: Should also deal with the files.
|
||||||
|
});
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.DeleteFolder(It.IsAny<string>(), It.IsAny<bool>()))
|
||||||
|
.Callback<string, bool>((f, r) =>
|
||||||
|
{
|
||||||
|
WithExistingFolder(f, false);
|
||||||
|
// Note: Should also deal with the files.
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note: never returns anything.
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.GetDirectoryInfos(It.IsAny<string>()))
|
||||||
|
.Returns(new List<DirectoryInfo>());
|
||||||
|
|
||||||
|
// Note: never returns anything.
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.GetFileInfos(It.IsAny<string>()))
|
||||||
|
.Returns(new List<FileInfo>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithRealDiskProvider()
|
private void WithRealDiskProvider()
|
||||||
@ -865,6 +1044,18 @@ private void WithRealDiskProvider()
|
|||||||
.Returns<string>(s => new FileStream(s, FileMode.Open, FileAccess.Read));
|
.Returns<string>(s => new FileStream(s, FileMode.Open, FileAccess.Read));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WithMockMount(string root)
|
||||||
|
{
|
||||||
|
var rootDir = root;
|
||||||
|
var mock = new Mock<IMount>();
|
||||||
|
mock.SetupGet(v => v.RootDirectory)
|
||||||
|
.Returns(rootDir);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.GetMount(It.Is<string>(s => s.StartsWith(rootDir))))
|
||||||
|
.Returns(mock.Object);
|
||||||
|
}
|
||||||
|
|
||||||
private void VerifyCopyFolder(string source, string destination)
|
private void VerifyCopyFolder(string source, string destination)
|
||||||
{
|
{
|
||||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||||
|
@ -32,7 +32,7 @@ public void should_get_free_space_for_folder_that_doesnt_exist()
|
|||||||
public void should_be_able_to_check_space_on_ramdrive()
|
public void should_be_able_to_check_space_on_ramdrive()
|
||||||
{
|
{
|
||||||
MonoOnly();
|
MonoOnly();
|
||||||
Subject.GetAvailableSpace("/").Should().NotBe(0);
|
Subject.GetAvailableSpace("/run/").Should().NotBe(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Ignore("Docker")]
|
[Ignore("Docker")]
|
||||||
@ -62,7 +62,7 @@ public void should_throw_if_drive_doesnt_exist()
|
|||||||
{
|
{
|
||||||
if (new DriveInfo(driveletter.ToString()).IsReady)
|
if (new DriveInfo(driveletter.ToString()).IsReady)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(driveletter + @":\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvailableSpace(driveletter + @":\NOT_A_REAL_PATH\DOES_NOT_EXIST".AsOsAgnostic()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ public class BuildInfoFixture
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_return_version()
|
public void should_return_version()
|
||||||
{
|
{
|
||||||
BuildInfo.Version.Major.Should().BeOneOf(0, 10);
|
BuildInfo.Version.Major.Should().BeOneOf(2, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_get_branch()
|
public void should_get_branch()
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,13 @@ namespace NzbDrone.Common.Test.Http
|
|||||||
{
|
{
|
||||||
public class HttpUriFixture : TestBase
|
public class HttpUriFixture : TestBase
|
||||||
{
|
{
|
||||||
|
[TestCase("abc://my_host.com:8080/root/api/")]
|
||||||
|
public void should_parse(string uri)
|
||||||
|
{
|
||||||
|
var newUri = new HttpUri(uri);
|
||||||
|
newUri.FullUri.Should().Be(uri);
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase("", "", "")]
|
[TestCase("", "", "")]
|
||||||
[TestCase("/", "", "/")]
|
[TestCase("/", "", "/")]
|
||||||
[TestCase("base", "", "base")]
|
[TestCase("base", "", "base")]
|
||||||
@ -77,7 +84,7 @@ public void should_combine_uri(string basePath, string relativePath, string expe
|
|||||||
public void should_combine_relative_path(string basePath, string relativePath, string expected)
|
public void should_combine_relative_path(string basePath, string relativePath, string expected)
|
||||||
{
|
{
|
||||||
var newUri = new HttpUri(basePath).CombinePath(relativePath);
|
var newUri = new HttpUri(basePath).CombinePath(relativePath);
|
||||||
|
|
||||||
newUri.FullUri.Should().Be(expected);
|
newUri.FullUri.Should().Be(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ public void DownloadString_should_be_able_to_dowload_text_file()
|
|||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("")]
|
[TestCase("")]
|
||||||
|
[TestCase("http://")]
|
||||||
public void DownloadString_should_throw_on_error(string url)
|
public void DownloadString_should_throw_on_error(string url)
|
||||||
{
|
{
|
||||||
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
||||||
|
@ -16,7 +16,6 @@ public static class PathExtensions
|
|||||||
private const string LOG_DB = "logs.db";
|
private const string LOG_DB = "logs.db";
|
||||||
private const string NLOG_CONFIG_FILE = "nlog.config";
|
private const string NLOG_CONFIG_FILE = "nlog.config";
|
||||||
private const string UPDATE_CLIENT_EXE = "Radarr.Update.exe";
|
private const string UPDATE_CLIENT_EXE = "Radarr.Update.exe";
|
||||||
private const string BACKUP_FOLDER = "Backups";
|
|
||||||
|
|
||||||
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "radarr_update" + Path.DirectorySeparatorChar;
|
private static readonly string UPDATE_SANDBOX_FOLDER_NAME = "radarr_update" + Path.DirectorySeparatorChar;
|
||||||
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "Radarr" + Path.DirectorySeparatorChar;
|
private static readonly string UPDATE_PACKAGE_FOLDER_NAME = "Radarr" + Path.DirectorySeparatorChar;
|
||||||
|
@ -7,7 +7,7 @@ public static class TryParseExtensions
|
|||||||
{
|
{
|
||||||
public static int? ParseInt32(this string source)
|
public static int? ParseInt32(this string source)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result;
|
||||||
|
|
||||||
if (int.TryParse(source, out result))
|
if (int.TryParse(source, out result))
|
||||||
{
|
{
|
||||||
@ -17,9 +17,9 @@ public static class TryParseExtensions
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Nullable<long> ParseInt64(this string source)
|
public static long? ParseInt64(this string source)
|
||||||
{
|
{
|
||||||
long result = 0;
|
long result;
|
||||||
|
|
||||||
if (long.TryParse(source, out result))
|
if (long.TryParse(source, out result))
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||||
{
|
{
|
||||||
@ -36,7 +39,7 @@ private Movie GetMovie(int id)
|
|||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private RemoteMovie GetRemoteMovie(QualityModel quality, Movie movie = null)
|
private RemoteMovie GetRemoteMovie(QualityModel quality, Movie movie = null, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
|
||||||
{
|
{
|
||||||
if (movie == null)
|
if (movie == null)
|
||||||
{
|
{
|
||||||
@ -54,12 +57,13 @@ private RemoteMovie GetRemoteMovie(QualityModel quality, Movie movie = null)
|
|||||||
MovieTitle = "A Movie",
|
MovieTitle = "A Movie",
|
||||||
},
|
},
|
||||||
Movie = movie,
|
Movie = movie,
|
||||||
|
|
||||||
Release = new ReleaseInfo()
|
Release = new ReleaseInfo()
|
||||||
{
|
{
|
||||||
PublishDate = DateTime.UtcNow,
|
PublishDate = DateTime.UtcNow,
|
||||||
Title = "A.Movie.1998",
|
Title = "A.Movie.1998",
|
||||||
Size = 200
|
Size = 200,
|
||||||
|
DownloadProtocol = downloadProtocol
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,6 +95,25 @@ public void should_only_download_movie_once()
|
|||||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_download_if_any_movie_was_already_downloaded()
|
||||||
|
{
|
||||||
|
var remoteMovie1 = GetRemoteMovie(
|
||||||
|
new QualityModel(Quality.HDTV720p)
|
||||||
|
);
|
||||||
|
|
||||||
|
var remoteMovie2 = GetRemoteMovie(
|
||||||
|
new QualityModel(Quality.HDTV720p)
|
||||||
|
);
|
||||||
|
|
||||||
|
var decisions = new List<DownloadDecision>();
|
||||||
|
decisions.Add(new DownloadDecision(remoteMovie1));
|
||||||
|
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||||
|
|
||||||
|
Subject.ProcessDecisions(decisions);
|
||||||
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_downloaded_reports()
|
public void should_return_downloaded_reports()
|
||||||
{
|
{
|
||||||
@ -179,7 +202,6 @@ public void should_not_grab_if_pending()
|
|||||||
|
|
||||||
var decisions = new List<DownloadDecision>();
|
var decisions = new List<DownloadDecision>();
|
||||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
||||||
decisions.Add(new DownloadDecision(remoteMovie));
|
|
||||||
|
|
||||||
Subject.ProcessDecisions(decisions);
|
Subject.ProcessDecisions(decisions);
|
||||||
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Never());
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Never());
|
||||||
@ -201,15 +223,68 @@ public void should_not_add_to_pending_if_movie_was_grabbed()
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_add_to_pending_even_if_already_added_to_pending()
|
public void should_add_to_pending_even_if_already_added_to_pending()
|
||||||
{
|
{
|
||||||
|
var remoteEpisode = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||||
|
|
||||||
|
var decisions = new List<DownloadDecision>();
|
||||||
|
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||||
|
decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary)));
|
||||||
|
|
||||||
|
Subject.ProcessDecisions(decisions);
|
||||||
|
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.AddMany(It.IsAny<List<Tuple<DownloadDecision, PendingReleaseReason>>>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_add_to_failed_if_already_failed_for_that_protocol()
|
||||||
|
{
|
||||||
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||||
|
|
||||||
var decisions = new List<DownloadDecision>();
|
var decisions = new List<DownloadDecision>();
|
||||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
decisions.Add(new DownloadDecision(remoteMovie));
|
||||||
decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary)));
|
decisions.Add(new DownloadDecision(remoteMovie));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>()))
|
||||||
|
.Throws(new DownloadClientUnavailableException("Download client failed"));
|
||||||
|
|
||||||
Subject.ProcessDecisions(decisions);
|
Subject.ProcessDecisions(decisions);
|
||||||
Mocker.GetMock<IPendingReleaseService>().Verify(v => v.AddMany(It.IsAny<List<Tuple<DownloadDecision, PendingReleaseReason>>>()), Times.Exactly(2));
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.IsAny<RemoteMovie>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_add_to_failed_if_failed_for_a_different_protocol()
|
||||||
|
{
|
||||||
|
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Usenet);
|
||||||
|
var remoteMovie2 = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Torrent);
|
||||||
|
|
||||||
|
var decisions = new List<DownloadDecision>();
|
||||||
|
decisions.Add(new DownloadDecision(remoteMovie));
|
||||||
|
decisions.Add(new DownloadDecision(remoteMovie2));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadService>().Setup(s => s.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)))
|
||||||
|
.Throws(new DownloadClientUnavailableException("Download client failed"));
|
||||||
|
|
||||||
|
Subject.ProcessDecisions(decisions);
|
||||||
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)), Times.Once());
|
||||||
|
Mocker.GetMock<IDownloadService>().Verify(v => v.DownloadReport(It.Is<RemoteMovie>(r => r.Release.DownloadProtocol == DownloadProtocol.Torrent)), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_add_to_rejected_if_release_unavailable_on_indexer()
|
||||||
|
{
|
||||||
|
var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p));
|
||||||
|
|
||||||
|
var decisions = new List<DownloadDecision>();
|
||||||
|
decisions.Add(new DownloadDecision(remoteMovie));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadService>()
|
||||||
|
.Setup(s => s.DownloadReport(It.IsAny<RemoteMovie>()))
|
||||||
|
.Throws(new ReleaseUnavailableException(remoteMovie.Release, "That 404 Error is not just a Quirk"));
|
||||||
|
|
||||||
|
var result = Subject.ProcessDecisions(decisions);
|
||||||
|
|
||||||
|
result.Grabbed.Should().BeEmpty();
|
||||||
|
result.Rejected.Should().NotBeEmpty();
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ public void completed_download_should_have_required_properties()
|
|||||||
var item = Subject.GetItems().Single();
|
var item = Subject.GetItems().Single();
|
||||||
VerifyCompleted(item);
|
VerifyCompleted(item);
|
||||||
|
|
||||||
item.CanBeRemoved.Should().BeTrue();
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
item.CanMoveFiles.Should().BeTrue();
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -66,9 +66,9 @@ public void Download_should_return_unique_id()
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Download_with_TvDirectory_should_force_directory()
|
public void Download_with_MovieDirectory_should_force_directory()
|
||||||
{
|
{
|
||||||
GivenTvDirectory();
|
GivenMovieDirectory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteMovie = CreateRemoteMovie();
|
var remoteMovie = CreateRemoteMovie();
|
||||||
@ -84,7 +84,7 @@ public void Download_with_TvDirectory_should_force_directory()
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_with_category_should_force_directory()
|
public void Download_with_category_should_force_directory()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteMovie = CreateRemoteMovie();
|
var remoteMovie = CreateRemoteMovie();
|
||||||
@ -100,7 +100,7 @@ public void Download_with_category_should_force_directory()
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_with_category_should_not_have_double_slashes()
|
public void Download_with_category_should_not_have_double_slashes()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
_transmissionConfigItems["download-dir"] += "/";
|
_transmissionConfigItems["download-dir"] += "/";
|
||||||
@ -175,7 +175,7 @@ public void GetItems_should_return_downloading_item_as_downloadItemStatus(Transm
|
|||||||
item.Status.Should().Be(expectedItemStatus);
|
item.Status.Should().Be(expectedItemStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, true)]
|
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, false)]
|
||||||
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, false)]
|
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, false)]
|
||||||
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, false)]
|
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, false)]
|
||||||
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, false)]
|
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, false)]
|
||||||
@ -207,7 +207,7 @@ public void should_return_status_with_outputdirs()
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_exclude_items_not_in_category()
|
public void should_exclude_items_not_in_category()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
|
|
||||||
_downloading.DownloadDir = @"C:/Downloads/Finished/transmission/radarr";
|
_downloading.DownloadDir = @"C:/Downloads/Finished/transmission/radarr";
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ public void should_exclude_items_not_in_category()
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_exclude_items_not_in_TvDirectory()
|
public void should_exclude_items_not_in_TvDirectory()
|
||||||
{
|
{
|
||||||
GivenTvDirectory();
|
GivenMovieDirectory();
|
||||||
|
|
||||||
_downloading.DownloadDir = @"C:/Downloads/Finished/radarr/subdir";
|
_downloading.DownloadDir = @"C:/Downloads/Finished/radarr/subdir";
|
||||||
|
|
||||||
@ -283,5 +283,139 @@ public void should_ignore_negative_eta(int eta)
|
|||||||
var item = Subject.GetItems().Single();
|
var item = Subject.GetItems().Single();
|
||||||
item.RemainingTime.Should().NotHaveValue();
|
item.RemainingTime.Should().NotHaveValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_reached_and_not_stopped()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(1.0);
|
||||||
|
PrepareClientToReturnCompletedItem(false, ratio: 1.0);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits();
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 1.0);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(1.0);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 1.0);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(2.0);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 1.0, ratioLimit: 0.8);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(0.2);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 0.5, ratioLimit: 0.8);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_and_should_not_allow_move_files_if_max_idletime_reached_and_not_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(null, 20);
|
||||||
|
PrepareClientToReturnCompletedItem(false, ratio: 2.0, seedingTime: 30);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_allow_move_files_if_max_idletime_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(null, 20);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 2.0, seedingTime: 20);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_allow_move_files_if_overridden_max_idletime_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(null, 40);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 2.0, seedingTime: 20, idleLimit: 10);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_not_allow_move_files_if_overridden_max_idletime_reached_and_not_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(null, 40);
|
||||||
|
PrepareClientToReturnCompletedItem(false, ratio: 2.0, seedingTime: 20, idleLimit: 10);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_if_overridden_max_idletime_not_reached_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(null, 20);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 2.0, seedingTime: 30, idleLimit: 40);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_be_removable_if_max_idletime_reached_but_ratio_not_and_not_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(2.0, 20);
|
||||||
|
PrepareClientToReturnCompletedItem(false, ratio: 1.0, seedingTime: 30);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeFalse();
|
||||||
|
item.CanMoveFiles.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_be_removable_and_should_allow_move_files_if_max_idletime_configured_and_paused()
|
||||||
|
{
|
||||||
|
GivenGlobalSeedLimits(2.0, 20);
|
||||||
|
PrepareClientToReturnCompletedItem(true, ratio: 1.0, seedingTime: 30);
|
||||||
|
|
||||||
|
var item = Subject.GetItems().Single();
|
||||||
|
item.CanBeRemoved.Should().BeTrue();
|
||||||
|
item.CanMoveFiles.Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.Clients.Transmission;
|
using NzbDrone.Core.Download.Clients.Transmission;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
@ -72,11 +73,13 @@ public void Setup()
|
|||||||
{
|
{
|
||||||
HashString = "HASH",
|
HashString = "HASH",
|
||||||
IsFinished = true,
|
IsFinished = true,
|
||||||
Status = TransmissionTorrentStatus.Stopped,
|
Status = TransmissionTorrentStatus.Seeding,
|
||||||
Name = _title,
|
Name = _title,
|
||||||
TotalSize = 1000,
|
TotalSize = 1000,
|
||||||
LeftUntilDone = 0,
|
LeftUntilDone = 0,
|
||||||
DownloadDir = "somepath"
|
DownloadDir = "somepath",
|
||||||
|
DownloadedEver = 1000,
|
||||||
|
UploadedEver = 900
|
||||||
};
|
};
|
||||||
|
|
||||||
_magnet = new TransmissionTorrent
|
_magnet = new TransmissionTorrent
|
||||||
@ -106,16 +109,16 @@ public void Setup()
|
|||||||
|
|
||||||
Mocker.GetMock<ITransmissionProxy>()
|
Mocker.GetMock<ITransmissionProxy>()
|
||||||
.Setup(v => v.GetConfig(It.IsAny<TransmissionSettings>()))
|
.Setup(v => v.GetConfig(It.IsAny<TransmissionSettings>()))
|
||||||
.Returns(_transmissionConfigItems);
|
.Returns(() => Json.Deserialize<TransmissionConfig>(_transmissionConfigItems.ToJson()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GivenTvCategory()
|
protected void GivenMovieCategory()
|
||||||
{
|
{
|
||||||
_settings.MovieCategory = "radarr";
|
_settings.MovieCategory = "radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GivenTvDirectory()
|
protected void GivenMovieDirectory()
|
||||||
{
|
{
|
||||||
_settings.MovieDirectory = @"C:/Downloads/Finished/radarr";
|
_settings.MovieDirectory = @"C:/Downloads/Finished/radarr";
|
||||||
}
|
}
|
||||||
@ -178,8 +181,40 @@ protected void PrepareClientToReturnFailedItem()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void PrepareClientToReturnCompletedItem()
|
protected void PrepareClientToReturnCompletedItem(bool stopped = false, double ratio = 0.9, int seedingTime = 60, double? ratioLimit = null, int? idleLimit = null)
|
||||||
{
|
{
|
||||||
|
if (stopped)
|
||||||
|
_completed.Status = TransmissionTorrentStatus.Stopped;
|
||||||
|
_completed.UploadedEver = (int)(_completed.DownloadedEver * ratio);
|
||||||
|
_completed.SecondsSeeding = seedingTime * 60;
|
||||||
|
|
||||||
|
if (ratioLimit.HasValue)
|
||||||
|
{
|
||||||
|
if (double.IsPositiveInfinity(ratioLimit.Value))
|
||||||
|
{
|
||||||
|
_completed.SeedRatioMode = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_completed.SeedRatioMode = 1;
|
||||||
|
_completed.SeedRatioLimit = ratioLimit.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idleLimit.HasValue)
|
||||||
|
{
|
||||||
|
if (double.IsPositiveInfinity(idleLimit.Value))
|
||||||
|
{
|
||||||
|
_completed.SeedIdleMode = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_completed.SeedIdleMode = 1;
|
||||||
|
_completed.SeedIdleLimit = idleLimit.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GivenTorrents(new List<TransmissionTorrent>
|
GivenTorrents(new List<TransmissionTorrent>
|
||||||
{
|
{
|
||||||
_completed
|
_completed
|
||||||
@ -193,5 +228,20 @@ protected void PrepareClientToReturnMagnetItem()
|
|||||||
_magnet
|
_magnet
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void GivenGlobalSeedLimits(double? ratioLimit = null, int? idleLimit = null)
|
||||||
|
{
|
||||||
|
_transmissionConfigItems["seedRatioLimited"] = ratioLimit.HasValue;
|
||||||
|
if (ratioLimit.HasValue)
|
||||||
|
{
|
||||||
|
_transmissionConfigItems["seedRatioLimit"] = ratioLimit.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_transmissionConfigItems["idle-seeding-limit-enabled"] = idleLimit.HasValue;
|
||||||
|
if (idleLimit.HasValue)
|
||||||
|
{
|
||||||
|
_transmissionConfigItems["idle-seeding-limit"] = idleLimit.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -74,7 +74,7 @@ public void Download_should_return_unique_id()
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_with_TvDirectory_should_force_directory()
|
public void Download_with_TvDirectory_should_force_directory()
|
||||||
{
|
{
|
||||||
GivenTvDirectory();
|
GivenMovieDirectory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteMovie = CreateRemoteMovie();
|
var remoteMovie = CreateRemoteMovie();
|
||||||
@ -90,7 +90,7 @@ public void Download_with_TvDirectory_should_force_directory()
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_with_category_should_force_directory()
|
public void Download_with_category_should_force_directory()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteMovie = CreateRemoteMovie();
|
var remoteMovie = CreateRemoteMovie();
|
||||||
@ -106,7 +106,7 @@ public void Download_with_category_should_force_directory()
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_with_category_should_not_have_double_slashes()
|
public void Download_with_category_should_not_have_double_slashes()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
_transmissionConfigItems["download-dir"] += "/";
|
_transmissionConfigItems["download-dir"] += "/";
|
||||||
@ -213,7 +213,7 @@ public void should_return_status_with_outputdirs()
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_exclude_items_not_in_category()
|
public void should_exclude_items_not_in_category()
|
||||||
{
|
{
|
||||||
GivenTvCategory();
|
GivenMovieCategory();
|
||||||
|
|
||||||
_downloading.DownloadDir = @"C:/Downloads/Finished/transmission/radarr";
|
_downloading.DownloadDir = @"C:/Downloads/Finished/transmission/radarr";
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ public void should_exclude_items_not_in_category()
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_exclude_items_not_in_TvDirectory()
|
public void should_exclude_items_not_in_TvDirectory()
|
||||||
{
|
{
|
||||||
GivenTvDirectory();
|
GivenMovieDirectory();
|
||||||
|
|
||||||
_downloading.DownloadDir = @"C:/Downloads/Finished/radarr/subdir";
|
_downloading.DownloadDir = @"C:/Downloads/Finished/radarr/subdir";
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
{
|
{
|
||||||
@ -70,6 +72,7 @@ public void should_not_delete_metadata_files_that_have_a_coresponding_movie_file
|
|||||||
|
|
||||||
var movieFile = Builder<MovieFile>.CreateNew()
|
var movieFile = Builder<MovieFile>.CreateNew()
|
||||||
.With(h => h.Quality = new QualityModel())
|
.With(h => h.Quality = new QualityModel())
|
||||||
|
.With(h => h.Languages = new List<Language>())
|
||||||
.BuildNew();
|
.BuildNew();
|
||||||
|
|
||||||
Db.Insert(movie);
|
Db.Insert(movie);
|
||||||
|
@ -22,7 +22,7 @@ public class ReleaseGroupParserFixture : CoreTest
|
|||||||
[TestCase("The Colbert Report - 2014-06-02 - Thomas Piketty.mkv", null)]
|
[TestCase("The Colbert Report - 2014-06-02 - Thomas Piketty.mkv", null)]
|
||||||
[TestCase("Real Time with Bill Maher S12E17 May 23, 2014.mp4", null)]
|
[TestCase("Real Time with Bill Maher S12E17 May 23, 2014.mp4", null)]
|
||||||
[TestCase("Reizen Waes - S01E08 - Transistri\u00EB, Zuid-Osseti\u00EB en Abchazi\u00EB SDTV.avi", null)]
|
[TestCase("Reizen Waes - S01E08 - Transistri\u00EB, Zuid-Osseti\u00EB en Abchazi\u00EB SDTV.avi", null)]
|
||||||
[TestCase("Simpsons 10x11 - Wild Barts Cant Be Broken [rl].avi", null)]
|
[TestCase("Simpsons 10x11 - Wild Barts Cant Be Broken [rl].avi", "rl")]
|
||||||
[TestCase("[ www.Torrenting.com ] - Revenge.S03E14.720p.HDTV.X264-DIMENSION", "DIMENSION")]
|
[TestCase("[ www.Torrenting.com ] - Revenge.S03E14.720p.HDTV.X264-DIMENSION", "DIMENSION")]
|
||||||
[TestCase("Seed S02E09 HDTV x264-2HD [eztv]-[rarbg.com]", "2HD")]
|
[TestCase("Seed S02E09 HDTV x264-2HD [eztv]-[rarbg.com]", "2HD")]
|
||||||
[TestCase("7s-atlantis-s02e01-720p.mkv", null)]
|
[TestCase("7s-atlantis-s02e01-720p.mkv", null)]
|
||||||
@ -32,6 +32,11 @@ public class ReleaseGroupParserFixture : CoreTest
|
|||||||
[TestCase("Who.is.America.S01E01.INTERNAL.720p.HDTV.x264-aAF-RakuvUS-Obfuscated", "aAF")]
|
[TestCase("Who.is.America.S01E01.INTERNAL.720p.HDTV.x264-aAF-RakuvUS-Obfuscated", "aAF")]
|
||||||
[TestCase("Haunted.Hayride.2018.720p.WEBRip.DDP5.1.x264-NTb-postbot", "NTb")]
|
[TestCase("Haunted.Hayride.2018.720p.WEBRip.DDP5.1.x264-NTb-postbot", "NTb")]
|
||||||
[TestCase("Haunted.Hayride.2018.720p.WEBRip.DDP5.1.x264-NTb-xpost", "NTb")]
|
[TestCase("Haunted.Hayride.2018.720p.WEBRip.DDP5.1.x264-NTb-xpost", "NTb")]
|
||||||
|
[TestCase("2.Broke.Girls.S02E24.1080p.AMZN.WEBRip.DD5.1.x264-CasStudio-AsRequested", "CasStudio")]
|
||||||
|
[TestCase("Billions.S04E11.Lamster.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTb-AlternativeToRequested", "NTb")]
|
||||||
|
[TestCase("NCIS.S16E04.Third.Wheel.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTb-GEROV", "NTb")]
|
||||||
|
[TestCase("Will.and.Grace.S10E06.Kid.n.Play.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTb-Z0iDS3N", "NTb")]
|
||||||
|
[TestCase("Absolute.Power.S02E06.The.House.of.Lords.DVDRip.x264-MaG-Chamele0n", "MaG")]
|
||||||
//[TestCase("", "")]
|
//[TestCase("", "")]
|
||||||
public void should_parse_release_group(string title, string expected)
|
public void should_parse_release_group(string title, string expected)
|
||||||
{
|
{
|
||||||
|
@ -36,11 +36,13 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit
|
|||||||
}
|
}
|
||||||
|
|
||||||
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
||||||
if (subject.Movie.Runtime == 0)
|
|
||||||
{
|
if (subject.Movie.Runtime == 0)
|
||||||
_logger.Warn("{0} has no runtime information using median movie runtime of 110 minutes.", subject.Movie);
|
{
|
||||||
subject.Movie.Runtime = 110;
|
_logger.Warn("{0} has no runtime information using median movie runtime of 110 minutes.", subject.Movie);
|
||||||
}
|
subject.Movie.Runtime = 110;
|
||||||
|
}
|
||||||
|
|
||||||
if (qualityDefinition.MinSize.HasValue)
|
if (qualityDefinition.MinSize.HasValue)
|
||||||
{
|
{
|
||||||
var minSize = qualityDefinition.MinSize.Value.Megabytes();
|
var minSize = qualityDefinition.MinSize.Value.Megabytes();
|
||||||
|
@ -7,4 +7,4 @@ public class QBittorrentLabel
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string SavePath { get; set; }
|
public string SavePath { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,17 +35,8 @@ public TransmissionBase(ITransmissionProxy proxy,
|
|||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
{
|
{
|
||||||
List<TransmissionTorrent> torrents;
|
var configFunc = new Lazy<TransmissionConfig>(() => _proxy.GetConfig(Settings));
|
||||||
|
var torrents = _proxy.GetTorrents(Settings);
|
||||||
try
|
|
||||||
{
|
|
||||||
torrents = _proxy.GetTorrents(Settings);
|
|
||||||
}
|
|
||||||
catch (DownloadClientException ex)
|
|
||||||
{
|
|
||||||
_logger.Error(ex, ex.Message);
|
|
||||||
return Enumerable.Empty<DownloadClientItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var items = new List<DownloadClientItem>();
|
var items = new List<DownloadClientItem>();
|
||||||
|
|
||||||
@ -111,9 +102,8 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||||||
item.Status = DownloadItemStatus.Downloading;
|
item.Status = DownloadItemStatus.Downloading;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.CanMoveFiles = item.CanBeRemoved =
|
item.CanBeRemoved = HasReachedSeedLimit(torrent, item.SeedRatio, configFunc);
|
||||||
torrent.Status == TransmissionTorrentStatus.Stopped &&
|
item.CanMoveFiles = item.CanBeRemoved && torrent.Status == TransmissionTorrentStatus.Stopped;
|
||||||
item.SeedRatio >= torrent.SeedRatioLimit;
|
|
||||||
|
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
@ -121,6 +111,46 @@ public override IEnumerable<DownloadClientItem> GetItems()
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool HasReachedSeedLimit(TransmissionTorrent torrent, double? ratio, Lazy<TransmissionConfig> config)
|
||||||
|
{
|
||||||
|
var isStopped = torrent.Status == TransmissionTorrentStatus.Stopped;
|
||||||
|
var isSeeding = torrent.Status == TransmissionTorrentStatus.Seeding;
|
||||||
|
|
||||||
|
if (torrent.SeedRatioMode == 1)
|
||||||
|
{
|
||||||
|
if (isStopped && ratio.HasValue && ratio >= torrent.SeedRatioLimit)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (torrent.SeedRatioMode == 0)
|
||||||
|
{
|
||||||
|
if (isStopped && config.Value.SeedRatioLimited && ratio >= config.Value.SeedRatioLimit)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmission doesn't support SeedTimeLimit, use/abuse seed idle limit, but only if it was set per-torrent.
|
||||||
|
if (torrent.SeedIdleMode == 1)
|
||||||
|
{
|
||||||
|
if ((isStopped || isSeeding) && torrent.SecondsSeeding > torrent.SeedIdleLimit * 60)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (torrent.SeedIdleMode == 0)
|
||||||
|
{
|
||||||
|
// The global idle limit is a real idle limit, if it's configured then 'Stopped' is enough.
|
||||||
|
if (isStopped && config.Value.IdleSeedingLimitEnabled)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public override void RemoveItem(string downloadId, bool deleteData)
|
public override void RemoveItem(string downloadId, bool deleteData)
|
||||||
{
|
{
|
||||||
_proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
|
_proxy.RemoveTorrent(downloadId.ToLower(), deleteData, Settings);
|
||||||
@ -129,8 +159,8 @@ public override void RemoveItem(string downloadId, bool deleteData)
|
|||||||
public override DownloadClientInfo GetStatus()
|
public override DownloadClientInfo GetStatus()
|
||||||
{
|
{
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _proxy.GetConfig(Settings);
|
||||||
var destDir = config.GetValueOrDefault("download-dir") as string;
|
var destDir = config.DownloadDir;
|
||||||
|
|
||||||
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
if (Settings.MovieCategory.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
destDir = string.Format("{0}/.{1}", destDir, Settings.MovieCategory);
|
destDir = string.Format("{0}/.{1}", destDir, Settings.MovieCategory);
|
||||||
@ -197,7 +227,7 @@ protected string GetDownloadDirectory()
|
|||||||
if (!Settings.MovieCategory.IsNotNullOrWhiteSpace()) return null;
|
if (!Settings.MovieCategory.IsNotNullOrWhiteSpace()) return null;
|
||||||
|
|
||||||
var config = _proxy.GetConfig(Settings);
|
var config = _proxy.GetConfig(Settings);
|
||||||
var destDir = (string)config.GetValueOrDefault("download-dir");
|
var destDir = config.DownloadDir;
|
||||||
|
|
||||||
return $"{destDir.TrimEnd('/')}/{Settings.MovieCategory}";
|
return $"{destDir.TrimEnd('/')}/{Settings.MovieCategory}";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
|
{
|
||||||
|
public class TransmissionConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("rpc-version")]
|
||||||
|
public string RpcVersion { get; set; }
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("download-dir")]
|
||||||
|
public string DownloadDir { get; set; }
|
||||||
|
|
||||||
|
public double SeedRatioLimit { get; set; }
|
||||||
|
public bool SeedRatioLimited { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("idle-seeding-limit")]
|
||||||
|
public long IdleSeedingLimit { get; set; }
|
||||||
|
[JsonProperty("idle-seeding-limit-enabled")]
|
||||||
|
public bool IdleSeedingLimitEnabled { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ public interface ITransmissionProxy
|
|||||||
void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings);
|
void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings);
|
||||||
void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings);
|
void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings);
|
||||||
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, TransmissionSettings settings);
|
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, TransmissionSettings settings);
|
||||||
Dictionary<string, object> GetConfig(TransmissionSettings settings);
|
TransmissionConfig GetConfig(TransmissionSettings settings);
|
||||||
string GetProtocolVersion(TransmissionSettings settings);
|
string GetProtocolVersion(TransmissionSettings settings);
|
||||||
string GetClientVersion(TransmissionSettings settings);
|
string GetClientVersion(TransmissionSettings settings);
|
||||||
void RemoveTorrent(string hash, bool removeData, TransmissionSettings settings);
|
void RemoveTorrent(string hash, bool removeData, TransmissionSettings settings);
|
||||||
@ -101,26 +101,22 @@ public string GetProtocolVersion(TransmissionSettings settings)
|
|||||||
{
|
{
|
||||||
var config = GetConfig(settings);
|
var config = GetConfig(settings);
|
||||||
|
|
||||||
var version = config["rpc-version"];
|
return config.RpcVersion;
|
||||||
|
|
||||||
return version.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetClientVersion(TransmissionSettings settings)
|
public string GetClientVersion(TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
var config = GetConfig(settings);
|
var config = GetConfig(settings);
|
||||||
|
|
||||||
var version = config["version"];
|
return config.Version;
|
||||||
|
|
||||||
return version.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, object> GetConfig(TransmissionSettings settings)
|
public TransmissionConfig GetConfig(TransmissionSettings settings)
|
||||||
{
|
{
|
||||||
// Gets the transmission version.
|
// Gets the transmission version.
|
||||||
var result = GetSessionVariables(settings);
|
var result = GetSessionVariables(settings);
|
||||||
|
|
||||||
return result.Arguments;
|
return Json.Deserialize<TransmissionConfig>(result.Arguments.ToJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveTorrent(string hashString, bool removeData, TransmissionSettings settings)
|
public void RemoveTorrent(string hashString, bool removeData, TransmissionSettings settings)
|
||||||
@ -164,15 +160,20 @@ private TransmissionResponse GetTorrentStatus(IEnumerable<string> hashStrings, T
|
|||||||
"hashString", // Unique torrent ID. Use this instead of the client id?
|
"hashString", // Unique torrent ID. Use this instead of the client id?
|
||||||
"name",
|
"name",
|
||||||
"downloadDir",
|
"downloadDir",
|
||||||
"status",
|
|
||||||
"totalSize",
|
"totalSize",
|
||||||
"leftUntilDone",
|
"leftUntilDone",
|
||||||
"isFinished",
|
"isFinished",
|
||||||
"eta",
|
"eta",
|
||||||
|
"status",
|
||||||
|
"secondsDownloading",
|
||||||
|
"secondsSeeding",
|
||||||
"errorString",
|
"errorString",
|
||||||
"uploadedEver",
|
"uploadedEver",
|
||||||
"downloadedEver",
|
"downloadedEver",
|
||||||
"seedRatioLimit",
|
"seedRatioLimit",
|
||||||
|
"seedRatioMode",
|
||||||
|
"seedIdleLimit",
|
||||||
|
"seedIdleMode",
|
||||||
"fileCount"
|
"fileCount"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,10 +12,14 @@ public class TransmissionTorrent
|
|||||||
public int Eta { get; set; }
|
public int Eta { get; set; }
|
||||||
public TransmissionTorrentStatus Status { get; set; }
|
public TransmissionTorrentStatus Status { get; set; }
|
||||||
public int SecondsDownloading { get; set; }
|
public int SecondsDownloading { get; set; }
|
||||||
|
public int SecondsSeeding { get; set; }
|
||||||
public string ErrorString { get; set; }
|
public string ErrorString { get; set; }
|
||||||
public long DownloadedEver { get; set; }
|
public long DownloadedEver { get; set; }
|
||||||
public long UploadedEver { get; set; }
|
public long UploadedEver { get; set; }
|
||||||
public long SeedRatioLimit { get; set; }
|
public double SeedRatioLimit { get; set; }
|
||||||
|
public int SeedRatioMode { get; set; }
|
||||||
|
public long SeedIdleLimit { get; set; }
|
||||||
|
public int SeedIdleMode { get; set; }
|
||||||
public int FileCount { get; set; }
|
public int FileCount { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,7 @@
|
|||||||
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxySelector.cs" />
|
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxySelector.cs" />
|
||||||
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxyV1.cs" />
|
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxyV1.cs" />
|
||||||
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxyV2.cs" />
|
<Compile Include="Download\Clients\QBittorrent\QBittorrentProxyV2.cs" />
|
||||||
|
<Compile Include="Download\Clients\Transmission\TransmissionConfig.cs" />
|
||||||
<Compile Include="Download\DownloadClientInfo.cs" />
|
<Compile Include="Download\DownloadClientInfo.cs" />
|
||||||
<Compile Include="Download\DownloadClientStatusRepository.cs" />
|
<Compile Include="Download\DownloadClientStatusRepository.cs" />
|
||||||
<Compile Include="Download\DownloadClientStatusService.cs" />
|
<Compile Include="Download\DownloadClientStatusService.cs" />
|
||||||
|
@ -113,7 +113,7 @@ public static class Parser
|
|||||||
private static readonly Regex SixDigitAirDateRegex = new Regex(@"(?<=[_.-])(?<airdate>(?<!\d)(?<airyear>[1-9]\d{1})(?<airmonth>[0-1][0-9])(?<airday>[0-3][0-9]))(?=[_.-])",
|
private static readonly Regex SixDigitAirDateRegex = new Regex(@"(?<=[_.-])(?<airdate>(?<!\d)(?<airyear>[1-9]\d{1})(?<airmonth>[0-1][0-9])(?<airday>[0-3][0-9]))(?=[_.-])",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex CleanReleaseGroupRegex = new Regex(@"^(.*?[-._ ](S\d+E\d+)[-._ ])|(-(RP|1|NZBGeek|Obfuscated|sample|Pre|postbot|xpost|Rakuv[a-z]*|WhiteRev|BUYMORE|AsRequested))+$",
|
private static readonly Regex CleanReleaseGroupRegex = new Regex(@"^(.*?[-._ ](S\d+E\d+)[-._ ])|(-(RP|1|NZBGeek|Obfuscated|sample|Pre|postbot|xpost|Rakuv[a-z]*|WhiteRev|BUYMORE|AsRequested|AlternativeToRequested|GEROV|Z0iDS3N|Chamele0n))+$",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex CleanTorrentSuffixRegex = new Regex(@"\[(?:ettv|rartv|rarbg|cttv)\]$",
|
private static readonly Regex CleanTorrentSuffixRegex = new Regex(@"\[(?:ettv|rartv|rarbg|cttv)\]$",
|
||||||
|
Loading…
Reference in New Issue
Block a user