mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
This reverts commit 3e22ff0d6d
.
This commit is contained in:
@@ -9,7 +9,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AngleSharp.Html.Parser;
|
using AngleSharp.Html.Parser;
|
||||||
using Jackett.Common.Models;
|
using Jackett.Common.Models;
|
||||||
using Jackett.Common.Models.IndexerConfig.Bespoke;
|
using Jackett.Common.Models.IndexerConfig;
|
||||||
using Jackett.Common.Services.Interfaces;
|
using Jackett.Common.Services.Interfaces;
|
||||||
using Jackett.Common.Utils;
|
using Jackett.Common.Utils;
|
||||||
using Jackett.Common.Utils.Clients;
|
using Jackett.Common.Utils.Clients;
|
||||||
@@ -22,24 +22,26 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public abstract class GazelleTracker : BaseWebIndexer
|
public abstract class GazelleTracker : BaseWebIndexer
|
||||||
{
|
{
|
||||||
protected virtual string LoginUrl => SiteLink + "login.php";
|
protected string LoginUrl => SiteLink + "login.php";
|
||||||
protected virtual string APIUrl => SiteLink + "ajax.php";
|
protected string APIUrl => SiteLink + "ajax.php";
|
||||||
protected virtual string DownloadUrl => SiteLink + "torrents.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id=";
|
protected string DownloadUrl => SiteLink + "torrents.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id=";
|
||||||
protected virtual string DetailsUrl => SiteLink + "torrents.php?torrentid=";
|
protected string DetailsUrl => SiteLink + "torrents.php?torrentid=";
|
||||||
|
protected bool supportsFreeleechTokens;
|
||||||
protected bool useTokens;
|
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 = "";
|
protected string cookie = "";
|
||||||
|
|
||||||
private readonly bool imdbInTags;
|
private new ConfigurationDataBasicLogin configData
|
||||||
private readonly bool useApiKey;
|
{
|
||||||
|
get => (ConfigurationDataBasicLogin)base.configData;
|
||||||
private new ConfigurationDataGazelleTracker configData => (ConfigurationDataGazelleTracker)base.configData;
|
set => base.configData = value;
|
||||||
|
}
|
||||||
|
|
||||||
protected GazelleTracker(string link, string id, string name, string description,
|
protected GazelleTracker(string link, string id, string name, string description,
|
||||||
IIndexerConfigurationService configService, WebClient client, Logger logger,
|
IIndexerConfigurationService configService, WebClient client, Logger logger,
|
||||||
IProtectionService p, TorznabCapabilities caps, bool supportsFreeleechTokens,
|
IProtectionService p, TorznabCapabilities caps, bool supportsFreeleechTokens,
|
||||||
bool imdbInTags = false, bool has2Fa = false, bool useApiKey = false,
|
bool imdbInTags = false, bool has2Fa = false)
|
||||||
string instructionMessageOptional = null)
|
|
||||||
: base(id: id,
|
: base(id: id,
|
||||||
name: name,
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
@@ -49,57 +51,55 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
client: client,
|
client: client,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
p: p,
|
p: p,
|
||||||
configData: new ConfigurationDataGazelleTracker(
|
configData: new ConfigurationDataBasicLogin())
|
||||||
has2Fa, supportsFreeleechTokens, useApiKey, instructionMessageOptional))
|
|
||||||
{
|
{
|
||||||
Encoding = Encoding.UTF8;
|
Encoding = Encoding.UTF8;
|
||||||
|
this.supportsFreeleechTokens = supportsFreeleechTokens;
|
||||||
this.imdbInTags = imdbInTags;
|
this.imdbInTags = imdbInTags;
|
||||||
this.useApiKey = useApiKey;
|
|
||||||
|
if (has2Fa)
|
||||||
|
{
|
||||||
|
var cookieHint = new ConfigurationData.DisplayItem(
|
||||||
|
"<ol><li>(use this only if 2FA is enabled for your account)</li><li>Login to this tracker with your browser<li>Open the <b>DevTools</b> panel by pressing <b>F12</b><li>Select the <b>Network</b> tab<li>Click on the <b>Doc</b> button<li>Refresh the page by pressing <b>F5</b><li>Select the <b>Headers</b> tab<li>Find 'cookie:' in the <b>Request Headers</b> section<li>Copy & paste the whole cookie string to here.</ol>")
|
||||||
|
{
|
||||||
|
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)
|
public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
|
||||||
{
|
{
|
||||||
base.LoadValuesFromJson(jsonConfig, useProtectionService);
|
base.LoadValuesFromJson(jsonConfig, useProtectionService);
|
||||||
|
|
||||||
var cookieItem = configData.CookieItem;
|
var cookieItem = (ConfigurationData.StringItem)configData.GetDynamic("cookie");
|
||||||
if (cookieItem != null)
|
if (cookieItem != null)
|
||||||
|
{
|
||||||
cookie = cookieItem.Value;
|
cookie = cookieItem.Value;
|
||||||
|
}
|
||||||
|
|
||||||
var useTokenItem = configData.UseTokenItem;
|
var useTokenItem = (ConfigurationData.BoolItem)configData.GetDynamic("usetoken");
|
||||||
if (useTokenItem != null)
|
if (useTokenItem != null)
|
||||||
|
{
|
||||||
useTokens = useTokenItem.Value;
|
useTokens = useTokenItem.Value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||||
{
|
{
|
||||||
LoadValuesFromJson(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<string, string> {
|
var pairs = new Dictionary<string, string> {
|
||||||
{ "username", configData.Username.Value },
|
{ "username", configData.Username.Value },
|
||||||
{ "password", configData.Password.Value },
|
{ "password", configData.Password.Value },
|
||||||
@@ -114,7 +114,9 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
{
|
{
|
||||||
var results = await PerformQuery(new TorznabQuery());
|
var results = await PerformQuery(new TorznabQuery());
|
||||||
if (!results.Any())
|
if (!results.Any())
|
||||||
|
{
|
||||||
throw new Exception("Found 0 results in the tracker");
|
throw new Exception("Found 0 results in the tracker");
|
||||||
|
}
|
||||||
|
|
||||||
IsConfigured = true;
|
IsConfigured = true;
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
@@ -123,7 +125,7 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
IsConfigured = false;
|
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" }
|
{ "order_way", "desc" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.ImdbID))
|
if (!string.IsNullOrWhiteSpace(query.ImdbID))
|
||||||
{
|
{
|
||||||
if (imdbInTags)
|
if (imdbInTags)
|
||||||
@@ -168,7 +171,9 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
queryCollection.Add("cataloguenumber", query.ImdbID);
|
queryCollection.Add("cataloguenumber", query.ImdbID);
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(searchString))
|
else if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
|
{
|
||||||
queryCollection.Add("searchstr", searchString);
|
queryCollection.Add("searchstr", searchString);
|
||||||
|
}
|
||||||
|
|
||||||
if (query.Artist != null)
|
if (query.Artist != null)
|
||||||
queryCollection.Add("artistname", query.Artist);
|
queryCollection.Add("artistname", query.Artist);
|
||||||
@@ -182,17 +187,18 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
if (query.Album != null)
|
if (query.Album != null)
|
||||||
queryCollection.Add("groupname", query.Album);
|
queryCollection.Add("groupname", query.Album);
|
||||||
|
|
||||||
foreach (var cat in MapTorznabCapsToTrackers(query))
|
if (supportsCategories)
|
||||||
queryCollection.Add("filter_cat[" + cat + "]", "1");
|
{
|
||||||
|
foreach (var cat in MapTorznabCapsToTrackers(query))
|
||||||
|
{
|
||||||
|
queryCollection.Add("filter_cat[" + cat + "]", "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
searchUrl += "?" + queryCollection.GetQueryString();
|
searchUrl += "?" + queryCollection.GetQueryString();
|
||||||
|
|
||||||
var apiKey = configData.ApiKey;
|
var response = await RequestWithCookiesAndRetryAsync(searchUrl);
|
||||||
var headers = apiKey != null ? new Dictionary<string, string> { ["Authorization"] = apiKey.Value } : null;
|
if (response.IsRedirect)
|
||||||
|
|
||||||
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\"")))
|
|
||||||
{
|
{
|
||||||
// re-login
|
// re-login
|
||||||
await ApplyConfiguration(null);
|
await ApplyConfiguration(null);
|
||||||
@@ -235,11 +241,14 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
|
|
||||||
|
|
||||||
if (imdbInTags)
|
if (imdbInTags)
|
||||||
|
{
|
||||||
release.Imdb = tags
|
release.Imdb = tags
|
||||||
.Select(tag => ParseUtil.GetImdbID((string)tag))
|
.Select(tag => ParseUtil.GetImdbID((string)tag))
|
||||||
.Where(tag => tag != null).FirstIfSingleOrDefault();
|
.Where(tag => tag != null).FirstIfSingleOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
if (r["torrents"] is JArray)
|
if (r["torrents"] is JArray)
|
||||||
|
{
|
||||||
foreach (JObject torrent in r["torrents"])
|
foreach (JObject torrent in r["torrents"])
|
||||||
{
|
{
|
||||||
var release2 = (ReleaseInfo)release.Clone();
|
var release2 = (ReleaseInfo)release.Clone();
|
||||||
@@ -247,6 +256,7 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
if (ReleaseInfoPostParse(release2, torrent, r))
|
if (ReleaseInfoPostParse(release2, torrent, r))
|
||||||
releases.Add(release2);
|
releases.Add(release2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FillReleaseInfoFromJson(release, r);
|
FillReleaseInfoFromJson(release, r);
|
||||||
@@ -272,7 +282,9 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
|
|
||||||
var time = (string)torrent["time"];
|
var time = (string)torrent["time"];
|
||||||
if (!string.IsNullOrEmpty(time))
|
if (!string.IsNullOrEmpty(time))
|
||||||
|
{
|
||||||
release.PublishDate = DateTime.ParseExact(time + " +0000", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
|
release.PublishDate = DateTime.ParseExact(time + " +0000", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
var flags = new List<string>();
|
var flags = new List<string>();
|
||||||
|
|
||||||
@@ -353,10 +365,14 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
release.DownloadVolumeFactor = 1;
|
release.DownloadVolumeFactor = 1;
|
||||||
release.UploadVolumeFactor = 1;
|
release.UploadVolumeFactor = 1;
|
||||||
if ((bool)torrent["isFreeleech"])
|
if ((bool)torrent["isFreeleech"])
|
||||||
|
{
|
||||||
release.DownloadVolumeFactor = 0;
|
release.DownloadVolumeFactor = 0;
|
||||||
|
}
|
||||||
var isPersonalFreeleech = (bool?)torrent["isPersonalFreeleech"];
|
var isPersonalFreeleech = (bool?)torrent["isPersonalFreeleech"];
|
||||||
if (isPersonalFreeleech != null && isPersonalFreeleech == true)
|
if (isPersonalFreeleech != null && isPersonalFreeleech == true)
|
||||||
|
{
|
||||||
release.DownloadVolumeFactor = 0;
|
release.DownloadVolumeFactor = 0;
|
||||||
|
}
|
||||||
if ((bool)torrent["isNeutralLeech"])
|
if ((bool)torrent["isNeutralLeech"])
|
||||||
{
|
{
|
||||||
release.DownloadVolumeFactor = 0;
|
release.DownloadVolumeFactor = 0;
|
||||||
@@ -366,10 +382,7 @@ namespace Jackett.Common.Indexers.Abstract
|
|||||||
|
|
||||||
public override async Task<byte[]> Download(Uri link)
|
public override async Task<byte[]> Download(Uri link)
|
||||||
{
|
{
|
||||||
var apiKey = configData.ApiKey;
|
var content = await base.Download(link);
|
||||||
var headers = apiKey != null ? new Dictionary<string, string> { ["Authorization"] = apiKey.Value } : null;
|
|
||||||
|
|
||||||
var content = await base.Download(link, RequestType.GET, headers: headers);
|
|
||||||
|
|
||||||
// Check if we're out of FL tokens/torrent is to large
|
// 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
|
// 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
|
// download again with usetoken=0
|
||||||
var requestLinkNew = requestLink.Replace("usetoken=1", "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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -381,7 +381,7 @@ namespace Jackett.Common.Indexers
|
|||||||
return await Download(uncleanLink, RequestType.GET);
|
return await Download(uncleanLink, RequestType.GET);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task<byte[]> Download(Uri link, RequestType method, string refererlink = null, Dictionary<string, string>headers = null)
|
protected async Task<byte[]> Download(Uri link, RequestType method, string refererlink = null)
|
||||||
{
|
{
|
||||||
// return magnet link
|
// return magnet link
|
||||||
if (link.Scheme == "magnet")
|
if (link.Scheme == "magnet")
|
||||||
@@ -392,8 +392,11 @@ namespace Jackett.Common.Indexers
|
|||||||
.Replace("(", "%28")
|
.Replace("(", "%28")
|
||||||
.Replace(")", "%29")
|
.Replace(")", "%29")
|
||||||
.Replace("'", "%27");
|
.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)
|
if (response.IsRedirect)
|
||||||
{
|
{
|
||||||
await FollowIfRedirect(response);
|
await FollowIfRedirect(response);
|
||||||
|
@@ -5,16 +5,14 @@ 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 Jackett.Common.Utils.Clients;
|
||||||
using NLog;
|
using NLog;
|
||||||
using WebClient = Jackett.Common.Utils.Clients.WebClient;
|
|
||||||
|
|
||||||
namespace Jackett.Common.Indexers
|
namespace Jackett.Common.Indexers
|
||||||
{
|
{
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public class Redacted : GazelleTracker
|
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)
|
public Redacted(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||||
: base(id: "redacted",
|
: base(id: "redacted",
|
||||||
name: "Redacted",
|
name: "Redacted",
|
||||||
@@ -29,10 +27,7 @@ namespace Jackett.Common.Indexers
|
|||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
supportsFreeleechTokens: true,
|
supportsFreeleechTokens: true,
|
||||||
has2Fa: false,
|
has2Fa: 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>"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Language = "en-us";
|
Language = "en-us";
|
||||||
Type = "private";
|
Type = "private";
|
||||||
@@ -53,6 +48,5 @@ namespace Jackett.Common.Indexers
|
|||||||
results = results.Where(release => query.MatchQueryStringAND(release.Title));
|
results = results.Where(release => query.MatchQueryStringAND(release.Title));
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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.
|
|
||||||
<ol><li>Login to this tracker with your browser
|
|
||||||
<li>Open the <b>DevTools</b> panel by pressing <b>F12</b>
|
|
||||||
<li>Select the <b>Network</b> tab
|
|
||||||
<li>Click on the <b>Doc</b> button
|
|
||||||
<li>Refresh the page by pressing <b>F5</b>
|
|
||||||
<li>Select the <b>Headers</b> tab
|
|
||||||
<li>Find 'cookie:' in the <b>Request Headers</b> section
|
|
||||||
<li>Copy & paste the whole cookie string to here.</ol>")
|
|
||||||
{
|
|
||||||
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 = "" };
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -169,7 +169,6 @@ namespace Jackett.Common.Models.IndexerConfig
|
|||||||
.GetProperties()
|
.GetProperties()
|
||||||
.Where(p => p.CanRead)
|
.Where(p => p.CanRead)
|
||||||
.Where(p => p.PropertyType.IsSubclassOf(typeof(Item)))
|
.Where(p => p.PropertyType.IsSubclassOf(typeof(Item)))
|
||||||
.Where(p => p.GetValue(this) != null)
|
|
||||||
.Select(p => (Item)p.GetValue(this)).ToList();
|
.Select(p => (Item)p.GetValue(this)).ToList();
|
||||||
|
|
||||||
// remove/insert Site Link manualy to make sure it shows up first
|
// remove/insert Site Link manualy to make sure it shows up first
|
||||||
|
Reference in New Issue
Block a user