diff --git a/src/Lidarr.Api.V1/Indexers/ReleaseModule.cs b/src/Lidarr.Api.V1/Indexers/ReleaseModule.cs index d7a170b10..69fd534f5 100644 --- a/src/Lidarr.Api.V1/Indexers/ReleaseModule.cs +++ b/src/Lidarr.Api.V1/Indexers/ReleaseModule.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using FluentValidation; using Nancy; using Nancy.ModelBinding; @@ -13,6 +14,7 @@ using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; using Lidarr.Http.Extensions; +using Lidarr.Http.REST; using HttpStatusCode = System.Net.HttpStatusCode; namespace Lidarr.Api.V1.Indexers @@ -25,6 +27,7 @@ namespace Lidarr.Api.V1.Indexers private readonly IPrioritizeDownloadDecision _prioritizeDownloadDecision; private readonly IDownloadService _downloadService; private readonly Logger _logger; + private ResourceValidator _releaseValidator; private readonly ICached _remoteAlbumCache; @@ -43,17 +46,25 @@ namespace Lidarr.Api.V1.Indexers _downloadService = downloadService; _logger = logger; + _releaseValidator = new ResourceValidator(); + _releaseValidator.RuleFor(s => s.IndexerId).ValidId(); + _releaseValidator.RuleFor(s => s.Guid).NotEmpty(); + GetResourceAll = GetReleases; Post["/"] = x => DownloadRelease(this.Bind()); - PostValidator.RuleFor(s => s.IndexerId).ValidId(); - PostValidator.RuleFor(s => s.Guid).NotEmpty(); - _remoteAlbumCache = cacheManager.GetCache(GetType(), "remoteAlbums"); } private Response DownloadRelease(ReleaseResource release) { + var validationFailures = _releaseValidator.Validate(release).Errors; + + if (validationFailures.Any()) + { + throw new ValidationException(validationFailures); + } + var remoteAlbum = _remoteAlbumCache.Find(GetCacheKey(release)); if (remoteAlbum == null) diff --git a/src/Lidarr.Api.V1/Indexers/ReleasePushModule.cs b/src/Lidarr.Api.V1/Indexers/ReleasePushModule.cs index 9ecf45a78..e484cdd85 100644 --- a/src/Lidarr.Api.V1/Indexers/ReleasePushModule.cs +++ b/src/Lidarr.Api.V1/Indexers/ReleasePushModule.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using FluentValidation; +using FluentValidation.Results; using Nancy; using Nancy.ModelBinding; using NLog; @@ -11,6 +12,10 @@ using Lidarr.Http.Extensions; using NzbDrone.Common.Extensions; using NzbDrone.Core.Datastore; using NzbDrone.Core.Indexers; +using Lidarr.Http.REST; +using System; +using NzbDrone.Core.Exceptions; +using HttpStatusCode = System.Net.HttpStatusCode; namespace Lidarr.Api.V1.Indexers { @@ -20,6 +25,7 @@ namespace Lidarr.Api.V1.Indexers private readonly IProcessDownloadDecisions _downloadDecisionProcessor; private readonly IIndexerFactory _indexerFactory; private readonly Logger _logger; + private ResourceValidator _releaseValidator; public ReleasePushModule(IMakeDownloadDecision downloadDecisionMaker, IProcessDownloadDecisions downloadDecisionProcessor, @@ -31,19 +37,39 @@ namespace Lidarr.Api.V1.Indexers _indexerFactory = indexerFactory; _logger = logger; - Post["/push"] = x => ProcessRelease(this.Bind()); + _releaseValidator = new ResourceValidator(); + _releaseValidator.RuleFor(s => s.Title).NotEmpty(); + _releaseValidator.RuleFor(s => s.DownloadUrl).NotEmpty(); + _releaseValidator.RuleFor(s => s.DownloadProtocol).NotEmpty(); + _releaseValidator.RuleFor(s => s.PublishDate).NotEmpty(); - PostValidator.RuleFor(s => s.Title).NotEmpty(); - PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty(); - PostValidator.RuleFor(s => s.DownloadProtocol).NotEmpty(); - PostValidator.RuleFor(s => s.PublishDate).NotEmpty(); + Post["/push"] = x => ProcessRelease(); } - private Response ProcessRelease(ReleaseResource release) + private Response ProcessRelease() { - _logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl); - var info = release.ToModel(); + var resource = new ReleaseResource(); + + try + { + resource = Request.Body.FromJson(); + } + catch (Exception ex) + { + throw new NzbDroneClientException(HttpStatusCode.BadRequest, ex.Message); + } + + var validationFailures = _releaseValidator.Validate(resource).Errors; + + if (validationFailures.Any()) + { + throw new ValidationException(validationFailures); + } + + _logger.Info("Release pushed: {0} - {1}", resource.Title, resource.DownloadUrl); + + var info = resource.ToModel(); info.Guid = "PUSH-" + info.DownloadUrl; @@ -52,7 +78,14 @@ namespace Lidarr.Api.V1.Indexers var decisions = _downloadDecisionMaker.GetRssDecision(new List { info }); _downloadDecisionProcessor.ProcessDecisions(decisions); - return MapDecisions(decisions).First().AsResponse(); + var firstDecision = decisions.FirstOrDefault(); + + if (firstDecision?.RemoteAlbum.ParsedAlbumInfo == null) + { + throw new ValidationException(new List { new ValidationFailure("Title", "Unable to parse", resource.Title) }); + } + + return MapDecisions(new[] { firstDecision }).AsResponse(); } private void ResolveIndexer(ReleaseInfo release) diff --git a/src/Lidarr.Api.V1/Indexers/ReleaseResource.cs b/src/Lidarr.Api.V1/Indexers/ReleaseResource.cs index 229d4a863..9620a929d 100644 --- a/src/Lidarr.Api.V1/Indexers/ReleaseResource.cs +++ b/src/Lidarr.Api.V1/Indexers/ReleaseResource.cs @@ -54,11 +54,6 @@ namespace Lidarr.Api.V1.Indexers //TODO: besides a test I don't think this is used... public DownloadProtocol DownloadProtocol { get; set; } - //public bool IsDaily { get; set; } - //public bool IsAbsoluteNumbering { get; set; } - //public bool IsPossibleSpecialEpisode { get; set; } - //public bool Special { get; set; } - // Sent when queuing an unknown release [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]