mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
basic RSS fetch seems to be working.
download might still not work.
This commit is contained in:
parent
182192e0ba
commit
a1783a53a9
@ -5,6 +5,7 @@
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Api.RootFolders;
|
||||
using NzbDrone.Api.Series;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
using NzbDrone.Test.Common;
|
||||
@ -18,6 +19,7 @@ public class ResourceMappingFixture : TestBase
|
||||
[TestCase(typeof(Core.Tv.Episode), typeof(EpisodeResource))]
|
||||
[TestCase(typeof(RootFolder), typeof(RootFolderResource))]
|
||||
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
|
||||
[TestCase(typeof(IndexerDefinition), typeof(IndexerRepository))]
|
||||
public void matching_fields(Type modelType, Type resourceType)
|
||||
{
|
||||
MappingValidation.ValidateMapping(modelType, resourceType);
|
||||
|
21
NzbDrone.Api/Indexers/IndexerModule.cs
Normal file
21
NzbDrone.Api/Indexers/IndexerModule.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Indexers;
|
||||
|
||||
namespace NzbDrone.Api.Indexers
|
||||
{
|
||||
public class IndexerModule : NzbDroneRestModule<IndexerResource>
|
||||
{
|
||||
private readonly IIndexerService _indexerService;
|
||||
|
||||
public IndexerModule(IIndexerService indexerService)
|
||||
{
|
||||
_indexerService = indexerService;
|
||||
GetResourceAll = GetAll;
|
||||
}
|
||||
|
||||
private List<IndexerResource> GetAll()
|
||||
{
|
||||
return ApplyToList(_indexerService.All);
|
||||
}
|
||||
}
|
||||
}
|
12
NzbDrone.Api/Indexers/IndexerResource.cs
Normal file
12
NzbDrone.Api/Indexers/IndexerResource.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.Indexers
|
||||
{
|
||||
public class IndexerResource : RestResource
|
||||
{
|
||||
public Boolean Enable { get; set; }
|
||||
public String Name { get; set; }
|
||||
public String Settings { get; set; }
|
||||
}
|
||||
}
|
@ -94,6 +94,8 @@
|
||||
<Compile Include="Frontend\IndexModule.cs" />
|
||||
<Compile Include="Frontend\StaticResourceProvider.cs" />
|
||||
<Compile Include="Frontend\StaticResourceMapper.cs" />
|
||||
<Compile Include="Indexers\IndexerModule.cs" />
|
||||
<Compile Include="Indexers\IndexerResource.cs" />
|
||||
<Compile Include="Mapping\MappingValidation.cs" />
|
||||
<Compile Include="Mapping\ResourceMappingException.cs" />
|
||||
<Compile Include="Mapping\ValueInjectorExtensions.cs" />
|
||||
@ -103,6 +105,7 @@
|
||||
<Compile Include="Resolvers\EndTimeResolver.cs" />
|
||||
<Compile Include="Resolvers\NextAiringResolver.cs" />
|
||||
<Compile Include="Resolvers\NullableDatetimeToString.cs" />
|
||||
<Compile Include="REST\BadRequestException.cs" />
|
||||
<Compile Include="REST\ResourceValidator.cs" />
|
||||
<Compile Include="REST\RestModule.cs" />
|
||||
<Compile Include="REST\RestResource.cs" />
|
||||
|
14
NzbDrone.Api/REST/BadRequestException.cs
Normal file
14
NzbDrone.Api/REST/BadRequestException.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.ErrorManagement;
|
||||
|
||||
namespace NzbDrone.Api.REST
|
||||
{
|
||||
public class BadRequestException : ApiException
|
||||
{
|
||||
public BadRequestException(object content = null)
|
||||
: base(HttpStatusCode.BadRequest, content)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,15 @@ public abstract class RestModule<TResource> : NancyModule
|
||||
protected ResourceValidator<TResource> SharedValidator { get; private set; }
|
||||
|
||||
|
||||
protected void ValidateId(int id)
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
throw new BadRequestException(id + " is not a valid ID");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected RestModule(string modulePath)
|
||||
: base(modulePath)
|
||||
{
|
||||
@ -42,6 +51,7 @@ protected Action<int> DeleteResource
|
||||
_deleteResource = value;
|
||||
Delete[ID_ROUTE] = options =>
|
||||
{
|
||||
ValidateId(options.Id);
|
||||
DeleteResource((int)options.Id);
|
||||
return new Response { StatusCode = HttpStatusCode.OK };
|
||||
};
|
||||
@ -56,12 +66,7 @@ protected Func<int, TResource> GetResourceById
|
||||
_getResourceById = value;
|
||||
Get[ID_ROUTE] = options =>
|
||||
{
|
||||
int id;
|
||||
if (!Int32.TryParse(options.Id, out id))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
ValidateId(options.Id);
|
||||
var resource = GetResourceById((int)options.Id);
|
||||
return resource.AsResponse();
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ public void Setup()
|
||||
_fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(false);
|
||||
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(false);
|
||||
|
||||
_reports = new List<ReportInfo> {new ReportInfo()};
|
||||
_reports = new List<ReportInfo> { new ReportInfo() };
|
||||
_remoteEpisode = new RemoteEpisode();
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ReportInfo>()))
|
||||
@ -101,6 +101,25 @@ public void should_have_same_number_of_rejections_as_specs_that_failed()
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_not_attempt_to_make_decision_if_remote_episode_is_null()
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
|
||||
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ReportInfo>()))
|
||||
.Returns<RemoteEpisode>(null);
|
||||
|
||||
var results = Subject.GetRssDecision(_reports).ToList();
|
||||
|
||||
_pass1.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>()), Times.Never());
|
||||
_pass2.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>()), Times.Never());
|
||||
_pass3.Verify(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>()), Times.Never());
|
||||
|
||||
results.Should().BeEmpty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
1
NzbDrone.Core.Test/Files/Indexers/Nzbx/nzbx_recent.json
Normal file
1
NzbDrone.Core.Test/Files/Indexers/Nzbx/nzbx_recent.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,22 @@
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Nzbx;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.IntegerationTests
|
||||
{
|
||||
public class NzbxIntegerationTests : CoreTest<FetchFeedService>
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_fetch_rss()
|
||||
{
|
||||
UseRealHttp();
|
||||
|
||||
var indexer = new Nzbx();
|
||||
|
||||
Subject.FetchRss(indexer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using NzbDrone.Core.Indexers.Nzbx;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.ParserTests
|
||||
{
|
||||
public class NzbxParserFixture : CoreTest<NzbxParser>
|
||||
{
|
||||
[Test]
|
||||
public void should_be_able_to_parse_json()
|
||||
{
|
||||
var stream = OpenRead("Files", "Indexers", "Nzbx", "nzbx_recent.json");
|
||||
|
||||
var result = Subject.Process(stream).ToList();
|
||||
|
||||
result.Should().NotBeEmpty();
|
||||
}
|
||||
}
|
||||
}
|
@ -132,6 +132,8 @@
|
||||
<Compile Include="Framework\NBuilderExtensions.cs" />
|
||||
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
||||
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
||||
<Compile Include="IndexerTests\IntegerationTests\NzbxIntegerationTests.cs" />
|
||||
<Compile Include="IndexerTests\ParserTests\NzbxParserFixture.cs" />
|
||||
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
||||
<Compile Include="JobTests\RenameSeasonJobFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
||||
@ -261,10 +263,10 @@
|
||||
<None Include="..\NzbDrone.Test.Common\App.config">
|
||||
<Link>App.config</Link>
|
||||
</None>
|
||||
<None Include="Files\RSS\nzbx_search.json">
|
||||
<None Include="Files\Indexers\Nzbx\nzbx_search.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Files\RSS\nzbx_recent.json">
|
||||
<None Include="Files\Indexers\Nzbx\nzbx_recent.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Files\RSS\omgwtfnzbs.xml">
|
||||
|
@ -29,9 +29,12 @@ public IEnumerable<DownloadDecision> GetRssDecision(IEnumerable<ReportInfo> repo
|
||||
foreach (var report in reports)
|
||||
{
|
||||
var parseResult = _parsingService.Map(report);
|
||||
yield return new DownloadDecision(parseResult, GetGeneralRejectionReasons(parseResult).ToArray());
|
||||
}
|
||||
if (parseResult != null)
|
||||
{
|
||||
|
||||
yield return new DownloadDecision(parseResult, GetGeneralRejectionReasons(parseResult).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<DownloadDecision> GetSearchDecision(IEnumerable<ReportInfo> reports, SearchDefinitionBase searchDefinitionBase)
|
||||
|
@ -14,7 +14,7 @@ public virtual bool EnabledByDefault
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,15 @@ public override bool IsConfigured
|
||||
get { return Settings.IsValid; }
|
||||
}
|
||||
|
||||
protected TSetting Settings { get; private set; }
|
||||
public override bool EnabledByDefault
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public TSetting Settings { get; private set; }
|
||||
|
||||
public void Handle(IndexerSettingUpdatedEvent message)
|
||||
{
|
||||
|
@ -5,6 +5,14 @@ namespace NzbDrone.Core.Indexers.Nzbx
|
||||
{
|
||||
public class Nzbx : Indexer
|
||||
{
|
||||
public override IParseFeed Parser
|
||||
{
|
||||
get
|
||||
{
|
||||
return new NzbxParser();
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "nzbx"; }
|
||||
|
@ -3,8 +3,6 @@
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Nzbx
|
||||
@ -14,9 +12,9 @@ public class NzbxParser : IParseFeed
|
||||
private readonly Logger _logger;
|
||||
private readonly JsonSerializer _serializer;
|
||||
|
||||
public NzbxParser(Logger logger)
|
||||
public NzbxParser()
|
||||
{
|
||||
_logger = logger;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_serializer = new JsonSerializer();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ public interface IParsingService
|
||||
{
|
||||
LocalEpisode GetEpisodes(string fileName, Series series);
|
||||
Series GetSeries(string title);
|
||||
RemoteEpisode Map(ReportInfo indexerParseResult);
|
||||
RemoteEpisode Map(ReportInfo reportInfo);
|
||||
}
|
||||
|
||||
public class ParsingService : IParsingService
|
||||
@ -65,9 +65,34 @@ public Series GetSeries(string title)
|
||||
return _seriesService.FindByTitle(searchTitle);
|
||||
}
|
||||
|
||||
public RemoteEpisode Map(ReportInfo indexerParseResult)
|
||||
public RemoteEpisode Map(ReportInfo reportInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var parsedInfo = Parser.ParseTitle(reportInfo.Title);
|
||||
|
||||
if (parsedInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var series = _seriesService.FindByTitle(parsedInfo.SeriesTitle);
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
_logger.Trace("No matching series {0}", parsedInfo.SeriesTitle);
|
||||
return null;
|
||||
}
|
||||
|
||||
var remoteEpisode = new RemoteEpisode
|
||||
{
|
||||
Series = series,
|
||||
Episodes = GetEpisodes(parsedInfo, series),
|
||||
FullSeason = parsedInfo.FullSeason,
|
||||
Language = parsedInfo.Language,
|
||||
Quality = parsedInfo.Quality,
|
||||
Report = reportInfo
|
||||
};
|
||||
|
||||
return remoteEpisode;
|
||||
}
|
||||
|
||||
private List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series)
|
||||
|
@ -41,8 +41,9 @@ public void should_be_able_to_add_and_delete_series()
|
||||
var rootFolder = RootFolders.Post(new RootFolderResource { Path = Directory.GetCurrentDirectory() });
|
||||
|
||||
series.RootFolderId = rootFolder.Id;
|
||||
series.QualityProfileId = 1;
|
||||
|
||||
Series.Post(series);
|
||||
series = Series.Post(series);
|
||||
|
||||
Series.All().Should().HaveCount(1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user