From d6139714af6a6a1940cd76873c396356e8299992 Mon Sep 17 00:00:00 2001 From: ngosang Date: Tue, 6 Oct 2020 20:54:00 +0200 Subject: [PATCH] Revert "redacted: add API Key support to GazelleTracker. resolves #8898 (#9666)" This reverts commit 3e22ff0d6d080fc25701c39bd6989e03091c2b20. --- .../Indexers/Abstract/GazelleTracker.cs | 129 ++++++++++-------- src/Jackett.Common/Indexers/BaseIndexer.cs | 7 +- src/Jackett.Common/Indexers/Redacted.cs | 10 +- .../ConfigurationDataGazelleTracker.cs | 49 ------- .../Models/IndexerConfig/ConfigurationData.cs | 1 - 5 files changed, 78 insertions(+), 118 deletions(-) delete mode 100644 src/Jackett.Common/Models/IndexerConfig/Bespoke/ConfigurationDataGazelleTracker.cs diff --git a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs index eac06866d..f0b245827 100644 --- a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs +++ b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs @@ -9,7 +9,7 @@ using System.Text; using System.Threading.Tasks; using AngleSharp.Html.Parser; using Jackett.Common.Models; -using Jackett.Common.Models.IndexerConfig.Bespoke; +using Jackett.Common.Models.IndexerConfig; using Jackett.Common.Services.Interfaces; using Jackett.Common.Utils; using Jackett.Common.Utils.Clients; @@ -22,24 +22,26 @@ namespace Jackett.Common.Indexers.Abstract [ExcludeFromCodeCoverage] public abstract class GazelleTracker : BaseWebIndexer { - protected virtual string LoginUrl => SiteLink + "login.php"; - protected virtual string APIUrl => SiteLink + "ajax.php"; - protected virtual string DownloadUrl => SiteLink + "torrents.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id="; - protected virtual string DetailsUrl => SiteLink + "torrents.php?torrentid="; - - protected bool useTokens; + protected string LoginUrl => SiteLink + "login.php"; + protected string APIUrl => SiteLink + "ajax.php"; + protected string DownloadUrl => SiteLink + "torrents.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id="; + protected string DetailsUrl => SiteLink + "torrents.php?torrentid="; + protected bool supportsFreeleechTokens; + protected bool imdbInTags; + protected bool supportsCategories = true; // set to false if the tracker doesn't include the categories in the API search results + protected bool useTokens = false; protected string cookie = ""; - private readonly bool imdbInTags; - private readonly bool useApiKey; - - private new ConfigurationDataGazelleTracker configData => (ConfigurationDataGazelleTracker)base.configData; + private new ConfigurationDataBasicLogin configData + { + get => (ConfigurationDataBasicLogin)base.configData; + set => base.configData = value; + } protected GazelleTracker(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, IProtectionService p, TorznabCapabilities caps, bool supportsFreeleechTokens, - bool imdbInTags = false, bool has2Fa = false, bool useApiKey = false, - string instructionMessageOptional = null) + bool imdbInTags = false, bool has2Fa = false) : base(id: id, name: name, description: description, @@ -49,57 +51,55 @@ namespace Jackett.Common.Indexers.Abstract client: client, logger: logger, p: p, - configData: new ConfigurationDataGazelleTracker( - has2Fa, supportsFreeleechTokens, useApiKey, instructionMessageOptional)) + configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; - + this.supportsFreeleechTokens = supportsFreeleechTokens; this.imdbInTags = imdbInTags; - this.useApiKey = useApiKey; + + if (has2Fa) + { + var cookieHint = new ConfigurationData.DisplayItem( + "
  1. (use this only if 2FA is enabled for your account)
  2. Login to this tracker with your browser
  3. Open the DevTools panel by pressing F12
  4. Select the Network tab
  5. Click on the Doc button
  6. Refresh the page by pressing F5
  7. Select the Headers tab
  8. Find 'cookie:' in the Request Headers section
  9. Copy & paste the whole cookie string to here.
") + { + Name = "CookieHint" + }; + configData.AddDynamic("cookieHint", cookieHint); + var cookieItem = new ConfigurationData.StringItem { Value = "" }; + cookieItem.Name = "Cookie"; + configData.AddDynamic("cookie", cookieItem); + } + + if (supportsFreeleechTokens) + { + var useTokenItem = new ConfigurationData.BoolItem { Value = false }; + useTokenItem.Name = "Use Freeleech Tokens when available"; + configData.AddDynamic("usetoken", useTokenItem); + } } public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false) { base.LoadValuesFromJson(jsonConfig, useProtectionService); - var cookieItem = configData.CookieItem; + var cookieItem = (ConfigurationData.StringItem)configData.GetDynamic("cookie"); if (cookieItem != null) + { cookie = cookieItem.Value; + } - var useTokenItem = configData.UseTokenItem; + var useTokenItem = (ConfigurationData.BoolItem)configData.GetDynamic("usetoken"); if (useTokenItem != null) + { useTokens = useTokenItem.Value; + } + } public override async Task ApplyConfiguration(JToken configJson) { LoadValuesFromJson(configJson); - if (useApiKey) - { - var apiKey = configData.ApiKey; - if (apiKey?.Value == null) - throw new Exception("Invalid API Key configured"); - if (apiKey.Value.Length != 41) - throw new Exception($"Invalid API Key configured: expected length: 41, got {apiKey.Value.Length}"); - - try - { - var results = await PerformQuery(new TorznabQuery()); - if (!results.Any()) - throw new Exception("Found 0 results in the tracker"); - - IsConfigured = true; - SaveConfig(); - return IndexerConfigurationStatus.Completed; - } - catch (Exception e) - { - IsConfigured = false; - throw new Exception($"Your API Key did not work: {e.Message}"); - } - } - var pairs = new Dictionary { { "username", configData.Username.Value }, { "password", configData.Password.Value }, @@ -114,7 +114,9 @@ namespace Jackett.Common.Indexers.Abstract { var results = await PerformQuery(new TorznabQuery()); if (!results.Any()) + { throw new Exception("Found 0 results in the tracker"); + } IsConfigured = true; SaveConfig(); @@ -123,7 +125,7 @@ namespace Jackett.Common.Indexers.Abstract catch (Exception e) { IsConfigured = false; - throw new Exception($"Your cookie did not work: {e.Message}"); + throw new Exception("Your cookie did not work: " + e.Message); } } @@ -160,6 +162,7 @@ namespace Jackett.Common.Indexers.Abstract { "order_way", "desc" } }; + if (!string.IsNullOrWhiteSpace(query.ImdbID)) { if (imdbInTags) @@ -168,7 +171,9 @@ namespace Jackett.Common.Indexers.Abstract queryCollection.Add("cataloguenumber", query.ImdbID); } else if (!string.IsNullOrWhiteSpace(searchString)) + { queryCollection.Add("searchstr", searchString); + } if (query.Artist != null) queryCollection.Add("artistname", query.Artist); @@ -182,17 +187,18 @@ namespace Jackett.Common.Indexers.Abstract if (query.Album != null) queryCollection.Add("groupname", query.Album); - foreach (var cat in MapTorznabCapsToTrackers(query)) - queryCollection.Add("filter_cat[" + cat + "]", "1"); + if (supportsCategories) + { + foreach (var cat in MapTorznabCapsToTrackers(query)) + { + queryCollection.Add("filter_cat[" + cat + "]", "1"); + } + } searchUrl += "?" + queryCollection.GetQueryString(); - var apiKey = configData.ApiKey; - var headers = apiKey != null ? new Dictionary { ["Authorization"] = 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 || (response.ContentString != null && response.ContentString.Contains("\"bad credentials\""))) + var response = await RequestWithCookiesAndRetryAsync(searchUrl); + if (response.IsRedirect) { // re-login await ApplyConfiguration(null); @@ -235,11 +241,14 @@ namespace Jackett.Common.Indexers.Abstract if (imdbInTags) + { release.Imdb = tags .Select(tag => ParseUtil.GetImdbID((string)tag)) .Where(tag => tag != null).FirstIfSingleOrDefault(); + } if (r["torrents"] is JArray) + { foreach (JObject torrent in r["torrents"]) { var release2 = (ReleaseInfo)release.Clone(); @@ -247,6 +256,7 @@ namespace Jackett.Common.Indexers.Abstract if (ReleaseInfoPostParse(release2, torrent, r)) releases.Add(release2); } + } else { FillReleaseInfoFromJson(release, r); @@ -272,7 +282,9 @@ namespace Jackett.Common.Indexers.Abstract var time = (string)torrent["time"]; if (!string.IsNullOrEmpty(time)) + { release.PublishDate = DateTime.ParseExact(time + " +0000", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture); + } var flags = new List(); @@ -353,10 +365,14 @@ namespace Jackett.Common.Indexers.Abstract release.DownloadVolumeFactor = 1; release.UploadVolumeFactor = 1; if ((bool)torrent["isFreeleech"]) + { release.DownloadVolumeFactor = 0; + } var isPersonalFreeleech = (bool?)torrent["isPersonalFreeleech"]; if (isPersonalFreeleech != null && isPersonalFreeleech == true) + { release.DownloadVolumeFactor = 0; + } if ((bool)torrent["isNeutralLeech"]) { release.DownloadVolumeFactor = 0; @@ -366,10 +382,7 @@ namespace Jackett.Common.Indexers.Abstract public override async Task Download(Uri link) { - var apiKey = configData.ApiKey; - var headers = apiKey != null ? new Dictionary { ["Authorization"] = apiKey.Value } : null; - - var content = await base.Download(link, RequestType.GET, headers: headers); + var content = await base.Download(link); // Check if we're out of FL tokens/torrent is to large // most gazelle trackers will simply return the torrent anyway but e.g. redacted will return an error @@ -385,7 +398,7 @@ namespace Jackett.Common.Indexers.Abstract { // download again with usetoken=0 var requestLinkNew = requestLink.Replace("usetoken=1", "usetoken=0"); - content = await base.Download(new Uri(requestLinkNew), RequestType.GET, headers: headers); + content = await base.Download(new Uri(requestLinkNew)); } } diff --git a/src/Jackett.Common/Indexers/BaseIndexer.cs b/src/Jackett.Common/Indexers/BaseIndexer.cs index bbeafcdba..f39932254 100644 --- a/src/Jackett.Common/Indexers/BaseIndexer.cs +++ b/src/Jackett.Common/Indexers/BaseIndexer.cs @@ -381,7 +381,7 @@ namespace Jackett.Common.Indexers return await Download(uncleanLink, RequestType.GET); } - protected async Task Download(Uri link, RequestType method, string refererlink = null, Dictionaryheaders = null) + protected async Task Download(Uri link, RequestType method, string refererlink = null) { // return magnet link if (link.Scheme == "magnet") @@ -392,8 +392,11 @@ namespace Jackett.Common.Indexers .Replace("(", "%28") .Replace(")", "%29") .Replace("'", "%27"); - var response = await RequestWithCookiesAndRetryAsync(requestLink, null, method, refererlink, null, headers); + var response = await RequestWithCookiesAndRetryAsync(requestLink, null, method, requestLink); + // if referer link is provied it will be used + if (refererlink != null) + response = await RequestWithCookiesAndRetryAsync(requestLink, null, method, refererlink); if (response.IsRedirect) { await FollowIfRedirect(response); diff --git a/src/Jackett.Common/Indexers/Redacted.cs b/src/Jackett.Common/Indexers/Redacted.cs index 824ba4aa6..b5f0b2ed0 100644 --- a/src/Jackett.Common/Indexers/Redacted.cs +++ b/src/Jackett.Common/Indexers/Redacted.cs @@ -5,16 +5,14 @@ using System.Threading.Tasks; using Jackett.Common.Indexers.Abstract; using Jackett.Common.Models; using Jackett.Common.Services.Interfaces; +using Jackett.Common.Utils.Clients; using NLog; -using WebClient = Jackett.Common.Utils.Clients.WebClient; namespace Jackett.Common.Indexers { [ExcludeFromCodeCoverage] public class Redacted : GazelleTracker { - protected override string DownloadUrl => SiteLink + "ajax.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id="; - public Redacted(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) : base(id: "redacted", name: "Redacted", @@ -29,10 +27,7 @@ namespace Jackett.Common.Indexers logger: l, p: ps, supportsFreeleechTokens: true, - has2Fa: false, - useApiKey: true, - instructionMessageOptional: "
  1. Go to Redacted's site and open your account settings.
  2. Go to Access Settings tab and copy the API Key.
  3. Ensure that you've checked Confirm API Key.
  4. Finally, click Save Profile.
" - ) + has2Fa: true) { Language = "en-us"; Type = "private"; @@ -53,6 +48,5 @@ namespace Jackett.Common.Indexers results = results.Where(release => query.MatchQueryStringAND(release.Title)); return results; } - } } diff --git a/src/Jackett.Common/Models/IndexerConfig/Bespoke/ConfigurationDataGazelleTracker.cs b/src/Jackett.Common/Models/IndexerConfig/Bespoke/ConfigurationDataGazelleTracker.cs deleted file mode 100644 index 99e7b8cba..000000000 --- a/src/Jackett.Common/Models/IndexerConfig/Bespoke/ConfigurationDataGazelleTracker.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace Jackett.Common.Models.IndexerConfig.Bespoke -{ - public class ConfigurationDataGazelleTracker : ConfigurationData - { - public StringItem Username { get; private set; } - public StringItem Password { get; private set; } - public StringItem ApiKey { get; private set; } - public DisplayItem CookieHint { get; private set; } - public StringItem CookieItem { get; private set; } - public BoolItem UseTokenItem { get; private set; } - public DisplayItem Instructions { get; private set; } - - public ConfigurationDataGazelleTracker(bool has2Fa = false, bool supportsFreeleechToken = false, - bool useApiKey = false, string instructionMessageOptional = null) - { - if (useApiKey) - ApiKey = new StringItem { Name = "APIKey" }; - else - { - Username = new StringItem { Name = "Username" }; - Password = new StringItem { Name = "Password" }; - } - - if (has2Fa) - { - CookieHint = new DisplayItem( - @"Use the Cookie field only if 2FA is enabled for your account, let it empty otherwise. -
  1. Login to this tracker with your browser -
  2. Open the DevTools panel by pressing F12 -
  3. Select the Network tab -
  4. Click on the Doc button -
  5. Refresh the page by pressing F5 -
  6. Select the Headers tab -
  7. Find 'cookie:' in the Request Headers section -
  8. Copy & paste the whole cookie string to here.
") - { - Name = "CookieHint" - }; - CookieItem = new StringItem { Name = "Cookie", Value = "" }; - } - - if (supportsFreeleechToken) - UseTokenItem = new BoolItem { Name = "Use Freeleech Tokens when Available", Value = false }; - - Instructions = new DisplayItem(instructionMessageOptional) { Name = "" }; - } - - } -} diff --git a/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs b/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs index d999fe30b..db6583c6c 100644 --- a/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs +++ b/src/Jackett.Common/Models/IndexerConfig/ConfigurationData.cs @@ -169,7 +169,6 @@ namespace Jackett.Common.Models.IndexerConfig .GetProperties() .Where(p => p.CanRead) .Where(p => p.PropertyType.IsSubclassOf(typeof(Item))) - .Where(p => p.GetValue(this) != null) .Select(p => (Item)p.GetValue(this)).ToList(); // remove/insert Site Link manualy to make sure it shows up first