From e2592121c654db61326309b45c2d8ca6f7a2f8b6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 3 Jan 2024 10:58:54 +0200 Subject: [PATCH] gazellegamesapi: update categories and refactor parsing (#14948) --- .../Indexers/Abstract/GazelleTracker.cs | 2 +- .../Indexers/GazelleGamesAPI.cs | 121 ++++++++++++------ 2 files changed, 81 insertions(+), 42 deletions(-) diff --git a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs index 48f40063f..66d466e7f 100644 --- a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs +++ b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs @@ -540,7 +540,7 @@ namespace Jackett.Common.Indexers.Abstract public override async Task Download(Uri link) { var apiKey = configData.ApiKey; - var headers = apiKey != null ? new Dictionary { [AuthorizationName] = String.Format(AuthorizationFormat, apiKey.Value) } : null; + var headers = apiKey != null ? new Dictionary { [AuthorizationName] = string.Format(AuthorizationFormat, apiKey.Value) } : null; var response = await base.RequestWithCookiesAsync(link.ToString(), null, RequestType.GET, headers: headers); var content = response.ContentBytes; diff --git a/src/Jackett.Common/Indexers/GazelleGamesAPI.cs b/src/Jackett.Common/Indexers/GazelleGamesAPI.cs index ed7f61157..aaafb22fa 100644 --- a/src/Jackett.Common/Indexers/GazelleGamesAPI.cs +++ b/src/Jackett.Common/Indexers/GazelleGamesAPI.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Linq; using System.Net; using System.Threading.Tasks; +using Jackett.Common.Extensions; using Jackett.Common.Indexers.Abstract; using Jackett.Common.Models; using Jackett.Common.Models.IndexerConfig.Bespoke; @@ -59,6 +61,7 @@ namespace Jackett.Common.Indexers caps.Categories.AddCategoryMapping("Mac", TorznabCatType.ConsoleOther, "Mac"); caps.Categories.AddCategoryMapping("iOS", TorznabCatType.PCMobileiOS, "iOS"); caps.Categories.AddCategoryMapping("Apple Bandai Pippin", TorznabCatType.ConsoleOther, "Apple Bandai Pippin"); + caps.Categories.AddCategoryMapping("Apple II", TorznabCatType.ConsoleOther, "Apple II"); // Google caps.Categories.AddCategoryMapping("Android", TorznabCatType.PCMobileAndroid, "Android"); @@ -81,6 +84,7 @@ namespace Jackett.Common.Indexers caps.Categories.AddCategoryMapping("Nintendo GameCube", TorznabCatType.ConsoleOther, "Nintendo GameCube"); caps.Categories.AddCategoryMapping("Pokemon Mini", TorznabCatType.ConsoleOther, "Pokemon Mini"); caps.Categories.AddCategoryMapping("SNES", TorznabCatType.ConsoleOther, "SNES"); + caps.Categories.AddCategoryMapping("Switch", TorznabCatType.ConsoleOther, "Switch"); caps.Categories.AddCategoryMapping("Virtual Boy", TorznabCatType.ConsoleOther, "Virtual Boy"); caps.Categories.AddCategoryMapping("Wii", TorznabCatType.ConsoleWii, "Wii"); caps.Categories.AddCategoryMapping("Wii U", TorznabCatType.ConsoleWiiU, "Wii U"); @@ -181,9 +185,10 @@ namespace Jackett.Common.Indexers caps.Categories.AddCategoryMapping("Retro - Other", TorznabCatType.ConsoleOther, "Retro - Other"); // special categories (real categories/not platforms) - caps.Categories.AddCategoryMapping("OST", TorznabCatType.AudioOther, "OST"); - caps.Categories.AddCategoryMapping("Applications", TorznabCatType.PC0day, "Applications"); - caps.Categories.AddCategoryMapping("E-Books", TorznabCatType.BooksEBook, "E-Books"); + caps.Categories.AddCategoryMapping(1, TorznabCatType.PCGames, "Games"); + caps.Categories.AddCategoryMapping(2, TorznabCatType.PC0day, "Applications"); + caps.Categories.AddCategoryMapping(3, TorznabCatType.BooksEBook, "E-Books"); + caps.Categories.AddCategoryMapping(4, TorznabCatType.AudioOther, "OST"); return caps; } @@ -203,20 +208,32 @@ namespace Jackett.Common.Indexers { "order_way", "desc" } }; - if (!string.IsNullOrWhiteSpace(searchString)) - queryCollection.Add("searchstr", searchString); + if (searchString.IsNotNullOrWhiteSpace()) + { + var searchGroupNames = ((BoolConfigurationItem)configData.GetDynamic("searchgroupnames")).Value; + + queryCollection.Add(searchGroupNames ? "groupname" : "searchstr", searchString.Replace(".", " ")); + } + + var categoryMappings = MapTorznabCapsToTrackers(query) + .Distinct() + .Where(x => !x.IsAllDigits()) + .ToList(); var i = 0; - foreach (var cat in MapTorznabCapsToTrackers(query)) + foreach (var cat in categoryMappings) + { queryCollection.Add($"artistcheck[{i++}]", cat); + } // remove . as not used in titles - searchUrl += "?" + queryCollection.GetQueryString().Replace(".", " "); + searchUrl += "?" + queryCollection.GetQueryString(); var apiKey = ((ConfigurationDataGazelleTracker)configData).ApiKey; - var headers = apiKey != null ? new Dictionary { [AuthorizationName] = String.Format(AuthorizationFormat, apiKey.Value) } : null; + var headers = apiKey != null ? new Dictionary { [AuthorizationName] = string.Format(AuthorizationFormat, apiKey.Value) } : null; var response = await RequestWithCookiesAndRetryAsync(searchUrl, headers: headers); + // we get a redirect in html pages and an error message in json response (api) if (response.IsRedirect && !useApiKey) { @@ -232,10 +249,10 @@ namespace Jackett.Common.Indexers throw new Exception(errorReason); } - try { var json = JObject.Parse(response.ContentString); + foreach (var gObj in JObject.FromObject(json["response"])) { var group = gObj.Value as JObject; @@ -245,65 +262,87 @@ namespace Jackett.Common.Indexers continue; } + var categories = group.Value("Artists") + .SelectMany(a => MapTrackerCatDescToNewznab(a.Value("name"))) + .Distinct() + .ToArray(); + foreach (var tObj in JObject.FromObject(group["Torrents"])) { var torrent = tObj.Value as JObject; - var torrentId = torrent["ID"].ToString(); + var torrentId = torrent.Value("ID"); - var Category = "Windows"; - if (((JArray)group["Artists"]).Count > 0) - Category = group["Artists"][0]["name"].ToString(); - var GroupCategory = MapTrackerCatToNewznab(Category); + if (categories.Length == 0) + { + categories = MapTrackerCatToNewznab(torrent.Value("CategoryID")).ToArray(); + } - var publishDate = DateTime.SpecifyKind( - DateTime.ParseExact(torrent["Time"].ToString(), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), - DateTimeKind.Unspecified).ToLocalTime(); - - var size = ParseUtil.CoerceLong(torrent["Size"].ToString()); var details = new Uri(DetailsUrl + torrentId); var link = new Uri(DownloadUrl + torrentId); - var grabs = ParseUtil.CoerceLong(torrent["Snatched"].ToString()); - var seeders = ParseUtil.CoerceLong(torrent["Seeders"].ToString()); - var leechers = ParseUtil.CoerceLong(torrent["Leechers"].ToString()); - var title = WebUtility.HtmlDecode(torrent["ReleaseTitle"].ToString()); - List tags = new List(); - string[] tagNames = { "Format", "Encoding", "Region", "Language", "Scene", "Miscellaneous", "GameDOXType", "GameDOXVers" }; + var title = WebUtility.HtmlDecode(torrent.Value("ReleaseTitle")); + var groupYear = group.Value("year"); + + if (groupYear > 0 && !title.Contains(groupYear.ToString())) + { + title += $" ({groupYear})"; + } + + if (torrent.Value("RemasterTitle").IsNotNullOrWhiteSpace()) + { + title += $" [{$"{torrent.Value("RemasterTitle")} {torrent.Value("RemasterYear")}".Trim()}]"; + } + + var tags = new List(); + + if (group.Value("Artists").Count > 0) + { + tags.Add(string.Join(", ", group.Value("Artists").Select(a => a.Value("name")))); + } + + var tagNames = new[] { "Format", "Encoding", "Region", "Language", "Scene", "Miscellaneous", "GameDOXType", "GameDOXVers" }; foreach (var tag in tagNames) { string tagValue; if (tag.Equals("Scene")) - tagValue = torrent[tag].ToString().Equals("1") ? "Scene" : ""; + { + tagValue = (torrent.Value(tag)?.Equals("1") ?? false) ? "Scene" : ""; + } else - tagValue = torrent[tag].ToString(); + { + tagValue = torrent.Value(tag); + } if (!string.IsNullOrEmpty(tagValue)) + { tags.Add(tagValue); + } } if (tags.Count > 0) - title += " [" + string.Join(", ", tags) + "]"; + { + title += $" [{string.Join(", ", tags)}]"; + } - var freeTorrent = ParseUtil.CoerceInt(torrent["FreeTorrent"].ToString()); - var files = ParseUtil.CoerceInt(torrent["FileCount"].ToString()); + var freeTorrent = torrent.Value("FreeTorrent"); var release = new ReleaseInfo { - MinimumRatio = 1, - MinimumSeedTime = 288000, //80 hours - Category = GroupCategory, - PublishDate = publishDate, - Size = size, + Guid = link, Details = details, Link = link, - Guid = link, - Grabs = grabs, - Seeders = seeders, - Peers = leechers + seeders, Title = title, - Files = files, + Category = categories, + PublishDate = DateTime.ParseExact(torrent.Value("Time"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal), + Size = ParseUtil.CoerceLong(torrent.Value("Size")), + Grabs = torrent.Value("Snatched"), + Seeders = torrent.Value("Seeders"), + Peers = torrent.Value("Seeders") + torrent.Value("Leechers"), + Files = torrent.Value("FileCount"), UploadVolumeFactor = freeTorrent >= 2 ? 0 : 1, - DownloadVolumeFactor = freeTorrent >= 1 ? 0 : 1 + DownloadVolumeFactor = freeTorrent >= 1 ? 0 : 1, + MinimumRatio = 1, + MinimumSeedTime = 288000, // 80 hours }; releases.Add(release); }