From 860168fe44ec14d80bdca0aaeced17db2c140e1e Mon Sep 17 00:00:00 2001 From: Alexander Chapliuk Date: Mon, 20 Jan 2020 00:09:10 +0100 Subject: [PATCH] LostFilm: improvements. (#6981) resolves #6801 resolves #6945 resolves #2631 --- src/Jackett.Common/Indexers/LostFilm.cs | 54 +++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/Jackett.Common/Indexers/LostFilm.cs b/src/Jackett.Common/Indexers/LostFilm.cs index 83ed52812..23c9edb3b 100644 --- a/src/Jackett.Common/Indexers/LostFilm.cs +++ b/src/Jackett.Common/Indexers/LostFilm.cs @@ -92,7 +92,6 @@ namespace Jackett.Common.Indexers client: wc, logger: l, p: ps, - // TODO: Provide optional instructions configData: new ConfigurationDataCaptchaLogin()) { Encoding = Encoding.UTF8; @@ -152,7 +151,9 @@ namespace Jackett.Common.Indexers await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("\"success\":true"), () => { var errorMessage = result.Content; - if (errorMessage.StartsWith("\"error\":3,")) + if (errorMessage.Contains("\"error\":2")) + errorMessage = "Captcha is incorrect"; + if (errorMessage.Contains("\"error\":3")) errorMessage = "E-mail or password is incorrect"; throw new ExceptionWithConfigData(errorMessage, configData); }); @@ -226,6 +227,8 @@ namespace Jackett.Common.Indexers /* Torznab query for some series could contains sanitized title. E.g. "Star Wars: The Clone Wars" will become "Star Wars The Clone Wars". Search API on LostFilm.tv doesn't return anything on such search query so the query should be "morphed" even for "tvsearch" queries. + Also the queries to Specials is a union of Series and Episode titles. E.g.: "Breaking Bad - El Camino: A Breaking Bad Movie". + The algorythm works in the following way: 1. Search with the full SearchTerm. Just for example, let's search for episode by it's name - {Star Wars The Clone Wars To Catch a Jedi} @@ -242,7 +245,16 @@ namespace Jackett.Common.Indexers .filterBy(The Clone Wars To Catch) / a Jedi ... .filterBy(The Clone Wars) / To Catch a Jedi - 5. Fetch series detail page for "Star Wars The Clone Wars" with a "To Catch a Jedi" filterTerm to find required episode + 5. [loop] Now we know that series we're looking for is called "Star Wars The Clone Wars". Fetch series detail page for it and try to apply remaining words as episode filter, reducing filter by 1 word each time we get no results: + - .episodes().filteredBy(To Catch a Jedi) + - .episodes().filteredBy(To Catch a) / Jedi + - ... + - .episodes() / To Catch a Jedi + + Test queries: + - "Star Wars The Clone Wars To Catch a Jedi" -> S05E19 + - "Breaking Bad El Camino A Breaking Bad Movie" -> Special + - "The Magicians (2015)" -> Year should be ignored */ // Search query words. Consists of Series keywords that will be used for series search request, and Episode keywords that will be used for episode filtering. @@ -264,10 +276,20 @@ namespace Jackett.Common.Indexers }; logger.Debug("> Searching: " + searchString); var response = await PostDataWithCookies(url: ApiUrl, data: data); + if (response.Content == null) + { + logger.Debug("> Empty series response for query: " + searchString); + continue; + } try { var json = JToken.Parse(response.Content); + if (json == null || json.Type == JTokenType.Array) + { + logger.Debug("> Invalid response for query: " + searchString); + continue; // Search loop + } // Protect from {"data":false,"result":"ok"} var jsonData = json["data"]; @@ -318,11 +340,25 @@ namespace Jackett.Common.Indexers } else // Fetch the whole series OR episode with filter applied { - var filterKeywords = keywords.Skip(searchKeywords + serieFilterKeywords); - var filter = string.Join(" ", filterKeywords); + var episodeKeywords = keywords.Skip(searchKeywords + serieFilterKeywords); + var episodeFilterKeywords = episodeKeywords.Count(); - var taskReleases = await FetchSeriesReleases(url, query, filter); - releases.AddRange(taskReleases); + // Search for episodes dropping 1 filter word each time when no results has found. + // Last search will be performed with empty filter + do + { + var filter = string.Join(" ", episodeKeywords.Take(episodeFilterKeywords)); + logger.Debug("> Searching episodes with filter [" + filter + "]"); + var taskReleases = await FetchSeriesReleases(url, query, filter); + + if (taskReleases.Count() > 0) + { + logger.Debug("> Found " + taskReleases.Count().ToString() + " episodes"); + releases.AddRange(taskReleases); + break; // Episodes Filter loop + } + } + while (--episodeFilterKeywords >= 0); } } @@ -577,6 +613,10 @@ namespace Jackett.Common.Indexers // Get redirection page with generated link on it. This link can't be constructed manually as it contains Hash field and hashing algo is unknown. var results = await RequestStringWithCookies(url); + if (results.Content == null) + { + throw new ExceptionWithConfigData("Empty response from " + url, configData); + } if (results.Content == "log in first") { throw new ExceptionWithConfigData(results.Content, configData);