diff --git a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs index 4ff626743..ac1ff2f08 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PornoLab.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using AngleSharp.Html.Parser; -using FluentValidation; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; @@ -17,14 +17,13 @@ using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions { public class PornoLab : TorrentIndexerBase { public override string Name => "PornoLab"; - public override string[] IndexerUrls => new string[] { "https://pornolab.net/" }; + public override string[] IndexerUrls => new[] { "https://pornolab.net/" }; private string LoginUrl => Settings.BaseUrl + "forum/login.php"; public override string Description => "PornoLab is a Semi-Private Russian site for Adult content"; public override string Language => "ru-RU"; @@ -40,7 +39,7 @@ namespace NzbDrone.Core.Indexers.Definitions public override IIndexerRequestGenerator GetRequestGenerator() { - return new PornoLabRequestGenerator() { Settings = Settings, Capabilities = Capabilities }; + return new PornoLabRequestGenerator(Settings, Capabilities); } public override IParseIndexerResponse GetParser() @@ -68,38 +67,26 @@ namespace NzbDrone.Core.Indexers.Definitions if (CheckIfLoginNeeded(response)) { - var errorMessage = "Unknown error message, please report"; var loginResultParser = new HtmlParser(); var loginResultDocument = loginResultParser.ParseDocument(response.Content); - var errormsg = loginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]"); - if (errormsg != null) - { - errorMessage = errormsg.TextContent; - } + var errorMessage = loginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]")?.TextContent; - throw new IndexerAuthException(errorMessage); + throw new IndexerAuthException(errorMessage ?? "Unknown error message, please report"); } UpdateCookies(response.GetCookies(), DateTime.Now + TimeSpan.FromDays(30)); - _logger.Debug("PornoLab authentication succeeded"); + _logger.Debug("Authentication succeeded"); } protected override bool CheckIfLoginNeeded(HttpResponse httpResponse) { - if (!httpResponse.Content.Contains("Вы зашли как:")) - { - return true; - } - - return false; + return !httpResponse.Content.Contains("Вы зашли как:"); } private IndexerCapabilities SetCapabilities() { - var caps = new IndexerCapabilities - { - }; + var caps = new IndexerCapabilities(); caps.Categories.AddCategoryMapping(1768, NewznabStandardCategory.XXX, "Эротические фильмы / Erotic Movies"); caps.Categories.AddCategoryMapping(60, NewznabStandardCategory.XXX, "Документальные фильмы / Documentary & Reality"); @@ -246,44 +233,36 @@ namespace NzbDrone.Core.Indexers.Definitions public class PornoLabRequestGenerator : IIndexerRequestGenerator { - public PornoLabSettings Settings { get; set; } - public IndexerCapabilities Capabilities { get; set; } + private readonly PornoLabSettings _settings; + private readonly IndexerCapabilities _capabilities; - public PornoLabRequestGenerator() + public PornoLabRequestGenerator(PornoLabSettings settings, IndexerCapabilities capabilities) { + _settings = settings; + _capabilities = capabilities; } private IEnumerable GetPagedRequests(string term, int[] categories) { - var searchUrl = string.Format("{0}/forum/tracker.php", Settings.BaseUrl.TrimEnd('/')); - - var searchString = term; - - // NameValueCollection don't support cat[]=19&cat[]=6 - var qc = new List> + var parameters = new List> { { "o", "1" }, - { "s", "2" } + { "s", "2" }, + { "nm", term.IsNotNullOrWhiteSpace() ? term.Replace("-", " ") : "" } }; - // if the search string is empty use the getnew view - if (string.IsNullOrWhiteSpace(searchString)) + var queryCats = _capabilities.Categories.MapTorznabCapsToTrackers(categories); + if (queryCats.Any()) { - qc.Add("nm", searchString); - } - else - { - // use the normal search - searchString = searchString.Replace("-", " "); - qc.Add("nm", searchString); + queryCats.ForEach(cat => parameters.Add("f[]", $"{cat}")); } - foreach (var cat in Capabilities.Categories.MapTorznabCapsToTrackers(categories)) - { - qc.Add("f[]", cat); - } + var searchUrl = $"{_settings.BaseUrl.TrimEnd('/')}/forum/tracker.php"; - searchUrl = searchUrl + "?" + qc.GetQueryString(); + if (parameters.Count > 0) + { + searchUrl += $"?{parameters.GetQueryString()}"; + } var request = new IndexerRequest(searchUrl, HttpAccept.Html); @@ -294,7 +273,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria.Categories)); return pageableRequests; } @@ -303,7 +282,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria.Categories)); return pageableRequests; } @@ -312,7 +291,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedTvSearchString), searchCriteria.Categories)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedTvSearchString}", searchCriteria.Categories)); return pageableRequests; } @@ -321,7 +300,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria.Categories)); return pageableRequests; } @@ -330,7 +309,7 @@ namespace NzbDrone.Core.Indexers.Definitions { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories)); + pageableRequests.Add(GetPagedRequests($"{searchCriteria.SanitizedSearchTerm}", searchCriteria.Categories)); return pageableRequests; } @@ -344,7 +323,7 @@ namespace NzbDrone.Core.Indexers.Definitions private readonly PornoLabSettings _settings; private readonly IndexerCapabilitiesCategories _categories; private readonly Logger _logger; - private static readonly Regex StripRussianRegex = new Regex(@"(\([А-Яа-яЁё\W]+\))|(^[А-Яа-яЁё\W\d]+\/ )|([а-яА-ЯЁё \-]+,+)|([а-яА-ЯЁё]+)"); + private static readonly Regex StripRussianRegex = new (@"(\([\p{IsCyrillic}\W]+\))|(^[\p{IsCyrillic}\W\d]+\/ )|([\p{IsCyrillic} \-]+,+)|([\p{IsCyrillic}]+)"); public PornoLabParser(PornoLabSettings settings, IndexerCapabilitiesCategories categories, Logger logger) { @@ -355,13 +334,12 @@ namespace NzbDrone.Core.Indexers.Definitions public IList ParseResponse(IndexerResponse indexerResponse) { - var torrentInfos = new List(); - - var rowsSelector = "table#tor-tbl > tbody > tr"; + var releaseInfos = new List(); var searchResultParser = new HtmlParser(); var searchResultDocument = searchResultParser.ParseDocument(indexerResponse.Content); - var rows = searchResultDocument.QuerySelectorAll(rowsSelector); + + var rows = searchResultDocument.QuerySelectorAll("table#tor-tbl > tbody > tr"); foreach (var row in rows) { try @@ -377,48 +355,47 @@ namespace NzbDrone.Core.Indexers.Definitions var qForumLink = row.QuerySelector("a.f"); var qDetailsLink = row.QuerySelector("a.tLink"); var qSize = row.QuerySelector("td:nth-child(6) u"); - var link = new Uri(_settings.BaseUrl + "forum/" + qDetailsLink.GetAttribute("href")); + var infoUrl = _settings.BaseUrl + "forum/" + qDetailsLink.GetAttribute("href"); var seederString = row.QuerySelector("td:nth-child(7) b").TextContent; var seeders = string.IsNullOrWhiteSpace(seederString) ? 0 : ParseUtil.CoerceInt(seederString); - var timestr = row.QuerySelector("td:nth-child(11) u").TextContent; - var forum = qForumLink; - var forumid = forum.GetAttribute("href").Split('=')[1]; + var forumid = ParseUtil.GetArgumentFromQueryString(qForumLink?.GetAttribute("href"), "f"); var title = _settings.StripRussianLetters - ? StripRussianRegex.Replace(qDetailsLink.TextContent, "") + ? StripRussianRegex.Replace(qDetailsLink.TextContent, string.Empty) : qDetailsLink.TextContent; var size = ParseUtil.GetBytes(qSize.TextContent); var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(8)").TextContent); var grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(9)").TextContent); - var publishDate = DateTimeUtil.UnixTimestampToDateTime(long.Parse(timestr)); + var publishDate = DateTimeUtil.UnixTimestampToDateTime(long.Parse(row.QuerySelector("td:nth-child(11) u").TextContent)); + var release = new TorrentInfo { - MinimumRatio = 1, - MinimumSeedTime = 0, + Guid = infoUrl, + DownloadUrl = infoUrl, + InfoUrl = infoUrl, Title = title, - InfoUrl = link.AbsoluteUri, Description = qForumLink.TextContent, - DownloadUrl = link.AbsoluteUri, - Guid = link.AbsoluteUri, + Categories = _categories.MapTrackerCatToNewznab(forumid), Size = size, + Grabs = grabs, Seeders = seeders, Peers = leechers + seeders, - Grabs = grabs, PublishDate = publishDate, - Categories = _categories.MapTrackerCatToNewznab(forumid), DownloadVolumeFactor = 1, - UploadVolumeFactor = 1 + UploadVolumeFactor = 1, + MinimumRatio = 1, + MinimumSeedTime = 0, }; - torrentInfos.Add(release); + releaseInfos.Add(release); } catch (Exception ex) { - _logger.Error(string.Format("Pornolab: Error while parsing row '{0}':\n\n{1}", row.OuterHtml, ex)); + _logger.Error($"Pornolab: Error while parsing row '{row.OuterHtml}':\n\n{ex}"); } } - return torrentInfos.ToArray(); + return releaseInfos.ToArray(); } public Action, DateTime?> CookiesUpdater { get; set; } @@ -428,6 +405,7 @@ namespace NzbDrone.Core.Indexers.Definitions { public PornoLabSettings() { + StripRussianLetters = false; } [FieldDefinition(4, Label = "Strip Russian Letters", HelpLink = "Strip Cyrillic letters from release names", Type = FieldType.Checkbox)]