mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
New: Upstream Updates
Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
This commit is contained in:
@@ -28,7 +28,7 @@ namespace NzbDrone.Api.ManualImport
|
||||
var downloadId = (string)downloadIdQuery.Value;
|
||||
var filterExistingFiles = Request.GetBooleanQueryParameter("filterExistingFiles", true);
|
||||
|
||||
return _manualImportService.GetMediaFiles(folder, downloadId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList();
|
||||
return _manualImportService.GetMediaFiles(folder, downloadId, null, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList();
|
||||
}
|
||||
|
||||
private ManualImportResource AddQualityWeight(ManualImportResource item)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace NzbDrone.Api.Qualities
|
||||
|
||||
CreateResource = Create;
|
||||
|
||||
DeleteResource = Delete;
|
||||
DeleteResource = DeleteFormat;
|
||||
|
||||
Get["/test"] = x => Test();
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace NzbDrone.Api.Qualities
|
||||
return _formatService.All().ToResource();
|
||||
}
|
||||
|
||||
private void Delete(int id)
|
||||
private void DeleteFormat(int id)
|
||||
{
|
||||
_formatService.Delete(id);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace NzbDrone.Automation.Test
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Trace, consoleTarget));
|
||||
}
|
||||
|
||||
[TestFixtureSetUp]
|
||||
[OneTimeSetUp]
|
||||
public void SmokeTestSetup()
|
||||
{
|
||||
driver = new FirefoxDriver();
|
||||
@@ -56,7 +56,7 @@ namespace NzbDrone.Automation.Test
|
||||
.Select(e => e.Text);
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
[OneTimeTearDown]
|
||||
public void SmokeTestTearDown()
|
||||
{
|
||||
_runner.KillAll();
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
public abstract class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
||||
{
|
||||
[Test]
|
||||
[Retry(5)]
|
||||
public void directory_exist_should_be_able_to_find_existing_folder()
|
||||
{
|
||||
Subject.FolderExists(TempFolder).Should().BeTrue();
|
||||
@@ -32,6 +33,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
protected abstract void SetWritePermissions(string path, bool writable);
|
||||
|
||||
[Test]
|
||||
[Retry(5)]
|
||||
public void FolderWritable_should_return_true_for_writable_directory()
|
||||
{
|
||||
var tempFolder = GetTempFilePath();
|
||||
@@ -62,6 +64,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Retry(5)]
|
||||
public void MoveFile_should_overwrite_existing_file()
|
||||
{
|
||||
var source1 = GetTempFilePath();
|
||||
@@ -122,6 +125,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Retry(5)]
|
||||
public void empty_folder_should_return_folder_modified_date()
|
||||
{
|
||||
var tempfolder = new DirectoryInfo(TempFolder);
|
||||
|
||||
@@ -616,6 +616,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Retry(5)]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public interface IOperatingSystemVersionInfo
|
||||
{
|
||||
string Version { get; }
|
||||
string Name { get; }
|
||||
string FullName { get; }
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,6 @@
|
||||
<Compile Include="Disk\FileSystemModel.cs" />
|
||||
<Compile Include="Disk\FileSystemResult.cs" />
|
||||
<Compile Include="Disk\SystemFolders.cs" />
|
||||
<Compile Include="EnvironmentInfo\IOperatingSystemVersionInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" />
|
||||
<Compile Include="EnvironmentInfo\IPlatformInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\OsVersionModel.cs" />
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Datastore.Converters
|
||||
{
|
||||
var i = 5;
|
||||
|
||||
Subject.ToDB(i).Should().Be(5);
|
||||
Subject.ToDB(i).Should().Be(i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -83,5 +83,20 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
FormatItems = CustomFormatsFixture.GetSampleFormatItems("None", "My Format")
|
||||
}, old, newQ).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_cutoffs_are_met_but_is_a_revision_upgrade()
|
||||
{
|
||||
Profile _profile = new Profile
|
||||
{
|
||||
Cutoff = Quality.HDTV1080p.Id,
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
};
|
||||
|
||||
Subject.CutoffNotMet(
|
||||
_profile,
|
||||
new QualityModel(Quality.WEBDL1080p, new Revision(version: 1)),
|
||||
new QualityModel(Quality.WEBDL1080p, new Revision(version: 2))).Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,16 +279,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_skip_deletestatus_copy()
|
||||
public void should_report_deletestatus_copy_as_failed()
|
||||
{
|
||||
_completed.DeleteStatus = "COPY";
|
||||
|
||||
GivenQueue(null);
|
||||
GivenHistory(_completed);
|
||||
|
||||
var result = Subject.GetItems().SingleOrDefault();
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
result.Should().BeNull();
|
||||
result.Status.Should().Be(DownloadItemStatus.Failed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Framework.AutoMoq
|
||||
{
|
||||
[TestFixture]
|
||||
class TestBaseTests : TestBase
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_no_exceptions_are_logged()
|
||||
{
|
||||
Logger.Info("Everything is fine and dandy!");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_errors_are_excpected()
|
||||
{
|
||||
Logger.Error("I knew this would happer");
|
||||
ExceptionVerification.ExcpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_warns_are_excpected()
|
||||
{
|
||||
Logger.Warn("I knew this would happer");
|
||||
ExceptionVerification.ExcpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_warns_are_ignored()
|
||||
{
|
||||
Logger.Warn("I knew this would happer");
|
||||
Logger.Warn("I knew this would happer");
|
||||
Logger.Warn("I knew this would happer");
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_errors_are_ignored()
|
||||
{
|
||||
Logger.Error("I knew this would happer");
|
||||
Logger.Error("I knew this would happer");
|
||||
Logger.Error("I knew this would happer");
|
||||
ExceptionVerification.IgnoreErrors();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_should_pass_when_exception_type_is_ignored()
|
||||
{
|
||||
Logger.ErrorException("bad exception", new WebException("Test"));
|
||||
ExceptionVerification.MarkInconclusive(typeof(WebException));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.ThingiProvider.Status;
|
||||
|
||||
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
{
|
||||
[TestFixture]
|
||||
public class FixFutureIndexerStatusTimesFixture : CoreTest<FixFutureIndexerStatusTimes>
|
||||
{
|
||||
[Test]
|
||||
public void should_set_disabled_till_when_its_too_far_in_the_future()
|
||||
{
|
||||
var disabledTillTime = EscalationBackOff.Periods[1];
|
||||
var indexerStatuses = Builder<IndexerStatus>.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(t => t.DisabledTill = DateTime.UtcNow.AddDays(5))
|
||||
.With(t => t.InitialFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.MostRecentFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.EscalationLevel = 1)
|
||||
.BuildListOfNew();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Setup(s => s.All())
|
||||
.Returns(indexerStatuses);
|
||||
|
||||
Subject.Clean();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Verify(v => v.UpdateMany(
|
||||
It.Is<List<IndexerStatus>>(i => i.All(
|
||||
s => s.DisabledTill.Value < DateTime.UtcNow.AddMinutes(disabledTillTime)))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_initial_failure_when_its_in_the_future()
|
||||
{
|
||||
var indexerStatuses = Builder<IndexerStatus>.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(t => t.DisabledTill = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.InitialFailure = DateTime.UtcNow.AddDays(5))
|
||||
.With(t => t.MostRecentFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.EscalationLevel = 1)
|
||||
.BuildListOfNew();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Setup(s => s.All())
|
||||
.Returns(indexerStatuses);
|
||||
|
||||
Subject.Clean();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Verify(v => v.UpdateMany(
|
||||
It.Is<List<IndexerStatus>>(i => i.All(
|
||||
s => s.InitialFailure.Value <= DateTime.UtcNow))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_most_recent_failure_when_its_in_the_future()
|
||||
{
|
||||
var indexerStatuses = Builder<IndexerStatus>.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(t => t.DisabledTill = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.InitialFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.MostRecentFailure = DateTime.UtcNow.AddDays(5))
|
||||
.With(t => t.EscalationLevel = 1)
|
||||
.BuildListOfNew();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Setup(s => s.All())
|
||||
.Returns(indexerStatuses);
|
||||
|
||||
Subject.Clean();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Verify(v => v.UpdateMany(
|
||||
It.Is<List<IndexerStatus>>(i => i.All(
|
||||
s => s.MostRecentFailure.Value <= DateTime.UtcNow))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_change_statuses_when_times_are_in_the_past()
|
||||
{
|
||||
var indexerStatuses = Builder<IndexerStatus>.CreateListOfSize(5)
|
||||
.All()
|
||||
.With(t => t.DisabledTill = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.InitialFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.MostRecentFailure = DateTime.UtcNow.AddDays(-5))
|
||||
.With(t => t.EscalationLevel = 0)
|
||||
.BuildListOfNew();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Setup(s => s.All())
|
||||
.Returns(indexerStatuses);
|
||||
|
||||
Subject.Clean();
|
||||
|
||||
Mocker.GetMock<IIndexerStatusRepository>()
|
||||
.Verify(v => v.UpdateMany(
|
||||
It.Is<List<IndexerStatus>>(i => i.Count == 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
{
|
||||
public class NzbSearchServiceFixture : CoreTest<NzbSearchService>
|
||||
{
|
||||
private List<IIndexer> _indexers;
|
||||
|
||||
private Series _searchTargetSeries;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
|
||||
_searchTargetSeries = Builder<Series>.CreateNew().BuildNew();
|
||||
|
||||
_indexers = new List<IIndexer>();
|
||||
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
|
||||
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
||||
|
||||
Mocker.GetMock<ISeriesService>().Setup(c => c.GetSeries(It.IsAny<int>()))
|
||||
.Returns(_searchTargetSeries);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_call_fetch_on_all_indexers_at_the_same_time()
|
||||
{
|
||||
|
||||
var counter = new ConcurrencyCounter(_indexers.Count);
|
||||
|
||||
Mocker.GetMock<IFetchFeedFromIndexers>().Setup(c => c.Fetch(It.IsAny<IIndexer>(), It.IsAny<SingleEpisodeSearchDefinition>()))
|
||||
.Returns(new List<ReportInfo>())
|
||||
.Callback((() => counter.SimulateWork(500)));
|
||||
|
||||
Mocker.GetMock<IIndexerService>().Setup(c => c.GetAvailableIndexers()).Returns(_indexers);
|
||||
|
||||
Mocker.GetMock<IMakeDownloadDecision>()
|
||||
.Setup(c => c.GetSearchDecision(It.IsAny<IEnumerable<ReportInfo>>(), It.IsAny<SearchDefinitionBase>()))
|
||||
.Returns(new List<DownloadDecision>());
|
||||
|
||||
Subject.SearchSingle(0, 0, 0);
|
||||
|
||||
counter.WaitForAllItems();
|
||||
|
||||
counter.MaxThreads.Should().Be(_indexers.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests
|
||||
{
|
||||
public class FetchAndParseRssServiceFixture : CoreTest<FetchAndParseRssService>
|
||||
{
|
||||
private List<IIndexer> _indexers;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_indexers = new List<IIndexer>();
|
||||
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
_indexers.Add(new Newznab());
|
||||
|
||||
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Explicit]
|
||||
public void should_call_fetch_on_all_indexers_at_the_same_time()
|
||||
{
|
||||
|
||||
var counter = new ConcurrencyCounter(_indexers.Count);
|
||||
|
||||
Mocker.GetMock<IFetchFeedFromIndexers>().Setup(c => c.FetchRss(It.IsAny<IIndexer>()))
|
||||
.Returns(new List<ReportInfo>())
|
||||
.Callback((() => counter.SimulateWork(500)));
|
||||
|
||||
Mocker.GetMock<IIndexerService>().Setup(c => c.GetAvailableIndexers()).Returns(_indexers);
|
||||
|
||||
Subject.Fetch();
|
||||
|
||||
counter.WaitForAllItems();
|
||||
|
||||
counter.MaxThreads.Should().Be(_indexers.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
|
||||
torrentInfo.Title.Should().Be("Sense8.S01E01.WEBRip.x264-FGT");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("magnet:?xt=urn:btih:d8bde635f573acb390c7d7e7efc1556965fdc802&dn=Sense8.S01E01.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce");
|
||||
torrentInfo.InfoUrl.Should().Be("https://torrentapi.org/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_6__d8bde635f5");
|
||||
torrentInfo.InfoUrl.Should().Be("https://torrentapi.org/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_6__d8bde635f5&app_id=Radarr");
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2015-06-05 16:58:11 +0000").ToUniversalTime());
|
||||
torrentInfo.Size.Should().Be(564198371);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class SeedConfigProviderFixture : CoreTest<SeedConfigProvider>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_return_config_for_non_existent_indexer()
|
||||
{
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(v => v.Get(It.IsAny<int>()))
|
||||
.Throws(new ModelNotFoundException(typeof(IndexerDefinition), 0));
|
||||
|
||||
var result = Subject.GetSeedConfiguration(new RemoteMovie
|
||||
{
|
||||
Release = new ReleaseInfo()
|
||||
{
|
||||
DownloadProtocol = DownloadProtocol.Torrent,
|
||||
IndexerId = 0
|
||||
}
|
||||
});
|
||||
|
||||
result.Should().BeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,8 +60,13 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_reject_when_there_isnt_enough_space_for_file_plus_100mb_padding()
|
||||
public void should_reject_when_there_isnt_enough_space_for_file_plus_min_free_space()
|
||||
{
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.MinimumFreeSpaceWhenImporting)
|
||||
.Returns(100);
|
||||
|
||||
GivenFileSize(100.Megabytes());
|
||||
GivenFreeSpace(150.Megabytes());
|
||||
|
||||
|
||||
@@ -63,5 +63,16 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Specifications
|
||||
|
||||
Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_accepted_if_file_cannot_be_fetched()
|
||||
{
|
||||
_localMovie.Movie = Builder<Movie>.CreateNew()
|
||||
.With(e => e.MovieFileId = 1)
|
||||
.With(e => e.MovieFile = new LazyLoaded<MovieFile>((MovieFile)null))
|
||||
.Build();
|
||||
|
||||
Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||
|
||||
Subject.UpgradeMovieFile(_movieFile, _localMovie);
|
||||
|
||||
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Once());
|
||||
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Once());
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||
|
||||
Subject.UpgradeMovieFile(_movieFile, _localMovie);
|
||||
|
||||
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Notifications.Growl;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.NotificationTests
|
||||
{
|
||||
[Explicit]
|
||||
[TestFixture]
|
||||
public class GrowlProviderTest : CoreTest
|
||||
{
|
||||
[Test]
|
||||
public void Register_should_add_new_application_to_local_growl_instance()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
Mocker.Resolve<GrowlProvider>().Register("localhost", 23053, "");
|
||||
|
||||
|
||||
Mocker.VerifyAllMocks();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNotification_should_send_a_message_to_local_growl_instance()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
Mocker.Resolve<GrowlProvider>().TestNotification("localhost", 23053, "");
|
||||
|
||||
|
||||
Mocker.VerifyAllMocks();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnGrab_should_send_a_message_to_local_growl_instance()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
Mocker.Resolve<GrowlProvider>().SendNotification("Episode Grabbed", "Series Title - 1x05 - Episode Title", "GRAB", "localhost", 23053, "");
|
||||
|
||||
|
||||
Mocker.VerifyAllMocks();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnDownload_should_send_a_message_to_local_growl_instance()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
Mocker.Resolve<GrowlProvider>().SendNotification("Episode Downloaded", "Series Title - 1x05 - Episode Title", "DOWNLOAD", "localhost", 23053, "");
|
||||
|
||||
|
||||
Mocker.VerifyAllMocks();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,6 +256,7 @@
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedMetadataFilesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupUnusedTagsFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedPendingReleasesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\FixFutureIndexerStatusTimesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\FixFutureRunScheduledTasksFixture.cs" />
|
||||
<Compile Include="Http\HttpProxySettingsProviderFixture.cs" />
|
||||
<Compile Include="Http\TorCacheHttpRequestInterceptorFixture.cs" />
|
||||
@@ -267,6 +268,7 @@
|
||||
<Compile Include="IndexerTests\IntegrationTests\IndexerIntegrationTests.cs" />
|
||||
<Compile Include="IndexerTests\NewznabTests\NewznabCapabilitiesProviderFixture.cs" />
|
||||
<Compile Include="IndexerTests\RarbgTests\RarbgFixture.cs" />
|
||||
<Compile Include="IndexerTests\SeedConfigProviderFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TorrentRssParserFactoryFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TorrentRssSettingsDetectorFixture.cs" />
|
||||
<Compile Include="IndexerTests\TorznabTests\TorznabFixture.cs" />
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetDirectories(RecycleBin))
|
||||
.Returns(new [] { @"C:\Test\RecycleBin\Folder1", @"C:\Test\RecycleBin\Folder2", @"C:\Test\RecycleBin\Folder3" });
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetFiles(RecycleBin, SearchOption.TopDirectoryOnly))
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetFiles(RecycleBin, SearchOption.AllDirectories))
|
||||
.Returns(new [] { @"C:\Test\RecycleBin\File1.avi", @"C:\Test\RecycleBin\File2.mkv" });
|
||||
}
|
||||
|
||||
@@ -56,12 +56,13 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_all_expired_folders()
|
||||
{
|
||||
WithExpired();
|
||||
public void should_return_if_recycleBinCleanupDays_is_zero()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().SetupGet(s => s.RecycleBinCleanupDays).Returns(0);
|
||||
|
||||
Mocker.Resolve<RecycleBinProvider>().Cleanup();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Verify(v => v.DeleteFolder(It.IsAny<string>(), true), Times.Exactly(3));
|
||||
Mocker.GetMock<IDiskProvider>().Verify(v => v.GetDirectories(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -7,7 +7,6 @@ using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace NzbDrone.Core.Configuration
|
||||
// TODO: Change back to "master" for the first stable release.
|
||||
public string Branch => GetValue("Branch", "develop").ToLowerInvariant();
|
||||
|
||||
public string LogLevel => GetValue("LogLevel", "Info");
|
||||
public string LogLevel => GetValue("LogLevel", "info");
|
||||
public string ConsoleLogLevel => GetValue("ConsoleLogLevel", string.Empty, persist: false);
|
||||
|
||||
public string SslCertHash => GetValue("SslCertHash", "");
|
||||
|
||||
@@ -93,6 +93,12 @@ namespace NzbDrone.Core.Configuration
|
||||
set { SetValue("RecycleBin", value); }
|
||||
}
|
||||
|
||||
public int RecycleBinCleanupDays
|
||||
{
|
||||
get { return GetValueInt("RecycleBinCleanupDays", 7); }
|
||||
set { SetValue("RecycleBinCleanupDays", value); }
|
||||
}
|
||||
|
||||
public int RssSyncInterval
|
||||
{
|
||||
get { return GetValueInt("RssSyncInterval", 60); }
|
||||
@@ -287,6 +293,13 @@ namespace NzbDrone.Core.Configuration
|
||||
set { SetValue("SkipFreeSpaceCheckWhenImporting", value); }
|
||||
}
|
||||
|
||||
public int MinimumFreeSpaceWhenImporting
|
||||
{
|
||||
get { return GetValueInt("MinimumFreeSpaceWhenImporting", 100); }
|
||||
|
||||
set { SetValue("MinimumFreeSpaceWhenImporting", value); }
|
||||
}
|
||||
|
||||
public bool CopyUsingHardlinks
|
||||
{
|
||||
get { return GetValueBoolean("CopyUsingHardlinks", true); }
|
||||
|
||||
@@ -27,11 +27,13 @@ namespace NzbDrone.Core.Configuration
|
||||
//Media Management
|
||||
bool AutoUnmonitorPreviouslyDownloadedMovies { get; set; }
|
||||
string RecycleBin { get; set; }
|
||||
int RecycleBinCleanupDays { get; set; }
|
||||
bool AutoDownloadPropers { get; set; }
|
||||
bool CreateEmptyMovieFolders { get; set; }
|
||||
bool DeleteEmptyFolders { get; set; }
|
||||
FileDateType FileDate { get; set; }
|
||||
bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||
int MinimumFreeSpaceWhenImporting { get; set; }
|
||||
bool CopyUsingHardlinks { get; set; }
|
||||
bool EnableMediaInfo { get; set; }
|
||||
bool ImportExtraFiles { get; set; }
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||
|
||||
var cdhEnabled = _configService.EnableCompletedDownloadHandling;
|
||||
|
||||
_logger.Debug("Performing history status check on report");
|
||||
_logger.Debug("Performing history status check on report");
|
||||
_logger.Debug("Checking current status of movie [{0}] in history", subject.Movie.Id);
|
||||
var mostRecent = _historyService.MostRecentForMovie(subject.Movie.Id);
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||
|
||||
if (!recent && cdhEnabled)
|
||||
{
|
||||
return Decision.Accept();
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (!cutoffUnmet)
|
||||
|
||||
@@ -48,9 +48,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
public bool CutoffNotMet(Profile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
||||
{
|
||||
var comparer = new QualityModelComparer(profile);
|
||||
var compare = comparer.Compare(currentQuality.Quality.Id, profile.Cutoff);
|
||||
var cutoffCompare = comparer.Compare(currentQuality.Quality.Id, profile.Cutoff);
|
||||
|
||||
if (compare < 0)
|
||||
if (cutoffCompare < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||
}
|
||||
catch (DownloadClientException ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
_logger.Error(ex, ex.Message);
|
||||
return Enumerable.Empty<DownloadClientItem>();
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||
}
|
||||
catch (DownloadClientAuthenticationException ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
_logger.Error(ex, ex.Message);
|
||||
|
||||
return new NzbDroneValidationFailure("Password", "Authentication failed");
|
||||
}
|
||||
@@ -188,7 +188,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(ex.Message, ex);
|
||||
_logger.Error(ex, ex.Message);
|
||||
return new NzbDroneValidationFailure(String.Empty, "Failed to get the list of torrents: " + ex.Message);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Failed to map Hadouken torrent data.", ex);
|
||||
_logger.Error(ex, "Failed to map Hadouken torrent data.");
|
||||
}
|
||||
|
||||
return torrent;
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
historyItem.CanMoveFiles = true;
|
||||
historyItem.CanBeRemoved = true;
|
||||
|
||||
if (item.DeleteStatus == "MANUAL" || item.DeleteStatus == "COPY")
|
||||
if (item.DeleteStatus == "MANUAL")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,18 +53,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
|
||||
private IEnumerable<DownloadClientItem> GetQueue()
|
||||
{
|
||||
SabnzbdQueue sabQueue;
|
||||
|
||||
try
|
||||
{
|
||||
sabQueue = _proxy.GetQueue(0, 0, Settings);
|
||||
}
|
||||
catch (DownloadClientException ex)
|
||||
{
|
||||
_logger.Warn(ex, "Couldn't get download queue. {0}", ex.Message);
|
||||
return Enumerable.Empty<DownloadClientItem>();
|
||||
}
|
||||
|
||||
var sabQueue = _proxy.GetQueue(0, 0, Settings);
|
||||
var queueItems = new List<DownloadClientItem>();
|
||||
|
||||
foreach (var sabQueueItem in sabQueue.Items)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
|
||||
torrentInfo.Title = torrent.title;
|
||||
torrentInfo.Size = torrent.size;
|
||||
torrentInfo.DownloadUrl = torrent.download;
|
||||
torrentInfo.InfoUrl = torrent.info_page;
|
||||
torrentInfo.InfoUrl = torrent.info_page + "&app_id=Radarr"; ;
|
||||
torrentInfo.PublishDate = torrent.pubdate.ToUniversalTime();
|
||||
torrentInfo.Seeders = torrent.seeders;
|
||||
torrentInfo.Peers = torrent.leechers + torrent.seeders;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
||||
{
|
||||
public interface IManualImportService
|
||||
{
|
||||
List<ManualImportItem> GetMediaFiles(string path, string downloadId, bool filterExistingFiles);
|
||||
List<ManualImportItem> GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles);
|
||||
}
|
||||
|
||||
public class ManualImportService : IExecute<ManualImportCommand>, IManualImportService
|
||||
@@ -71,7 +71,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<ManualImportItem> GetMediaFiles(string path, string downloadId, bool filterExistingFiles)
|
||||
public List<ManualImportItem> GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles)
|
||||
{
|
||||
if (downloadId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
@@ -96,14 +96,17 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
||||
return new List<ManualImportItem> { ProcessFile(rootFolder, rootFolder, path, downloadId) };
|
||||
}
|
||||
|
||||
return ProcessFolder(path, path, downloadId, filterExistingFiles);
|
||||
return ProcessFolder(path, path, downloadId, movieId, filterExistingFiles);
|
||||
}
|
||||
|
||||
private List<ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, bool filterExistingFiles)
|
||||
private List<ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int? movieId, bool filterExistingFiles)
|
||||
{
|
||||
DownloadClientItem downloadClientItem = null;
|
||||
var directoryInfo = new DirectoryInfo(baseFolder);
|
||||
var movie = _parsingService.GetMovie(directoryInfo.Name);
|
||||
|
||||
var movie = movieId.HasValue ?
|
||||
_movieService.GetMovie(movieId.Value) :
|
||||
_parsingService.GetMovie(directoryInfo.Name);
|
||||
|
||||
if (downloadId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
@@ -116,20 +119,13 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
||||
}
|
||||
}
|
||||
|
||||
// Try a lookup by the path if the movie is still unknown, this will handle
|
||||
// the case where the movie folder doesn't match the movie title.
|
||||
if (movie == null)
|
||||
{
|
||||
movie = _movieService.FindByPath(rootFolder);
|
||||
}
|
||||
|
||||
if (movie == null)
|
||||
{
|
||||
var files = _diskScanService.FilterFiles(baseFolder, _diskScanService.GetVideoFiles(baseFolder, false));
|
||||
var subfolders = _diskScanService.FilterFiles(baseFolder, _diskProvider.GetDirectories(baseFolder));
|
||||
|
||||
var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId));
|
||||
var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, filterExistingFiles));
|
||||
var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles));
|
||||
|
||||
return processedFiles.Concat(processedFolders).Where(i => i != null).ToList();
|
||||
}
|
||||
@@ -159,11 +155,11 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
|
||||
if (downloadId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var trackedDownload = _trackedDownloadService.Find(downloadId);
|
||||
downloadClientItem = trackedDownload.DownloadItem;
|
||||
downloadClientItem = trackedDownload?.DownloadItem;
|
||||
|
||||
if (movie == null)
|
||||
{
|
||||
movie = trackedDownload.RemoteMovie.Movie;
|
||||
movie = trackedDownload?.RemoteMovie?.Movie;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (freeSpace < localMovie.Size + 100.Megabytes())
|
||||
if (freeSpace < localMovie.Size + _configService.MinimumFreeSpaceWhenImporting.Megabytes())
|
||||
{
|
||||
_logger.Warn("Not enough free space ({0}) to import: {1} ({2})", freeSpace, localMovie, localMovie.Size);
|
||||
return Decision.Reject("Not enough free space");
|
||||
|
||||
@@ -19,12 +19,20 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications
|
||||
{
|
||||
var movieFile = localMovie.Movie.MovieFile;
|
||||
|
||||
if (localMovie.Movie.MovieFileId == 0 || movieFile == null)
|
||||
if (localMovie.Movie.MovieFileId == 0)
|
||||
{
|
||||
_logger.Debug("No existing movie file, skipping");
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (movieFile == null)
|
||||
{
|
||||
var movie = localMovie.Movie;
|
||||
_logger.Trace("Unable to get movie file details from the DB. MovieId: {0} MovieFileId: {1}", movie.Id, movie.MovieFileId);
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (movieFile.Size == localMovie.Size)
|
||||
{
|
||||
_logger.Debug("'{0}' Has the same filesize as existing file", localMovie.Path);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
public interface IRecycleBinProvider
|
||||
{
|
||||
void DeleteFolder(string path);
|
||||
void DeleteFile(string path);
|
||||
void DeleteFile(string path, string subfolder = "");
|
||||
void Empty();
|
||||
void Cleanup();
|
||||
}
|
||||
@@ -62,18 +62,14 @@ namespace NzbDrone.Core.MediaFiles
|
||||
_diskProvider.FolderSetLastWriteTime(destination, DateTime.UtcNow);
|
||||
foreach (var file in _diskProvider.GetFiles(destination, SearchOption.AllDirectories))
|
||||
{
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
//TODO: Better fix than this for non-Windows?
|
||||
_diskProvider.FileSetLastWriteTime(file, DateTime.UtcNow);
|
||||
}
|
||||
SetLastWriteTime(file, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
_logger.Debug("Folder has been moved to the recycling bin: {0}", destination);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFile(string path)
|
||||
public void DeleteFile(string path, string subfolder = "")
|
||||
{
|
||||
_logger.Debug("Attempting to send '{0}' to recycling bin", path);
|
||||
var recyclingBin = _configService.RecycleBin;
|
||||
@@ -94,7 +90,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||
else
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
var destination = Path.Combine(recyclingBin, fileInfo.Name);
|
||||
var destinationFolder = Path.Combine(recyclingBin, subfolder);
|
||||
var destination = Path.Combine(destinationFolder, fileInfo.Name);
|
||||
|
||||
_diskProvider.CreateFolder(destinationFolder);
|
||||
|
||||
var index = 1;
|
||||
while (_diskProvider.FileExists(destination))
|
||||
@@ -102,11 +101,11 @@ namespace NzbDrone.Core.MediaFiles
|
||||
index++;
|
||||
if (fileInfo.Extension.IsNullOrWhiteSpace())
|
||||
{
|
||||
destination = Path.Combine(recyclingBin, fileInfo.Name + "_" + index);
|
||||
destination = Path.Combine(destinationFolder, fileInfo.Name + "_" + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
destination = Path.Combine(recyclingBin, Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + index + fileInfo.Extension);
|
||||
destination = Path.Combine(destinationFolder, Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + index + fileInfo.Extension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,16 +116,11 @@ namespace NzbDrone.Core.MediaFiles
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
var message = string.Format("Unable to move '{0}' to the recycling bin: '{1}'", path, destination);
|
||||
_logger.Error(e, message);
|
||||
_logger.Error(e, "Unable to move '{0}' to the recycling bin: '{1}'", path, destination);
|
||||
throw;
|
||||
}
|
||||
|
||||
//TODO: Better fix than this for non-Windows?
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
_diskProvider.FileSetLastWriteTime(destination, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
SetLastWriteTime(destination, DateTime.UtcNow);
|
||||
|
||||
_logger.Debug("File has been moved to the recycling bin: {0}", destination);
|
||||
}
|
||||
@@ -163,22 +157,19 @@ namespace NzbDrone.Core.MediaFiles
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Info("Removing items older than 7 days from the recycling bin");
|
||||
var cleanupDays = _configService.RecycleBinCleanupDays;
|
||||
|
||||
foreach (var folder in _diskProvider.GetDirectories(_configService.RecycleBin))
|
||||
if (cleanupDays == 0)
|
||||
{
|
||||
if (_diskProvider.FolderGetLastWrite(folder).AddDays(7) > DateTime.UtcNow)
|
||||
{
|
||||
_logger.Debug("Folder hasn't expired yet, skipping: {0}", folder);
|
||||
continue;
|
||||
}
|
||||
|
||||
_diskProvider.DeleteFolder(folder, true);
|
||||
_logger.Info("Automatic cleanup of Recycle Bin is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly))
|
||||
_logger.Info("Removing items older than {0} days from the recycling bin", cleanupDays);
|
||||
|
||||
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.AllDirectories))
|
||||
{
|
||||
if (_diskProvider.FileGetLastWrite(file).AddDays(7) > DateTime.UtcNow)
|
||||
if (_diskProvider.FileGetLastWrite(file).AddDays(cleanupDays) > DateTime.UtcNow)
|
||||
{
|
||||
_logger.Debug("File hasn't expired yet, skipping: {0}", file);
|
||||
continue;
|
||||
@@ -187,9 +178,26 @@ namespace NzbDrone.Core.MediaFiles
|
||||
_diskProvider.DeleteFile(file);
|
||||
}
|
||||
|
||||
_diskProvider.RemoveEmptySubfolders(_configService.RecycleBin);
|
||||
|
||||
_logger.Debug("Recycling Bin has been cleaned up.");
|
||||
}
|
||||
|
||||
private void SetLastWriteTime(string file, DateTime dateTime)
|
||||
{
|
||||
// Swallow any IOException that may be thrown due to "Invalid parameter"
|
||||
try
|
||||
{
|
||||
_diskProvider.FileSetLastWriteTime(file, dateTime);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleAsync(MovieDeletedEvent message)
|
||||
{
|
||||
if (message.DeleteFiles)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Messaging.Commands
|
||||
_logger.Error(ex, "Thread aborted: " + ex.Message);
|
||||
Thread.ResetAbort();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
_logger.Trace("Stopped one command execution pipeline");
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
{
|
||||
return new List<Movie> { GetMovieInfo(parserResult.ImdbId) };
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception)
|
||||
{
|
||||
return new List<Movie>();
|
||||
}
|
||||
@@ -538,7 +538,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster);
|
||||
imdbMovie.Images.Add(imdbPoster);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.Debug(result);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace NzbDrone.Core.Movies
|
||||
movie.SecondaryYearSourceId = 0;
|
||||
}
|
||||
}
|
||||
catch (RadarrAPIException ex)
|
||||
catch (RadarrAPIException)
|
||||
{
|
||||
//Not that wild, could just be a 404.
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace NzbDrone.Core.Notifications.Plex.PlexTv
|
||||
{
|
||||
throw new NzbDroneClientException(ex.Response.StatusCode, "Unable to connect to plex.tv");
|
||||
}
|
||||
catch (WebException ex)
|
||||
catch (WebException)
|
||||
{
|
||||
throw new NzbDroneClientException(HttpStatusCode.BadRequest, "Unable to connect to plex.tv");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Parser.Augmenters
|
||||
try {
|
||||
indexerSettings = _indexerFactory.Get(releaseInfo.IndexerId)?.Settings as IIndexerSettings;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception)
|
||||
{
|
||||
//_logger.Debug("Indexer with id {0} does not exist, skipping minimum seeder checks.", subject.Release.IndexerId);
|
||||
} // First, let's augment the language!
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace NzbDrone.Core.Parser
|
||||
Logger.Debug("Unable to parse langauge from subtitle file: {0}", fileName);
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
#if !LIBRARY
|
||||
Logger.Debug("Failed parsing langauge from subtitle file: {0}", fileName);
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace NzbDrone.Core.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]))(?=[_.-])",
|
||||
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|AlternativeToRequested|GEROV|Z0iDS3N|Chamele0n))+$",
|
||||
private static readonly Regex CleanReleaseGroupRegex = new Regex(@"^(.*?[-._ ](S\d+E\d+)[-._ ])|(-(RP|1|NZBGeek|Obfuscated|sample|Pre|postbot|xpost|Rakuv[a-z0-9]*|WhiteRev|BUYMORE|AsRequested|AlternativeToRequested|GEROV|Z0iDS3N|Chamele0n))+$",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex CleanTorrentSuffixRegex = new Regex(@"\[(?:ettv|rartv|rarbg|cttv)\]$",
|
||||
@@ -135,7 +135,7 @@ namespace NzbDrone.Core.Parser
|
||||
private static readonly Regex SpecialEpisodeWordRegex = new Regex(@"\b(part|special|edition|christmas)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
private static readonly Regex DuplicateSpacesRegex = new Regex(@"\s{2,}", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex RequestInfoRegex = new Regex(@"\[.+?\]", RegexOptions.Compiled);
|
||||
private static readonly Regex RequestInfoRegex = new Regex(@"^(?:\[.+?\])+", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex ReportYearRegex = new Regex(@"^.*(?<year>(19|20)\d{2}).*$", RegexOptions.Compiled);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
private static readonly Regex SourceRegex = new Regex(@"\b(?:
|
||||
(?<bluray>M?BluRay|Blu-Ray|HDDVD|BD(?!$)|BDISO|BD25|BD50|BR.?DISK)|
|
||||
(?<webdl>WEB[-_. ]DL|HDRIP|WEBDL|WebRip|Web-Rip|iTunesHD|WebHD|WEBMux|[. ]WEB[. ](?:[xh]26[45]|DDP?5[. ]1)|\d+0p[-. ]WEB[-. ]|WEB-DLMux|\b\s\/\sWEB\s\/\s\b)|
|
||||
(?<webdl>WEB[-_. ]DL|HDRIP|WEBDL|WebRip|Web-Rip|iTunesHD|MaxdomeHD|NetflixU?HD|WebHD|WEBMux|[. ]WEB[. ](?:[xh]26[45]|DDP?5[. ]1)|\d+0p[-. ]WEB[-. ]|WEB-DLMux|\b\s\/\sWEB\s\/\s\b)|
|
||||
(?<hdtv>HDTV)|
|
||||
(?<bdrip>BDRip)|(?<brrip>BRRip)|
|
||||
(?<dvdr>DVD-R|DVDR)|
|
||||
|
||||
@@ -2,6 +2,8 @@ using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -71,11 +73,9 @@ namespace NzbDrone.Core.RootFolders
|
||||
{
|
||||
try
|
||||
{
|
||||
if (folder.Path.IsPathValid() && _diskProvider.FolderExists(folder.Path))
|
||||
if (folder.Path.IsPathValid())
|
||||
{
|
||||
folder.FreeSpace = _diskProvider.GetAvailableSpace(folder.Path);
|
||||
folder.TotalSpace = _diskProvider.GetTotalSize(folder.Path);
|
||||
folder.UnmappedFolders = GetUnmappedFolders(folder.Path);
|
||||
GetDetails(folder);
|
||||
}
|
||||
}
|
||||
//We don't want an exception to prevent the root folders from loading in the UI, so they can still be deleted
|
||||
@@ -115,9 +115,7 @@ namespace NzbDrone.Core.RootFolders
|
||||
|
||||
_rootFolderRepository.Insert(rootFolder);
|
||||
|
||||
rootFolder.FreeSpace = _diskProvider.GetAvailableSpace(rootFolder.Path);
|
||||
rootFolder.TotalSpace = _diskProvider.GetTotalSize(rootFolder.Path);
|
||||
rootFolder.UnmappedFolders = GetUnmappedFolders(rootFolder.Path);
|
||||
GetDetails(rootFolder);
|
||||
|
||||
return rootFolder;
|
||||
}
|
||||
@@ -168,9 +166,8 @@ namespace NzbDrone.Core.RootFolders
|
||||
public RootFolder Get(int id)
|
||||
{
|
||||
var rootFolder = _rootFolderRepository.Get(id);
|
||||
rootFolder.FreeSpace = _diskProvider.GetAvailableSpace(rootFolder.Path);
|
||||
rootFolder.TotalSpace = _diskProvider.GetTotalSize(rootFolder.Path);
|
||||
rootFolder.UnmappedFolders = GetUnmappedFolders(rootFolder.Path);
|
||||
GetDetails(rootFolder);
|
||||
|
||||
return rootFolder;
|
||||
}
|
||||
|
||||
@@ -187,5 +184,19 @@ namespace NzbDrone.Core.RootFolders
|
||||
|
||||
return possibleRootFolder.Path;
|
||||
}
|
||||
|
||||
private void GetDetails(RootFolder rootFolder)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (_diskProvider.FolderExists(rootFolder.Path))
|
||||
{
|
||||
rootFolder.FreeSpace = _diskProvider.GetAvailableSpace(rootFolder.Path);
|
||||
rootFolder.TotalSpace = _diskProvider.GetTotalSize(rootFolder.Path);
|
||||
rootFolder.UnmappedFolders = GetUnmappedFolders(rootFolder.Path);
|
||||
}
|
||||
})
|
||||
.Wait(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
|
||||
namespace NzbDrone.Core.Validation
|
||||
{
|
||||
public abstract class NzbDroneValidator<T> : AbstractValidator<T>
|
||||
{
|
||||
public override ValidationResult Validate(T instance)
|
||||
{
|
||||
return new NzbDroneValidationResult(base.Validate(instance).Errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace Radarr.Host.Owin.MiddleWare
|
||||
context.Response.Headers.Add(_versionHeader);
|
||||
await Next.Invoke(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
Logger.Debug("Unable to set version header");
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@ namespace Radarr.Api.V2.Config
|
||||
public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator)
|
||||
: base(configService)
|
||||
{
|
||||
SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0);
|
||||
SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
|
||||
SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100);
|
||||
}
|
||||
|
||||
protected override MediaManagementConfigResource ToResource(IConfigService model)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Radarr.Api.V2.Config
|
||||
{
|
||||
public bool AutoUnmonitorPreviouslyDownloadedMovies { get; set; }
|
||||
public string RecycleBin { get; set; }
|
||||
public int RecycleBinCleanupDays { get; set; }
|
||||
public bool AutoDownloadPropers { get; set; }
|
||||
public bool CreateEmptyMovieFolders { get; set; }
|
||||
public bool DeleteEmptyFolders { get; set; }
|
||||
@@ -23,6 +24,7 @@ namespace Radarr.Api.V2.Config
|
||||
public string ChownGroup { get; set; }
|
||||
|
||||
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||
public int MinimumFreeSpaceWhenImporting { get; set; }
|
||||
public bool CopyUsingHardlinks { get; set; }
|
||||
public bool ImportExtraFiles { get; set; }
|
||||
public string ExtraFileExtensions { get; set; }
|
||||
@@ -37,6 +39,7 @@ namespace Radarr.Api.V2.Config
|
||||
{
|
||||
AutoUnmonitorPreviouslyDownloadedMovies = model.AutoUnmonitorPreviouslyDownloadedMovies,
|
||||
RecycleBin = model.RecycleBin,
|
||||
RecycleBinCleanupDays = model.RecycleBinCleanupDays,
|
||||
AutoDownloadPropers = model.AutoDownloadPropers,
|
||||
CreateEmptyMovieFolders = model.CreateEmptyMovieFolders,
|
||||
DeleteEmptyFolders = model.DeleteEmptyFolders,
|
||||
@@ -52,6 +55,7 @@ namespace Radarr.Api.V2.Config
|
||||
ChownGroup = model.ChownGroup,
|
||||
|
||||
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
||||
MinimumFreeSpaceWhenImporting = model.MinimumFreeSpaceWhenImporting,
|
||||
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
||||
ImportExtraFiles = model.ImportExtraFiles,
|
||||
ExtraFileExtensions = model.ExtraFileExtensions,
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace Radarr.Api.V2.Indexers
|
||||
if (decision.RemoteMovie.Movie != null)
|
||||
{
|
||||
release.QualityWeight = decision.RemoteMovie.Movie
|
||||
.Profile.Value
|
||||
.Items.FindIndex(v => v.Quality == release.Quality.Quality) * 100;
|
||||
.Profile.Value.GetIndex(release.Quality.Quality).Index * 100;
|
||||
}
|
||||
|
||||
release.QualityWeight += release.Quality.Revision.Real * 10;
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace Radarr.Api.V2.ManualImport
|
||||
var folder = (string)Request.Query.folder;
|
||||
var downloadId = (string)Request.Query.downloadId;
|
||||
var filterExistingFiles = Request.GetBooleanQueryParameter("filterExistingFiles", true);
|
||||
var movieId = Request.GetNullableIntegerQueryParameter("movieId", null);
|
||||
|
||||
return _manualImportService.GetMediaFiles(folder, downloadId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList();
|
||||
return _manualImportService.GetMediaFiles(folder, downloadId, movieId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList();
|
||||
}
|
||||
|
||||
private ManualImportResource AddQualityWeight(ManualImportResource item)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Radarr.Api.V2.Qualities
|
||||
|
||||
CreateResource = Create;
|
||||
|
||||
DeleteResource = Delete;
|
||||
DeleteResource = DeleteFormat;
|
||||
|
||||
Get["/test"] = x => Test();
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Radarr.Api.V2.Qualities
|
||||
return _formatService.All().ToResource();
|
||||
}
|
||||
|
||||
private void Delete(int id)
|
||||
private void DeleteFormat(int id)
|
||||
{
|
||||
_formatService.Delete(id);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Radarr.Api.V2.Restrictions
|
||||
{
|
||||
_restrictionService = restrictionService;
|
||||
|
||||
GetResourceById = Get;
|
||||
GetResourceById = GetById;
|
||||
GetResourceAll = GetAll;
|
||||
CreateResource = Create;
|
||||
UpdateResource = Update;
|
||||
DeleteResource = Delete;
|
||||
DeleteResource = DeleteRestriction;
|
||||
|
||||
SharedValidator.Custom(restriction =>
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace Radarr.Api.V2.Restrictions
|
||||
});
|
||||
}
|
||||
|
||||
private RestrictionResource Get(int id)
|
||||
private RestrictionResource GetById(int id)
|
||||
{
|
||||
return _restrictionService.Get(id).ToResource();
|
||||
}
|
||||
@@ -52,7 +52,7 @@ namespace Radarr.Api.V2.Restrictions
|
||||
_restrictionService.Update(resource.ToModel());
|
||||
}
|
||||
|
||||
private void Delete(int id)
|
||||
private void DeleteRestriction(int id)
|
||||
{
|
||||
_restrictionService.Delete(id);
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace Radarr.Api.V2.Tags
|
||||
{
|
||||
_tagService = tagService;
|
||||
|
||||
GetResourceById = Get;
|
||||
GetResourceById = GetById;
|
||||
GetResourceAll = GetAll;
|
||||
}
|
||||
|
||||
private TagDetailsResource Get(int id)
|
||||
private TagDetailsResource GetById(int id)
|
||||
{
|
||||
return _tagService.Details(id).ToResource();
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace Radarr.Api.V2.Tags
|
||||
{
|
||||
_tagService = tagService;
|
||||
|
||||
GetResourceById = Get;
|
||||
GetResourceById = GetById;
|
||||
GetResourceAll = GetAll;
|
||||
CreateResource = Create;
|
||||
UpdateResource = Update;
|
||||
DeleteResource = Delete;
|
||||
DeleteResource = DeleteTag;
|
||||
}
|
||||
|
||||
private TagResource Get(int id)
|
||||
private TagResource GetById(int id)
|
||||
{
|
||||
return _tagService.GetTag(id).ToResource();
|
||||
}
|
||||
@@ -44,7 +44,7 @@ namespace Radarr.Api.V2.Tags
|
||||
_tagService.Update(resource.ToModel());
|
||||
}
|
||||
|
||||
private void Delete(int id)
|
||||
private void DeleteTag(int id)
|
||||
{
|
||||
_tagService.Delete(id);
|
||||
}
|
||||
|
||||
@@ -66,5 +66,17 @@ namespace Radarr.Http.Extensions
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static int? GetNullableIntegerQueryParameter(this Request request, string parameter, int? defaultValue = null)
|
||||
{
|
||||
var parameterValue = request.Query[parameter];
|
||||
|
||||
if (parameterValue.HasValue)
|
||||
{
|
||||
return int.Parse(parameterValue.Value);
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user