mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-04-24 05:47:22 -04:00
Fixed: (PassThePopcorn) Cleanup and ensure pagination is working in Radarr
This commit is contained in:
parent
f37ccba3f9
commit
3ff144421d
6 changed files with 96 additions and 155 deletions
|
@ -6,9 +6,8 @@ using FluentAssertions;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.PassThePopcorn;
|
||||
using NzbDrone.Core.Indexers.Definitions.PassThePopcorn;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
@ -21,26 +20,22 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
|||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
Subject.Definition = new IndexerDefinition
|
||||
{
|
||||
Name = "PTP",
|
||||
Settings = new PassThePopcornSettings() { APIUser = "asdf", APIKey = "sad" }
|
||||
Settings = new PassThePopcornSettings
|
||||
{
|
||||
APIUser = "asdf",
|
||||
APIKey = "sad"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[TestCase("Files/Indexers/PTP/imdbsearch.json")]
|
||||
public async Task should_parse_feed_from_PTP(string fileName)
|
||||
{
|
||||
var authResponse = new PassThePopcornAuthResponse { Result = "Ok" };
|
||||
|
||||
var authStream = new System.IO.StringWriter();
|
||||
Json.Serialize(authResponse, authStream);
|
||||
var responseJson = ReadAllText(fileName);
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), authStream.ToString())));
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, new CookieCollection(), responseJson)));
|
||||
|
|
|
@ -3,7 +3,7 @@ using NLog;
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.PassThePopcorn
|
||||
namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
|
||||
{
|
||||
public class PassThePopcorn : TorrentIndexerBase<PassThePopcornSettings>
|
||||
{
|
||||
|
@ -29,22 +29,20 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
|
||||
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||
{
|
||||
return new PassThePopcornRequestGenerator
|
||||
{
|
||||
Settings = Settings,
|
||||
HttpClient = _httpClient,
|
||||
Logger = _logger
|
||||
};
|
||||
return new PassThePopcornRequestGenerator(Settings);
|
||||
}
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new PassThePopcornParser(Settings, _logger);
|
||||
}
|
||||
|
||||
private IndexerCapabilities SetCapabilities()
|
||||
{
|
||||
var caps = new IndexerCapabilities
|
||||
{
|
||||
SearchParams = new List<SearchParam>
|
||||
{
|
||||
SearchParam.Q
|
||||
},
|
||||
LimitsDefault = PageSize,
|
||||
LimitsMax = PageSize,
|
||||
MovieSearchParams = new List<MovieSearchParam>
|
||||
{
|
||||
MovieSearchParam.Q, MovieSearchParam.ImdbId
|
||||
|
@ -73,16 +71,11 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
|
||||
return caps;
|
||||
}
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new PassThePopcornParser(Settings, Capabilities, _logger);
|
||||
}
|
||||
}
|
||||
|
||||
public class PassThePopcornFlag : IndexerFlag
|
||||
{
|
||||
public static IndexerFlag Golden => new IndexerFlag("golden", "Release follows Golden Popcorn quality rules");
|
||||
public static IndexerFlag Approved => new IndexerFlag("approved", "Release approved by PTP");
|
||||
public static IndexerFlag Golden => new ("golden", "Release follows Golden Popcorn quality rules");
|
||||
public static IndexerFlag Approved => new ("approved", "Release approved by PTP");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.PassThePopcorn
|
||||
namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
|
||||
{
|
||||
public class Director
|
||||
public class PassThePopcornResponse
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string TotalResults { get; set; }
|
||||
public List<PassThePopcornMovie> Movies { get; set; }
|
||||
public string Page { get; set; }
|
||||
public string AuthKey { get; set; }
|
||||
public string PassKey { get; set; }
|
||||
}
|
||||
|
||||
public class Torrent
|
||||
public class PassThePopcornMovie
|
||||
{
|
||||
public string GroupId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Year { get; set; }
|
||||
public string Cover { get; set; }
|
||||
public List<string> Tags { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public List<PassThePopcornTorrent> Torrents { get; set; }
|
||||
}
|
||||
|
||||
public class PassThePopcornTorrent
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Quality { get; set; }
|
||||
|
@ -29,32 +43,4 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
public bool GoldenPopcorn { get; set; }
|
||||
public string FreeleechType { get; set; }
|
||||
}
|
||||
|
||||
public class Movie
|
||||
{
|
||||
public string GroupId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Year { get; set; }
|
||||
public string Cover { get; set; }
|
||||
public List<string> Tags { get; set; }
|
||||
public List<Director> Directors { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public List<Torrent> Torrents { get; set; }
|
||||
}
|
||||
|
||||
public class PassThePopcornResponse
|
||||
{
|
||||
public string TotalResults { get; set; }
|
||||
public List<Movie> Movies { get; set; }
|
||||
public string Page { get; set; }
|
||||
public string AuthKey { get; set; }
|
||||
public string PassKey { get; set; }
|
||||
}
|
||||
|
||||
public class PassThePopcornAuthResponse
|
||||
{
|
||||
public string Result { get; set; }
|
||||
public string Popcron { get; set; }
|
||||
public string AntiCsrfToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,36 +8,28 @@ using NzbDrone.Common.Serializer;
|
|||
using NzbDrone.Core.Indexers.Exceptions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.PassThePopcorn
|
||||
namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
|
||||
{
|
||||
public class PassThePopcornParser : IParseIndexerResponse
|
||||
{
|
||||
private readonly IndexerCapabilities _capabilities;
|
||||
private readonly PassThePopcornSettings _settings;
|
||||
private readonly Logger _logger;
|
||||
public PassThePopcornParser(PassThePopcornSettings settings, IndexerCapabilities capabilities, Logger logger)
|
||||
|
||||
public PassThePopcornParser(PassThePopcornSettings settings, Logger logger)
|
||||
{
|
||||
_settings = settings;
|
||||
_capabilities = capabilities;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||
{
|
||||
var torrentInfos = new List<ReleaseInfo>();
|
||||
var indexerHttpResponse = indexerResponse.HttpResponse;
|
||||
|
||||
if (indexerHttpResponse.StatusCode != HttpStatusCode.OK)
|
||||
var httpResponse = indexerResponse.HttpResponse;
|
||||
|
||||
if (httpResponse.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
// Remove cookie cache
|
||||
if (indexerHttpResponse.HasHttpRedirect && indexerHttpResponse.RedirectUrl
|
||||
.ContainsIgnoreCase("login.php"))
|
||||
{
|
||||
CookiesUpdater(null, null);
|
||||
throw new IndexerAuthException("We are being redirected to the PTP login page. Most likely your session expired or was killed. Recheck your cookie or credentials and try testing the indexer.");
|
||||
}
|
||||
|
||||
if (indexerHttpResponse.StatusCode == HttpStatusCode.Forbidden)
|
||||
if (httpResponse.StatusCode == HttpStatusCode.Forbidden)
|
||||
{
|
||||
throw new RequestLimitReachedException(indexerResponse, "PTP Query Limit Reached. Please try again later.");
|
||||
}
|
||||
|
@ -45,19 +37,13 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
throw new IndexerException(indexerResponse, $"Unexpected response status {indexerResponse.HttpResponse.StatusCode} code from indexer request");
|
||||
}
|
||||
|
||||
if (indexerHttpResponse.Headers.ContentType != HttpAccept.Json.Value)
|
||||
if (httpResponse.Headers.ContentType != HttpAccept.Json.Value)
|
||||
{
|
||||
if (indexerHttpResponse.Request.Url.Path.ContainsIgnoreCase("login.php"))
|
||||
{
|
||||
CookiesUpdater(null, null);
|
||||
throw new IndexerAuthException("We are currently on the login page. Most likely your session expired or was killed. Try testing the indexer in the settings.");
|
||||
}
|
||||
|
||||
// Remove cookie cache
|
||||
throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from indexer request, expected {HttpAccept.Json.Value}");
|
||||
}
|
||||
|
||||
var jsonResponse = STJson.Deserialize<PassThePopcornResponse>(indexerResponse.Content);
|
||||
|
||||
if (jsonResponse.TotalResults == "0" ||
|
||||
jsonResponse.TotalResults.IsNullOrWhiteSpace() ||
|
||||
jsonResponse.Movies == null)
|
||||
|
@ -70,7 +56,6 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
foreach (var torrent in result.Torrents)
|
||||
{
|
||||
var id = torrent.Id;
|
||||
var title = torrent.ReleaseName;
|
||||
|
||||
var flags = new HashSet<IndexerFlag>();
|
||||
|
||||
|
@ -81,37 +66,32 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
|
||||
if (torrent.Checked)
|
||||
{
|
||||
flags.Add(PassThePopcornFlag.Approved); //title = $"{title} ✔";
|
||||
flags.Add(PassThePopcornFlag.Approved);
|
||||
}
|
||||
|
||||
if (torrent.Scene)
|
||||
{
|
||||
flags.Add(IndexerFlag.Scene);
|
||||
}
|
||||
|
||||
var free = !(torrent.FreeleechType is null);
|
||||
|
||||
// Only add approved torrents
|
||||
try
|
||||
{
|
||||
torrentInfos.Add(new TorrentInfo
|
||||
{
|
||||
Guid = string.Format("PassThePopcorn-{0}", id),
|
||||
Title = title,
|
||||
Size = long.Parse(torrent.Size),
|
||||
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
||||
Guid = $"PassThePopcorn-{id}",
|
||||
Title = torrent.ReleaseName,
|
||||
InfoUrl = GetInfoUrl(result.GroupId, id),
|
||||
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
||||
Categories = new List<IndexerCategory> { NewznabStandardCategory.Movies },
|
||||
Size = long.Parse(torrent.Size),
|
||||
Grabs = int.Parse(torrent.Snatched),
|
||||
Seeders = int.Parse(torrent.Seeders),
|
||||
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||
PublishDate = torrent.UploadTime.ToUniversalTime(),
|
||||
ImdbId = result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0,
|
||||
Scene = torrent.Scene,
|
||||
IndexerFlags = flags,
|
||||
DownloadVolumeFactor = torrent.FreeleechType is "Freeleech" ? 0 : 1,
|
||||
UploadVolumeFactor = 1,
|
||||
MinimumRatio = 1,
|
||||
MinimumSeedTime = 345600,
|
||||
DownloadVolumeFactor = free ? 0 : 1,
|
||||
UploadVolumeFactor = 1,
|
||||
Categories = new List<IndexerCategory> { NewznabStandardCategory.Movies }
|
||||
Genres = result.Tags ?? new List<string>()
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.PassThePopcorn
|
||||
namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
|
||||
{
|
||||
public class PassThePopcornRequestGenerator : IIndexerRequestGenerator
|
||||
{
|
||||
public PassThePopcornSettings Settings { get; set; }
|
||||
private readonly PassThePopcornSettings _settings;
|
||||
|
||||
public IDictionary<string, string> Cookies { get; set; }
|
||||
|
||||
public IIndexerHttpClient HttpClient { get; set; }
|
||||
public Logger Logger { get; set; }
|
||||
public PassThePopcornRequestGenerator(PassThePopcornSettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
|
@ -34,51 +33,6 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
return pageableRequests;
|
||||
}
|
||||
|
||||
public Func<IDictionary<string, string>> GetCookies { get; set; }
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
|
||||
private IEnumerable<IndexerRequest> GetRequest(string searchParameters, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
var queryParams = new NameValueCollection
|
||||
{
|
||||
{ "action", "advanced" },
|
||||
{ "json", "noredirect" },
|
||||
{ "grouping", "0" },
|
||||
{ "searchstr", searchParameters }
|
||||
};
|
||||
|
||||
if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0)
|
||||
{
|
||||
var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1;
|
||||
queryParams.Set("page", page.ToString());
|
||||
}
|
||||
|
||||
if (Settings.FreeleechOnly)
|
||||
{
|
||||
queryParams.Set("freetorrent", "1");
|
||||
}
|
||||
|
||||
var request =
|
||||
new IndexerRequest(
|
||||
$"{Settings.BaseUrl.Trim().TrimEnd('/')}/torrents.php?{queryParams.GetQueryString()}",
|
||||
HttpAccept.Json);
|
||||
|
||||
request.HttpRequest.Headers["ApiUser"] = Settings.APIUser;
|
||||
request.HttpRequest.Headers["ApiKey"] = Settings.APIKey;
|
||||
|
||||
if (Settings.APIKey.IsNullOrWhiteSpace())
|
||||
{
|
||||
foreach (var cookie in Cookies)
|
||||
{
|
||||
request.HttpRequest.Cookies[cookie.Key] = cookie.Value;
|
||||
}
|
||||
|
||||
CookiesUpdater(Cookies, DateTime.Now.AddDays(30));
|
||||
}
|
||||
|
||||
yield return request;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
|
||||
{
|
||||
return new IndexerPageableRequestChain();
|
||||
|
@ -102,5 +56,38 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
private IEnumerable<IndexerRequest> GetRequest(string searchParameters, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
var parameters = new NameValueCollection
|
||||
{
|
||||
{ "action", "advanced" },
|
||||
{ "json", "noredirect" },
|
||||
{ "grouping", "0" },
|
||||
{ "searchstr", searchParameters }
|
||||
};
|
||||
|
||||
if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0)
|
||||
{
|
||||
var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1;
|
||||
parameters.Set("page", page.ToString());
|
||||
}
|
||||
|
||||
if (_settings.FreeleechOnly)
|
||||
{
|
||||
parameters.Set("freetorrent", "1");
|
||||
}
|
||||
|
||||
var searchUrl = $"{_settings.BaseUrl.Trim().TrimEnd('/')}/torrents.php?{parameters.GetQueryString()}";
|
||||
|
||||
var request = new IndexerRequest(searchUrl, HttpAccept.Json);
|
||||
request.HttpRequest.Headers.Add("ApiUser", _settings.APIUser);
|
||||
request.HttpRequest.Headers.Add("ApiKey", _settings.APIKey);
|
||||
|
||||
yield return request;
|
||||
}
|
||||
|
||||
public Func<IDictionary<string, string>> GetCookies { get; set; }
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ using NzbDrone.Core.Annotations;
|
|||
using NzbDrone.Core.Indexers.Settings;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.PassThePopcorn
|
||||
namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
|
||||
{
|
||||
public class PassThePopcornSettingsValidator : NoAuthSettingsValidator<PassThePopcornSettings>
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue