Downloading releases via Manual Search are now processed via unique id to allow caching more Release details.

This commit is contained in:
Taloth Saldono 2014-08-06 19:29:34 +02:00
parent 9b5bf374a6
commit 518a75ea5c
7 changed files with 71 additions and 22 deletions

View File

@ -14,6 +14,8 @@ using Omu.ValueInjecter;
using System.Linq;
using Nancy.ModelBinding;
using NzbDrone.Api.Extensions;
using NzbDrone.Common.Cache;
using System.Threading;
namespace NzbDrone.Api.Indexers
{
@ -27,12 +29,15 @@ namespace NzbDrone.Api.Indexers
private readonly IParsingService _parsingService;
private readonly Logger _logger;
private readonly ICached<RemoteEpisode> _remoteEpisodeCache;
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
ISearchForNzb nzbSearchService,
IMakeDownloadDecision downloadDecisionMaker,
IPrioritizeDownloadDecision prioritizeDownloadDecision,
IDownloadService downloadService,
IParsingService parsingService,
ICacheManager cacheManager,
Logger logger)
{
_rssFetcherAndParser = rssFetcherAndParser;
@ -43,15 +48,24 @@ namespace NzbDrone.Api.Indexers
_parsingService = parsingService;
_logger = logger;
GetResourceAll = GetReleases;
Post["/"] = x=> DownloadRelease(this.Bind<ReleaseResource>());
Post["/"] = x => DownloadRelease(this.Bind<ReleaseResource>());
PostValidator.RuleFor(s => s.DownloadAllowed).Equal(true);
_remoteEpisodeCache = cacheManager.GetCache<RemoteEpisode>(GetType(), "remoteEpisodes");
}
private Response DownloadRelease(ReleaseResource release)
{
var remoteEpisode = _parsingService.Map(release.InjectTo<ParsedEpisodeInfo>(), release.TvRageId);
remoteEpisode.Release = release.InjectTo<ReleaseInfo>();
var remoteEpisode = _remoteEpisodeCache.Find(release.Guid);
if (remoteEpisode == null)
{
_logger.Debug("Couldn't find requested release in cache, cache timeout probably expired.");
return new NotFoundResponse();
}
_downloadService.DownloadReport(remoteEpisode);
return release.AsResponse();
@ -93,12 +107,14 @@ namespace NzbDrone.Api.Indexers
return MapDecisions(prioritizedDecisions);
}
private static List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
private List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
{
var result = new List<ReleaseResource>();
foreach (var downloadDecision in decisions)
{
_remoteEpisodeCache.Set(downloadDecision.RemoteEpisode.Release.Guid, downloadDecision.RemoteEpisode, TimeSpan.FromMinutes(30));
var release = new ReleaseResource();
release.InjectFrom(downloadDecision.RemoteEpisode.Release);

View File

@ -9,6 +9,7 @@ namespace NzbDrone.Api.Indexers
{
public class ReleaseResource : RestResource
{
public String Guid { get; set; }
public QualityModel Quality { get; set; }
public Int32 QualityWeight { get; set; }
public Int32 Age { get; set; }

View File

@ -174,6 +174,8 @@ namespace NzbDrone.Core.Indexers
}
}
result = result.DistinctBy(v => v.Guid).ToList();
result.ForEach(c =>
{
c.Indexer = indexer.Definition.Name;

View File

@ -47,8 +47,6 @@ namespace NzbDrone.Core.Indexers
if (reportInfo != null)
{
reportInfo.DownloadUrl = GetNzbUrl(item);
reportInfo.InfoUrl = GetNzbInfoUrl(item);
result.Add(reportInfo);
}
}
@ -65,11 +63,10 @@ namespace NzbDrone.Core.Indexers
private ReleaseInfo ParseFeedItem(XElement item, string url)
{
var title = GetTitle(item);
var reportInfo = CreateNewReleaseInfo();
reportInfo.Title = title;
reportInfo.Guid = GetGuid(item);
reportInfo.Title = GetTitle(item);
reportInfo.PublishDate = GetPublishDate(item);
reportInfo.DownloadUrl = GetNzbUrl(item);
reportInfo.InfoUrl = GetNzbInfoUrl(item);
@ -83,11 +80,16 @@ namespace NzbDrone.Core.Indexers
throw new SizeParsingException("Unable to parse size from: {0} [{1}]", reportInfo.Title, url);
}
_logger.Trace("Parsed: {0}", item.Title());
_logger.Trace("Parsed: {0}", reportInfo.Title);
return PostProcessor(item, reportInfo);
}
protected virtual String GetGuid(XElement item)
{
return item.TryGetValue("guid", Guid.NewGuid().ToString());
}
protected virtual string GetTitle(XElement item)
{
return item.Title();

View File

@ -5,14 +5,15 @@ namespace NzbDrone.Core.Parser.Model
{
public class ReleaseInfo
{
public string Title { get; set; }
public long Size { get; set; }
public string DownloadUrl { get; set; }
public string InfoUrl { get; set; }
public string CommentUrl { get; set; }
public String Guid { get; set; }
public String Title { get; set; }
public Int64 Size { get; set; }
public String DownloadUrl { get; set; }
public String InfoUrl { get; set; }
public String CommentUrl { get; set; }
public String Indexer { get; set; }
public DownloadProtocol DownloadProtocol { get; set; }
public int TvRageId { get; set; }
public Int32 TvRageId { get; set; }
public DateTime PublishDate { get; set; }
public Int32 Age

View File

@ -48,18 +48,18 @@ namespace NzbDrone.Integration.Test.Client
}
public TResource Post(TResource body)
public TResource Post(TResource body, HttpStatusCode statusCode = HttpStatusCode.Created)
{
var request = BuildRequest();
request.AddBody(body);
return Post<TResource>(request);
return Post<TResource>(request, statusCode);
}
public TResource Put(TResource body)
public TResource Put(TResource body, HttpStatusCode statusCode = HttpStatusCode.Accepted)
{
var request = BuildRequest();
request.AddBody(body);
return Put<TResource>(request);
return Put<TResource>(request, statusCode);
}
public TResource Get(int id, HttpStatusCode statusCode = HttpStatusCode.OK)

View File

@ -1,7 +1,11 @@
using System.Linq;
using FluentAssertions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Api.Indexers;
using NzbDrone.Api.Series;
using NzbDrone.Test.Common;
using System.Linq;
using System.Net;
using System.Threading;
namespace NzbDrone.Integration.Test
{
@ -18,8 +22,31 @@ namespace NzbDrone.Integration.Test
releases.Should().OnlyContain(c => BeValidRelease(c));
}
[Test]
public void should_reject_unknown_release()
{
var result = Releases.Post(new ReleaseResource { Guid = "unknown" }, HttpStatusCode.NotFound);
result.Id.Should().Be(0);
}
[Test]
public void should_accept_request_with_only_guid_supplied()
{
var releases = Releases.All();
// InternalServerError is caused by the Release being invalid for download (no Series).
// But if it didn't accept it, it would return NotFound.
// TODO: Maybe we should create a full mock Newznab server endpoint.
//var result = Releases.Post(new ReleaseResource { Guid = releases.First().Guid });
//result.Guid.Should().Be(releases.First().Guid);
var result = Releases.Post(new ReleaseResource { Guid = releases.First().Guid }, HttpStatusCode.InternalServerError);
}
private bool BeValidRelease(ReleaseResource releaseResource)
{
releaseResource.Guid.Should().NotBeNullOrEmpty();
releaseResource.Age.Should().BeGreaterOrEqualTo(-1);
releaseResource.Title.Should().NotBeNullOrWhiteSpace();
releaseResource.DownloadUrl.Should().NotBeNullOrWhiteSpace();