redacted: add freeload only option (#14867)

This commit is contained in:
Bogdan
2023-11-29 07:42:03 +02:00
committed by GitHub
parent 90827ac484
commit 7fae845d1c
3 changed files with 71 additions and 18 deletions

View File

@@ -44,7 +44,7 @@ namespace Jackett.Common.Indexers.Abstract
protected readonly bool usePassKey; protected readonly bool usePassKey;
protected readonly bool useAuthKey; protected readonly bool useAuthKey;
private new ConfigurationDataGazelleTracker configData protected new ConfigurationDataGazelleTracker configData
{ {
get => (ConfigurationDataGazelleTracker)base.configData; get => (ConfigurationDataGazelleTracker)base.configData;
set => base.configData = value; set => base.configData = value;
@@ -52,7 +52,7 @@ namespace Jackett.Common.Indexers.Abstract
protected GazelleTracker(IIndexerConfigurationService configService, WebClient client, Logger logger, protected GazelleTracker(IIndexerConfigurationService configService, WebClient client, Logger logger,
IProtectionService p, ICacheService cs, IProtectionService p, ICacheService cs,
bool supportsFreeleechTokens = false, bool supportsFreeleechOnly = false, bool supportsFreeleechTokens = false, bool supportsFreeleechOnly = false, bool supportsFreeloadOnly = false,
bool imdbInTags = false, bool has2Fa = false, bool useApiKey = false, bool imdbInTags = false, bool has2Fa = false, bool useApiKey = false,
bool usePassKey = false, bool useAuthKey = false, string instructionMessageOptional = null) bool usePassKey = false, bool useAuthKey = false, string instructionMessageOptional = null)
: base(configService: configService, : base(configService: configService,
@@ -60,7 +60,7 @@ namespace Jackett.Common.Indexers.Abstract
logger: logger, logger: logger,
p: p, p: p,
cacheService: cs, cacheService: cs,
configData: new ConfigurationDataGazelleTracker(has2Fa, supportsFreeleechTokens, supportsFreeleechOnly, useApiKey, usePassKey, useAuthKey, instructionMessageOptional)) configData: new ConfigurationDataGazelleTracker(has2Fa, supportsFreeleechTokens, supportsFreeleechOnly, supportsFreeloadOnly, useApiKey, usePassKey, useAuthKey, instructionMessageOptional))
{ {
this.imdbInTags = imdbInTags; this.imdbInTags = imdbInTags;
this.useApiKey = useApiKey; this.useApiKey = useApiKey;
@@ -192,60 +192,64 @@ namespace Jackett.Common.Indexers.Abstract
if (!string.IsNullOrWhiteSpace(query.Genre)) if (!string.IsNullOrWhiteSpace(query.Genre))
{ {
queryCollection.Add("taglist", query.Genre); queryCollection.Set("taglist", query.Genre);
} }
if (!string.IsNullOrWhiteSpace(query.ImdbID)) if (!string.IsNullOrWhiteSpace(query.ImdbID))
{ {
if (imdbInTags) if (imdbInTags)
{ {
queryCollection.Add("taglist", query.ImdbID); queryCollection.Set("taglist", query.ImdbID);
} }
else else
{ {
queryCollection.Add("cataloguenumber", query.ImdbID); queryCollection.Set("cataloguenumber", query.ImdbID);
} }
} }
else if (!string.IsNullOrWhiteSpace(searchString)) else if (!string.IsNullOrWhiteSpace(searchString))
{ {
queryCollection.Add("searchstr", searchString); queryCollection.Set("searchstr", searchString);
} }
if (query.Artist.IsNotNullOrWhiteSpace() && query.Artist != "VA") if (query.Artist.IsNotNullOrWhiteSpace() && query.Artist != "VA")
{ {
queryCollection.Add("artistname", query.Artist); queryCollection.Set("artistname", query.Artist);
} }
if (query.Label.IsNotNullOrWhiteSpace()) if (query.Label.IsNotNullOrWhiteSpace())
{ {
queryCollection.Add("recordlabel", query.Label); queryCollection.Set("recordlabel", query.Label);
} }
if (query.Year.HasValue) if (query.Year.HasValue)
{ {
queryCollection.Add("year", query.Year.ToString()); queryCollection.Set("year", query.Year.ToString());
} }
if (query.Album.IsNotNullOrWhiteSpace()) if (query.Album.IsNotNullOrWhiteSpace())
{ {
queryCollection.Add("groupname", query.Album); queryCollection.Set("groupname", query.Album);
} }
foreach (var cat in MapTorznabCapsToTrackers(query)) foreach (var cat in MapTorznabCapsToTrackers(query))
{ {
queryCollection.Add("filter_cat[" + cat + "]", "1"); queryCollection.Set("filter_cat[" + cat + "]", "1");
} }
if (configData.FreeleechOnly != null && configData.FreeleechOnly.Value) if (configData.FreeleechOnly != null && configData.FreeleechOnly.Value)
{ {
queryCollection.Add("freetorrent", "1"); queryCollection.Set("freetorrent", "1");
}
else if (configData.FreeloadOnly != null && configData.FreeloadOnly.Value)
{
queryCollection.Set("freetorrent", "4");
} }
// remove . as not used in titles // remove . as not used in titles
searchUrl += "?" + queryCollection.GetQueryString().Replace(".", " "); searchUrl += "?" + queryCollection.GetQueryString().Replace(".", " ");
var apiKey = configData.ApiKey; var apiKey = configData.ApiKey;
var headers = apiKey != null ? new Dictionary<string, string> { [AuthorizationName] = String.Format(AuthorizationFormat, apiKey.Value) } : null; var headers = apiKey != null ? new Dictionary<string, string> { [AuthorizationName] = string.Format(AuthorizationFormat, apiKey.Value) } : null;
var response = await RequestWithCookiesAndRetryAsync(searchUrl, headers: headers); var response = await RequestWithCookiesAndRetryAsync(searchUrl, headers: headers);
// we get a redirect in html pages and an error message in json response (api) // we get a redirect in html pages and an error message in json response (api)
@@ -344,6 +348,11 @@ namespace Jackett.Common.Indexers.Abstract
{ {
foreach (JObject torrent in r["torrents"]) foreach (JObject torrent in r["torrents"])
{ {
if (ShouldSkipRelease(torrent))
{
continue;
}
var release2 = (ReleaseInfo)release.Clone(); var release2 = (ReleaseInfo)release.Clone();
FillReleaseInfoFromJson(release2, torrent); FillReleaseInfoFromJson(release2, torrent);
if (ReleaseInfoPostParse(release2, torrent, r)) if (ReleaseInfoPostParse(release2, torrent, r))
@@ -354,6 +363,11 @@ namespace Jackett.Common.Indexers.Abstract
} }
else else
{ {
if (ShouldSkipRelease(r))
{
continue;
}
FillReleaseInfoFromJson(release, r); FillReleaseInfoFromJson(release, r);
if (ReleaseInfoPostParse(release, r, r)) if (ReleaseInfoPostParse(release, r, r))
{ {
@@ -373,6 +387,14 @@ namespace Jackett.Common.Indexers.Abstract
// hook to add/modify the parsed information, return false to exclude the torrent from the results // hook to add/modify the parsed information, return false to exclude the torrent from the results
protected virtual bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result) => true; protected virtual bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result) => true;
protected virtual bool ShouldSkipRelease(JObject torrent)
{
var isFreeleech = bool.TryParse((string)torrent["isFreeleech"], out var freeleech) && freeleech;
// skip non-freeload results when freeload only is set
return configData.FreeleechOnly != null && configData.FreeleechOnly.Value && !isFreeleech;
}
protected void FillReleaseInfoFromJson(ReleaseInfo release, JObject torrent) protected void FillReleaseInfoFromJson(ReleaseInfo release, JObject torrent)
{ {
var torrentId = torrent["torrentId"]; var torrentId = torrent["torrentId"];
@@ -499,8 +521,9 @@ namespace Jackett.Common.Indexers.Abstract
release.DownloadVolumeFactor = 0; release.DownloadVolumeFactor = 0;
} }
var isFreeload = (bool?)torrent["isFreeload"]; var isFreeload = bool.TryParse((string)torrent["isFreeload"], out var freeload) && freeload;
if ((bool)torrent["isNeutralLeech"] || (isFreeload != null && isFreeload == true))
if ((bool)torrent["isNeutralLeech"] || isFreeload)
{ {
release.DownloadVolumeFactor = 0; release.DownloadVolumeFactor = 0;
release.UploadVolumeFactor = 0; release.UploadVolumeFactor = 0;

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Jackett.Common.Indexers.Abstract; using Jackett.Common.Indexers.Abstract;
using Jackett.Common.Models; using Jackett.Common.Models;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Newtonsoft.Json.Linq;
using NLog; using NLog;
using WebClient = Jackett.Common.Utils.Clients.WebClient; using WebClient = Jackett.Common.Utils.Clients.WebClient;
@@ -31,6 +32,7 @@ namespace Jackett.Common.Indexers
p: ps, p: ps,
cs: cs, cs: cs,
supportsFreeleechTokens: true, supportsFreeleechTokens: true,
supportsFreeloadOnly: true,
has2Fa: false, has2Fa: false,
useApiKey: true, useApiKey: true,
instructionMessageOptional: "<ol><li>Go to Redacted's site and open your account settings.</li><li>Go to <b>Access Settings</b> tab and copy the API Key.</li><li>Ensure that you've checked <b>Confirm API Key</b>.</li><li>Finally, click <b>Save Profile</b>.</li></ol>" instructionMessageOptional: "<ol><li>Go to Redacted's site and open your account settings.</li><li>Go to <b>Access Settings</b> tab and copy the API Key.</li><li>Ensure that you've checked <b>Confirm API Key</b>.</li><li>Finally, click <b>Save Profile</b>.</li></ol>"
@@ -82,5 +84,17 @@ namespace Jackett.Common.Indexers
return releases; return releases;
} }
protected override bool ShouldSkipRelease(JObject torrent)
{
var isFreeload = bool.TryParse((string)torrent["isFreeload"], out var freeload) && freeload;
if (configData.FreeloadOnly != null && configData.FreeloadOnly.Value && !isFreeload)
{
return true;
}
return base.ShouldSkipRelease(torrent);
}
} }
} }

View File

@@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis;
namespace Jackett.Common.Models.IndexerConfig.Bespoke namespace Jackett.Common.Models.IndexerConfig.Bespoke
{ {
[ExcludeFromCodeCoverage] [ExcludeFromCodeCoverage]
internal class ConfigurationDataGazelleTracker : ConfigurationData public class ConfigurationDataGazelleTracker : ConfigurationData
{ {
public StringConfigurationItem Username { get; private set; } public StringConfigurationItem Username { get; private set; }
public PasswordConfigurationItem Password { get; private set; } public PasswordConfigurationItem Password { get; private set; }
@@ -14,14 +14,17 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
public StringConfigurationItem CookieItem { get; private set; } public StringConfigurationItem CookieItem { get; private set; }
public BoolConfigurationItem UseTokenItem { get; private set; } public BoolConfigurationItem UseTokenItem { get; private set; }
public BoolConfigurationItem FreeleechOnly { get; private set; } public BoolConfigurationItem FreeleechOnly { get; private set; }
public BoolConfigurationItem FreeloadOnly { get; private set; }
public DisplayInfoConfigurationItem Instructions { get; private set; } public DisplayInfoConfigurationItem Instructions { get; private set; }
public ConfigurationDataGazelleTracker(bool has2Fa = false, bool supportsFreeleechToken = false, bool supportsFreeleechOnly = false, public ConfigurationDataGazelleTracker(bool has2Fa = false, bool supportsFreeleechToken = false, bool supportsFreeleechOnly = false, bool supportsFreeloadOnly = false,
bool useApiKey = false, bool usePassKey = false, bool useAuthKey = false, bool useApiKey = false, bool usePassKey = false, bool useAuthKey = false,
string instructionMessageOptional = null) string instructionMessageOptional = null)
{ {
if (useApiKey) if (useApiKey)
{
ApiKey = new StringConfigurationItem("APIKey"); ApiKey = new StringConfigurationItem("APIKey");
}
else else
{ {
Username = new StringConfigurationItem("Username"); Username = new StringConfigurationItem("Username");
@@ -44,16 +47,29 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
} }
if (usePassKey) if (usePassKey)
{
PassKey = new StringConfigurationItem("Passkey"); PassKey = new StringConfigurationItem("Passkey");
}
if (useAuthKey) if (useAuthKey)
{
AuthKey = new StringConfigurationItem("Authkey"); AuthKey = new StringConfigurationItem("Authkey");
}
if (supportsFreeleechToken) if (supportsFreeleechToken)
{
UseTokenItem = new BoolConfigurationItem("Use Freeleech Tokens when Available") { Value = false }; UseTokenItem = new BoolConfigurationItem("Use Freeleech Tokens when Available") { Value = false };
}
if (supportsFreeleechOnly) if (supportsFreeleechOnly)
{
FreeleechOnly = new BoolConfigurationItem("Search freeleech only") { Value = false }; FreeleechOnly = new BoolConfigurationItem("Search freeleech only") { Value = false };
}
if (supportsFreeloadOnly)
{
FreeloadOnly = new BoolConfigurationItem("Search freeload only") { Value = false };
}
Instructions = new DisplayInfoConfigurationItem("", instructionMessageOptional); Instructions = new DisplayInfoConfigurationItem("", instructionMessageOptional);
} }