diff --git a/src/Jackett.Common/Indexers/XSpeeds.cs b/src/Jackett.Common/Indexers/XSpeeds.cs index 5136ac5ce..36a851d8d 100644 --- a/src/Jackett.Common/Indexers/XSpeeds.cs +++ b/src/Jackett.Common/Indexers/XSpeeds.cs @@ -142,8 +142,35 @@ namespace Jackett.Common.Indexers AddCategoryMapping("Wii Games", TorznabCatType.ConsoleWii); AddCategoryMapping("Wrestling", TorznabCatType.TVSport); AddCategoryMapping("Xbox Games", TorznabCatType.ConsoleXBox); + + // Configure the sort selects + var sortBySelect = new SingleSelectConfigurationItem( + "Sort by", + new Dictionary + { + { "added", "created" }, + { "seeders", "seeders" }, + { "size", "size" }, + { "name", "title" } + }) + { Value = "added" }; + configData.AddDynamic("sortrequestedfromsite", sortBySelect); + + var orderSelect = new SingleSelectConfigurationItem( + "Order", + new Dictionary + { + { "desc", "descending" }, + { "asc", "ascending" } + }) + { Value = "desc" }; + configData.AddDynamic("orderrequestedfromsite", orderSelect); } + private string GetSortBy => ((SingleSelectConfigurationItem)configData.GetDynamic("sortrequestedfromsite")).Value; + + private string GetOrder => ((SingleSelectConfigurationItem)configData.GetDynamic("orderrequestedfromsite")).Value; + public override async Task GetConfigurationForSetup() { var loginPage = await RequestWithCookiesAsync(LandingUrl); @@ -170,12 +197,11 @@ namespace Jackett.Common.Indexers public override async Task ApplyConfiguration(JToken configJson) { LoadValuesFromJson(configJson); - var pairs = new Dictionary - { - {"username", configData.Username.Value}, - {"password", configData.Password.Value} - }; + { + { "username", configData.Username.Value }, + { "password", configData.Password.Value } + }; var captchaText = (StringConfigurationItem)configData.GetDynamic("CaptchaText"); if (captchaText != null) @@ -183,26 +209,26 @@ namespace Jackett.Common.Indexers //var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink, true); var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SearchUrl, LandingUrl, true); - await ConfigureIfOK(result.Cookies, result.ContentString?.Contains("logout.php") == true, - () => - { - var parser = new HtmlParser(); - var dom = parser.ParseDocument(result.ContentString); - var errorMessage = dom.QuerySelector(".left_side table:nth-of-type(1) tr:nth-of-type(2)")?.TextContent.Trim().Replace("\n\t", " "); - if (string.IsNullOrWhiteSpace(errorMessage)) - errorMessage = dom.QuerySelector("div.notification-body").TextContent.Trim().Replace("\n\t", " "); - throw new ExceptionWithConfigData(errorMessage, configData); - }); + await ConfigureIfOK(result.Cookies, result.ContentString?.Contains("logout.php") == true, () => + { + var parser = new HtmlParser(); + var dom = parser.ParseDocument(result.ContentString); + var errorMessage = dom.QuerySelector(".left_side table:nth-of-type(1) tr:nth-of-type(2)")?.TextContent.Trim().Replace("\n\t", " "); + if (string.IsNullOrWhiteSpace(errorMessage)) + errorMessage = dom.QuerySelector("div.notification-body")?.TextContent.Trim().Replace("\n\t", " "); + + throw new ExceptionWithConfigData(errorMessage ?? "Login failed.", configData); + }); try { // Get RSS key var rssParams = new Dictionary - { - {"feedtype", "download"}, - {"timezone", "0"}, - {"showrows", "50"} - }; + { + { "feedtype", "download" }, + { "timezone", "0" }, + { "showrows", "50" } + }; var rssPage = await RequestWithCookiesAsync( GetRSSKeyUrl, result.Cookies, RequestType.POST, data: rssParams); var match = Regex.Match(rssPage.ContentString, "(?<=secret_key\\=)([a-zA-z0-9]*)"); @@ -216,19 +242,24 @@ namespace Jackett.Common.Indexers IsConfigured = false; throw; } + return IndexerConfigurationStatus.RequiresTesting; } protected override async Task> PerformQuery(TorznabQuery query) { - var releases = new List(); var searchString = query.GetQueryString(); var prevCook = CookieHeader + ""; - var searchParams = new Dictionary { + var categoryMapping = MapTorznabCapsToTrackers(query); + + var searchParams = new Dictionary + { { "do", "search" }, - { "category", "0" }, - { "include_dead_torrents", "no" } + { "category", categoryMapping.FirstIfSingleOrDefault("0") }, // multi category search not supported + { "include_dead_torrents", "yes" }, + { "sort", GetSortBy }, + { "order", GetOrder } }; if (query.IsImdbQuery) @@ -242,16 +273,16 @@ namespace Jackett.Common.Indexers searchParams.Add("search_type", "t_name"); } - var searchPage = await RequestWithCookiesAndRetryAsync( - SearchUrl, CookieHeader, RequestType.POST, null, searchParams); + var searchPage = await RequestWithCookiesAndRetryAsync(SearchUrl, CookieHeader, RequestType.POST, null, searchParams); // Occasionally the cookies become invalid, login again if that happens if (searchPage.IsRedirect) { await ApplyConfiguration(null); - searchPage = await RequestWithCookiesAndRetryAsync( - SearchUrl, CookieHeader, RequestType.POST, null, searchParams); + searchPage = await RequestWithCookiesAndRetryAsync(SearchUrl, CookieHeader, RequestType.POST, null, searchParams); } + var releases = new List(); + try { var parser = new HtmlParser();