ci/cd: fix whitespaces (#11749)

This commit is contained in:
Diego Heras 2021-05-16 20:13:54 +02:00 committed by GitHub
parent 519d1ea929
commit aca4a16bae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 333 additions and 294 deletions

View File

@ -300,23 +300,9 @@ stages:
workingDirectory: $(Build.SourcesDirectory) workingDirectory: $(Build.SourcesDirectory)
targetType: inline targetType: inline
failOnStderr: true failOnStderr: true
script: | # execute this command to format all files:
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/DateTimeRoutines # dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Common script: dotnet-format --check --verbosity diagnostic --folder ./src
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.IntegrationTests
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Server
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Service
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Test
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Tray
dotnet-format --fix-whitespace --verbosity diagnostic --folder ./src/Jackett.Updater
dotnet-format --check --verbosity diagnostic --folder ./src/DateTimeRoutines
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Common
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.IntegrationTests
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Server
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Service
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Test
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Tray
dotnet-format --check --verbosity diagnostic --folder ./src/Jackett.Updater
- job: Linting_YAML - job: Linting_YAML
displayName: Linting YAML displayName: Linting YAML

View File

@ -25,7 +25,7 @@ namespace Jackett.Common.Converters
return long.TryParse((string)reader.Value, out var foo) return long.TryParse((string)reader.Value, out var foo)
? foo ? foo
: (long?) null; : (long?)null;
} }
public override bool CanConvert(Type objectType) => objectType == typeof(string); public override bool CanConvert(Type objectType) => objectType == typeof(string);

View File

@ -45,7 +45,8 @@ namespace Jackett.Common.Indexers
name: "Abnormal", name: "Abnormal",
description: "General French Private Tracker", description: "General French Private Tracker",
link: "https://abnormal.ws/", link: "https://abnormal.ws/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep

View File

@ -77,7 +77,7 @@ namespace Jackett.Common.Indexers.Abstract
{ {
var cats = new List<int>(); var cats = new List<int>();
var resolution = row.Value<string>("video_quality"); var resolution = row.Value<string>("video_quality");
switch(row.Value<string>("type")) switch (row.Value<string>("type"))
{ {
case "Movie": case "Movie":
cats.Add(resolution switch cats.Add(resolution switch

View File

@ -145,7 +145,7 @@ namespace Jackett.Common.Indexers.Abstract
Link = link, Link = link,
Details = details, Details = details,
Guid = details, Guid = details,
Category = MapTrackerCatToNewznab(cat), Category = MapTrackerCatToNewznab(cat),
PublishDate = publishDate, PublishDate = publishDate,
Description = description, Description = description,
Poster = poster, Poster = poster,

View File

@ -5,8 +5,8 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Jackett.Common.Models; using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig.Bespoke; using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
@ -80,7 +80,8 @@ namespace Jackett.Common.Indexers
throw new WebException($"AniLibria search returned unexpected result. Expected 200 OK but got {response.Status}.", WebExceptionStatus.ProtocolError); throw new WebException($"AniLibria search returned unexpected result. Expected 200 OK but got {response.Status}.", WebExceptionStatus.ProtocolError);
var results = ParseApiResults(response.ContentString); var results = ParseApiResults(response.ContentString);
return results.Where(release => query.MatchQueryStringAND(release.Title, null, title));; return results.Where(release => query.MatchQueryStringAND(release.Title, null, title));
;
} }
private async Task<IEnumerable<ReleaseInfo>> FetchNewReleases() private async Task<IEnumerable<ReleaseInfo>> FetchNewReleases()
@ -97,7 +98,8 @@ namespace Jackett.Common.Indexers
return ParseApiResults(response.ContentString); return ParseApiResults(response.ContentString);
} }
private string composeTitle(dynamic json) { private string composeTitle(dynamic json)
{
var title = json.names.ru; var title = json.names.ru;
title += " / " + json.names.en; title += " / " + json.names.en;
if (json.alternative is string) if (json.alternative is string)
@ -109,7 +111,8 @@ namespace Jackett.Common.Indexers
private List<ReleaseInfo> ParseApiResults(string json) private List<ReleaseInfo> ParseApiResults(string json)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
foreach (dynamic r in JArray.Parse(json)) { foreach (dynamic r in JArray.Parse(json))
{
var baseRelease = new ReleaseInfo var baseRelease = new ReleaseInfo
{ {
Title = composeTitle(r), Title = composeTitle(r),
@ -117,12 +120,13 @@ namespace Jackett.Common.Indexers
Details = new Uri(SiteLink + "/release/" + r.code + ".html"), Details = new Uri(SiteLink + "/release/" + r.code + ".html"),
DownloadVolumeFactor = 0, DownloadVolumeFactor = 0,
UploadVolumeFactor = 1, UploadVolumeFactor = 1,
Category = new [] Category = new[]
{ {
TorznabCatType.TVAnime.ID TorznabCatType.TVAnime.ID
} }
}; };
foreach (var t in r.torrents.list) { foreach (var t in r.torrents.list)
{
var release = (ReleaseInfo)baseRelease.Clone(); var release = (ReleaseInfo)baseRelease.Clone();
release.Title += " [" + t.quality["string"] + "] - " + t.series["string"]; release.Title += " [" + t.quality["string"] + "] - " + t.series["string"];
release.Size = t.total_size; release.Size = t.total_size;

View File

@ -40,7 +40,8 @@ namespace Jackett.Common.Indexers
link: "https://animebytes.tv/", link: "https://animebytes.tv/",
configService: configService, configService: configService,
client: client, client: client,
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
@ -214,7 +215,8 @@ namespace Jackett.Common.Indexers
synonyms.Add(allSyonyms[1]); synonyms.Add(allSyonyms[1]);
if (AddAlternativeTitles && allSyonyms.Count >= 3) if (AddAlternativeTitles && allSyonyms.Count >= 3)
synonyms.AddRange(allSyonyms[2].Split(',').Select(t => t.Trim())); synonyms.AddRange(allSyonyms[2].Split(',').Select(t => t.Trim()));
} else }
else
{ {
var allSynonyms = group["Synonymns"].ToObject<Dictionary<int, string>>(); var allSynonyms = group["Synonymns"].ToObject<Dictionary<int, string>>();
@ -222,7 +224,8 @@ namespace Jackett.Common.Indexers
synonyms.Add(allSynonyms[0]); synonyms.Add(allSynonyms[0]);
if (AddRomajiTitle && allSynonyms.ContainsKey(1)) if (AddRomajiTitle && allSynonyms.ContainsKey(1))
synonyms.Add(allSynonyms[1]); synonyms.Add(allSynonyms[1]);
if (AddAlternativeTitles && allSynonyms.ContainsKey(2)) { if (AddAlternativeTitles && allSynonyms.ContainsKey(2))
{
synonyms.AddRange(allSynonyms[2].Split(',').Select(t => t.Trim())); synonyms.AddRange(allSynonyms[2].Split(',').Select(t => t.Trim()));
} }
} }

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
@ -38,7 +38,8 @@ namespace Jackett.Common.Indexers
name: "AnimeTorrents", name: "AnimeTorrents",
description: "Definitive source for anime and manga", description: "Definitive source for anime and manga",
link: "https://animetorrents.me/", link: "https://animetorrents.me/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep

View File

@ -2,9 +2,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Dom; using AngleSharp.Dom;
using AngleSharp.Html.Dom; using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser; using AngleSharp.Html.Parser;
@ -15,7 +16,6 @@ using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients; using Jackett.Common.Utils.Clients;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using System.Linq;
namespace Jackett.Common.Indexers namespace Jackett.Common.Indexers
{ {
@ -72,11 +72,15 @@ namespace Jackett.Common.Indexers
} }
// If the search string is empty use the latest releases // If the search string is empty use the latest releases
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
WebResult result; WebResult result;
if (query.IsTest || string.IsNullOrWhiteSpace(query.SearchTerm)) { if (query.IsTest || string.IsNullOrWhiteSpace(query.SearchTerm))
{
result = await RequestWithCookiesAndRetryAsync(SiteLink); result = await RequestWithCookiesAndRetryAsync(SiteLink);
} else { }
else
{
// Prepare the search query // Prepare the search query
var queryParameters = new NameValueCollection var queryParameters = new NameValueCollection
{ {
@ -134,7 +138,7 @@ namespace Jackett.Common.Indexers
Details = uri, Details = uri,
DownloadVolumeFactor = 0, DownloadVolumeFactor = 0,
UploadVolumeFactor = 1, UploadVolumeFactor = 1,
Category = new[]{ TorznabCatType.TVAnime.ID } Category = new[] { TorznabCatType.TVAnime.ID }
}; };
foreach (var t in document.QuerySelectorAll("ul.media__tabs__nav > li > a")) foreach (var t in document.QuerySelectorAll("ul.media__tabs__nav > li > a"))
{ {
@ -161,22 +165,26 @@ namespace Jackett.Common.Indexers
return releases; return releases;
} }
private string composeBaseTitle(IHtmlDocument r) { private string composeBaseTitle(IHtmlDocument r)
{
var name_ru = r.QuerySelector("div.media__post__header > h1").Text().Trim(); var name_ru = r.QuerySelector("div.media__post__header > h1").Text().Trim();
var name_en = r.QuerySelector("div.media__panel > div:nth-of-type(1) > div.col-l:nth-of-type(1) > div > span").Text().Trim(); var name_en = r.QuerySelector("div.media__panel > div:nth-of-type(1) > div.col-l:nth-of-type(1) > div > span").Text().Trim();
var name_orig = r.QuerySelector("div.media__panel > div:nth-of-type(1) > div.col-l:nth-of-type(2) > div > span").Text().Trim(); var name_orig = r.QuerySelector("div.media__panel > div:nth-of-type(1) > div.col-l:nth-of-type(2) > div > span").Text().Trim();
var title = name_ru + " / " + name_en; var title = name_ru + " / " + name_en;
if (name_en != name_orig) { if (name_en != name_orig)
{
title += " / " + name_orig; title += " / " + name_orig;
} }
return title; return title;
} }
private string composeTitleAdditionalInfo(IElement t, IElement tr) { private string composeTitleAdditionalInfo(IElement t, IElement tr)
{
var tabName = t.Text(); var tabName = t.Text();
tabName = tabName.Replace("Сезон", "Season"); tabName = tabName.Replace("Сезон", "Season");
if (tabName.Contains("Серии")) { if (tabName.Contains("Серии"))
{
tabName = ""; tabName = "";
} }

View File

@ -36,7 +36,8 @@ namespace Jackett.Common.Indexers
name: "Anthelion", // old name: TehConnection.me name: "Anthelion", // old name: TehConnection.me
description: "A movies tracker", description: "A movies tracker",
link: "https://anthelion.me/", link: "https://anthelion.me/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep

View File

@ -62,7 +62,7 @@ namespace Jackett.Common.Indexers
public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps,
ICacheService cs) ICacheService cs)
: base(id: "bjshare", : base(id: "bjshare",
name: "BJ-Share", name: "BJ-Share",
description: "A brazilian tracker.", description: "A brazilian tracker.",
link: "https://bj-share.info/", link: "https://bj-share.info/",
@ -160,7 +160,7 @@ namespace Jackett.Common.Indexers
var cleanTitle = _EpisodeRegex.Replace(title, string.Empty); var cleanTitle = _EpisodeRegex.Replace(title, string.Empty);
// Removes the year if it comes on the title // Removes the year if it comes on the title
// The space is added because on daily releases the date will be XX/XX/YYYY // The space is added because on daily releases the date will be XX/XX/YYYY
if(!string.IsNullOrEmpty(year)) if (!string.IsNullOrEmpty(year))
cleanTitle = cleanTitle.Replace(" " + year, string.Empty); cleanTitle = cleanTitle.Replace(" " + year, string.Empty);
cleanTitle = Regex.Replace(cleanTitle, @"^\s*|[\s-]*$", string.Empty); cleanTitle = Regex.Replace(cleanTitle, @"^\s*|[\s-]*$", string.Empty);
@ -296,10 +296,12 @@ namespace Jackett.Common.Indexers
// so let's try to pick up first without the .tooltip class, // so let's try to pick up first without the .tooltip class,
// if nothing is found, then we try again without that filter // if nothing is found, then we try again without that filter
var qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]:not(.tooltip)"); var qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]:not(.tooltip)");
if (qDetailsLink == null) { if (qDetailsLink == null)
{
qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]"); qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]");
// if still can't find the right link, skip it // if still can't find the right link, skip it
if (qDetailsLink == null) { if (qDetailsLink == null)
{
logger.Error($"{Id}: Error while parsing row '{row.OuterHtml}': Can't find the right details link"); logger.Error($"{Id}: Error while parsing row '{row.OuterHtml}': Can't find the right details link");
continue; continue;
} }

View File

@ -9,10 +9,10 @@ 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;
using Polly;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using Polly;
using static Jackett.Common.Models.IndexerConfig.ConfigurationData; using static Jackett.Common.Models.IndexerConfig.ConfigurationData;
namespace Jackett.Common.Indexers namespace Jackett.Common.Indexers
@ -510,7 +510,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 referer = null, Dictionary<string, string>headers = null) protected async Task<byte[]> Download(Uri link, RequestType method, string referer = null, Dictionary<string, string> headers = null)
{ {
// return magnet link // return magnet link
if (link.Scheme == "magnet") if (link.Scheme == "magnet")
@ -769,7 +769,7 @@ namespace Jackett.Common.Indexers
public abstract class BaseCachingWebIndexer : BaseWebIndexer public abstract class BaseCachingWebIndexer : BaseWebIndexer
{ {
protected BaseCachingWebIndexer(string link,string id, string name, string description, protected BaseCachingWebIndexer(string link, string id, string name, string description,
IIndexerConfigurationService configService, WebClient client, Logger logger, IIndexerConfigurationService configService, WebClient client, Logger logger,
ConfigurationData configData, IProtectionService p, ICacheService cacheService, ConfigurationData configData, IProtectionService p, ICacheService cacheService,
TorznabCapabilities caps = null, string downloadBase = null) TorznabCapabilities caps = null, string downloadBase = null)

View File

@ -108,7 +108,8 @@ namespace Jackett.Common.Indexers
{ {
searchParam["name"] = $"Season {query.Season}"; searchParam["name"] = $"Season {query.Season}";
searchParam["category"] = "Season"; searchParam["category"] = "Season";
} else if (query.Season > 0 && int.Parse(query.Episode) > 0) }
else if (query.Season > 0 && int.Parse(query.Episode) > 0)
{ {
searchParam["name"] = string.Format("S{0:00}E{1:00}", query.Season, int.Parse(query.Episode)); searchParam["name"] = string.Format("S{0:00}E{1:00}", query.Season, int.Parse(query.Episode));
searchParam["category"] = "Episode"; searchParam["category"] = "Episode";

View File

@ -241,50 +241,50 @@ namespace Jackett.Common.Indexers
switch (configurationItem) switch (configurationItem)
{ {
case BoolConfigurationItem boolItem: case BoolConfigurationItem boolItem:
{ {
variables[variableKey] = variables[boolItem.Value ? ".True" : ".False"]; variables[variableKey] = variables[boolItem.Value ? ".True" : ".False"];
break; break;
} }
case StringConfigurationItem stringItem: case StringConfigurationItem stringItem:
{ {
variables[variableKey] = stringItem.Value; variables[variableKey] = stringItem.Value;
break; break;
} }
case PasswordConfigurationItem passwordItem: case PasswordConfigurationItem passwordItem:
{ {
variables[variableKey] = passwordItem.Value; variables[variableKey] = passwordItem.Value;
break; break;
} }
case SingleSelectConfigurationItem selectItem: case SingleSelectConfigurationItem selectItem:
{ {
variables[variableKey] = selectItem.Value; variables[variableKey] = selectItem.Value;
break; break;
} }
case MultiSelectConfigurationItem multiSelectItem: case MultiSelectConfigurationItem multiSelectItem:
{ {
variables[variableKey] = multiSelectItem.Values; variables[variableKey] = multiSelectItem.Values;
break; break;
} }
case DisplayImageConfigurationItem displayImageItem: case DisplayImageConfigurationItem displayImageItem:
{ {
variables[variableKey] = displayImageItem.Value; variables[variableKey] = displayImageItem.Value;
break; break;
} }
case DisplayInfoConfigurationItem displayInfoItem: case DisplayInfoConfigurationItem displayInfoItem:
{ {
variables[variableKey] = displayInfoItem.Value; variables[variableKey] = displayInfoItem.Value;
break; break;
} }
case HiddenStringConfigurationItem hiddenStringItem: case HiddenStringConfigurationItem hiddenStringItem:
{ {
variables[variableKey] = hiddenStringItem.Value; variables[variableKey] = hiddenStringItem.Value;
break; break;
} }
default: default:
{ {
//TODO Should this throw a NotSupportedException, as it used to? //TODO Should this throw a NotSupportedException, as it used to?
break; break;
} }
} }
} }
@ -378,23 +378,23 @@ namespace Jackett.Common.Indexers
break; break;
case "eq": // Returns .True if equal case "eq": // Returns .True if equal
case "ne": // Returns .False if equal case "ne": // Returns .False if equal
{ {
var wantEqual = functionName == "eq"; var wantEqual = functionName == "eq";
// eq/ne take exactly 2 params. Update the length to match // eq/ne take exactly 2 params. Update the length to match
// This removes the whitespace between params 2 and 3. // This removes the whitespace between params 2 and 3.
// It shouldn't matter because the match starts at a word boundary // It shouldn't matter because the match starts at a word boundary
if (parameters.Count > 2) if (parameters.Count > 2)
functionLength = logicMatch.Groups[2].Captures[2].Index - functionStartIndex; functionLength = logicMatch.Groups[2].Captures[2].Index - functionStartIndex;
// Take first two parameters, convert vars to values and strip quotes on string literals // Take first two parameters, convert vars to values and strip quotes on string literals
// Counting distinct gives us 1 if equal and 2 if not. // Counting distinct gives us 1 if equal and 2 if not.
var isEqual = var isEqual =
parameters.Take(2).Select(param => param.StartsWith("\"") ? param.Trim('"') : variables[param] as string) parameters.Take(2).Select(param => param.StartsWith("\"") ? param.Trim('"') : variables[param] as string)
.Distinct().Count() == 1; .Distinct().Count() == 1;
functionResult = isEqual == wantEqual ? ".True" : ".False"; functionResult = isEqual == wantEqual ? ".True" : ".False";
break; break;
} }
} }
template = template.Remove(functionStartIndex, functionLength) template = template.Remove(functionStartIndex, functionLength)
@ -1796,7 +1796,7 @@ namespace Jackett.Common.Indexers
} }
private Dictionary<string, string> ParseCustomHeaders(Dictionary<string, List<string>> customHeaders, private Dictionary<string, string> ParseCustomHeaders(Dictionary<string, List<string>> customHeaders,
Dictionary<string,object> variables) Dictionary<string, object> variables)
{ {
if (customHeaders == null) if (customHeaders == null)
return null; return null;

View File

@ -172,7 +172,7 @@ namespace Jackett.Common.Indexers
var details = titleRow.QuerySelector("a[href^=\"details.php?id=\"]:has(span)"); var details = titleRow.QuerySelector("a[href^=\"details.php?id=\"]:has(span)");
var detailsLink = new Uri(SiteLink + details.GetAttribute("href")); var detailsLink = new Uri(SiteLink + details.GetAttribute("href"));
var encodedDownloadLink = detailsRow.QuerySelector("a[id^=\"download_\"]").GetAttribute("data-href"); var encodedDownloadLink = detailsRow.QuerySelector("a[id^=\"download_\"]").GetAttribute("data-href");
var siteDownloadLink = new Uri(SiteLink + Uri.UnescapeDataString(StringUtil.FromBase64(encodedDownloadLink))); var siteDownloadLink = new Uri(SiteLink + Uri.UnescapeDataString(StringUtil.FromBase64(encodedDownloadLink)));
var infoHash = HttpUtility.ParseQueryString(siteDownloadLink.Query)["id"]; var infoHash = HttpUtility.ParseQueryString(siteDownloadLink.Query)["id"];
var posterStr = detailsRow.QuerySelector("img[src^=\"./imgtorrent/\"]")?.GetAttribute("src"); var posterStr = detailsRow.QuerySelector("img[src^=\"./imgtorrent/\"]")?.GetAttribute("src");
var poster = !string.IsNullOrEmpty(posterStr) ? new Uri(SiteLink + posterStr) : null; var poster = !string.IsNullOrEmpty(posterStr) ? new Uri(SiteLink + posterStr) : null;
@ -228,10 +228,10 @@ namespace Jackett.Common.Indexers
{ {
return releases; return releases;
} }
for (var i = 0; i < rows.Length; i+=2) for (var i = 0; i < rows.Length; i += 2)
{ {
// First row contains table, the second row contains the rest of the details // First row contains table, the second row contains the rest of the details
var releaseInfo = ParseRow(rows[i], rows[i+1]); var releaseInfo = ParseRow(rows[i], rows[i + 1]);
releases.Add(releaseInfo); releases.Add(releaseInfo);
} }
} }

View File

@ -60,7 +60,8 @@ namespace Jackett.Common.Indexers
name: "DivxTotal", name: "DivxTotal",
description: "DivxTotal is a SPANISH site for Movies, TV series and Software", description: "DivxTotal is a SPANISH site for Movies, TV series and Software",
link: "https://www.divxtotal.ch/", link: "https://www.divxtotal.ch/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
@ -278,7 +279,7 @@ namespace Jackett.Common.Indexers
{ {
var anchor = row.QuerySelector("a"); var anchor = row.QuerySelector("a");
var episodeTitle = anchor.TextContent.Trim(); var episodeTitle = anchor.TextContent.Trim();
// Convert the title to Scene format // Convert the title to Scene format
episodeTitle = ParseDivxTotalSeriesTitle(episodeTitle, query); episodeTitle = ParseDivxTotalSeriesTitle(episodeTitle, query);

View File

@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq;
using System.Xml; using System.Xml;
using Jackett.Common.Models; using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig; using Jackett.Common.Models.IndexerConfig;
@ -353,7 +353,7 @@ namespace Jackett.Common.Indexers
).Trim(); ).Trim();
} }
private static (string strippedTitle, Dictionary<string, string> details) SearchTitleForDetails(string title, Dictionary<string, Dictionary<string,string>> definition) private static (string strippedTitle, Dictionary<string, string> details) SearchTitleForDetails(string title, Dictionary<string, Dictionary<string, string>> definition)
{ {
Dictionary<string, string> details = new Dictionary<string, string>(); Dictionary<string, string> details = new Dictionary<string, string>();
foreach (var search in definition) foreach (var search in definition)

View File

@ -226,7 +226,7 @@ namespace Jackett.Common.Indexers
var i = 0; var i = 0;
foreach (var cat in MapTorznabCapsToTrackers(query)) foreach (var cat in MapTorznabCapsToTrackers(query))
queryCollection.Add($"artistcheck[{i++}]", cat); queryCollection.Add($"artistcheck[{i++}]", cat);
searchUrl += "?" + queryCollection.GetQueryString(); searchUrl += "?" + queryCollection.GetQueryString();

View File

@ -55,7 +55,7 @@ namespace Jackett.Common.Indexers
void Unconfigure(); void Unconfigure();
Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer=false); Task<IndexerResult> ResultsForQuery(TorznabQuery query, bool isMetaIndexer = false);
bool CanHandleQuery(TorznabQuery query); bool CanHandleQuery(TorznabQuery query);
} }

View File

@ -230,7 +230,7 @@ namespace Jackett.Common.Indexers
var link = new Uri(SiteLink + qLink.GetAttribute("href").TrimStart('/')); var link = new Uri(SiteLink + qLink.GetAttribute("href").TrimStart('/'));
var descrSplit = row.QuerySelector("div.sub").TextContent.Split('|'); var descrSplit = row.QuerySelector("div.sub").TextContent.Split('|');
var dateSplit = descrSplit.Last().Split(new [] {" by "}, StringSplitOptions.None); var dateSplit = descrSplit.Last().Split(new[] { " by " }, StringSplitOptions.None);
var publishDate = DateTimeUtil.FromTimeAgo(dateSplit.First()); var publishDate = DateTimeUtil.FromTimeAgo(dateSplit.First());
var description = descrSplit.Length > 1 ? "Tags: " + descrSplit.First().Trim() : ""; var description = descrSplit.Length > 1 ? "Tags: " + descrSplit.First().Trim() : "";
description += dateSplit.Length > 1 ? " Uploaded by: " + dateSplit.Last().Trim() : ""; description += dateSplit.Length > 1 ? " Uploaded by: " + dateSplit.Last().Trim() : "";

View File

@ -274,7 +274,8 @@ namespace Jackett.Common.Indexers
for (var i = releaseTags.Count - 1; i >= 0; i--) for (var i = releaseTags.Count - 1; i >= 0; i--)
{ {
var releaseTag = releaseTags[i]; var releaseTag = releaseTags[i];
if (VolumeTagMappings.ContainsKey(releaseTag)) { if (VolumeTagMappings.ContainsKey(releaseTag))
{
var volumeFactor = VolumeTagMappings[releaseTag]; var volumeFactor = VolumeTagMappings[releaseTag];
release.DownloadVolumeFactor = volumeFactor.DownloadVolumeFactor; release.DownloadVolumeFactor = volumeFactor.DownloadVolumeFactor;
release.UploadVolumeFactor = volumeFactor.UploadVolumeFactor; release.UploadVolumeFactor = volumeFactor.UploadVolumeFactor;

View File

@ -103,7 +103,8 @@ namespace Jackett.Common.Indexers
name: "LostFilm.tv", name: "LostFilm.tv",
description: "Unique portal about foreign series", description: "Unique portal about foreign series",
link: "https://www.lostfilm.run/", link: "https://www.lostfilm.run/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep

View File

@ -69,7 +69,7 @@ namespace Jackett.Common.Indexers
{"N_FILES", "files"}, {"N_FILES", "files"},
{"RELEVANCE", "relevance"} {"RELEVANCE", "relevance"}
}) })
{ Value = "discovered" }; { Value = "discovered" };
configData.AddDynamic("sort", sort); configData.AddDynamic("sort", sort);
var order = new ConfigurationData.SingleSelectConfigurationItem("Order requested from site", new Dictionary<string, string> var order = new ConfigurationData.SingleSelectConfigurationItem("Order requested from site", new Dictionary<string, string>
@ -77,7 +77,7 @@ namespace Jackett.Common.Indexers
{"false", "desc"}, {"false", "desc"},
{"true", "asc"} {"true", "asc"}
}) })
{ Value = "false" }; { Value = "false" };
configData.AddDynamic("order", order); configData.AddDynamic("order", order);
AddCategoryMapping("1", TorznabCatType.Other); AddCategoryMapping("1", TorznabCatType.Other);
@ -126,7 +126,7 @@ namespace Jackett.Common.Indexers
Guid = details, Guid = details,
InfoHash = torrent.infoHash, InfoHash = torrent.infoHash,
PublishDate = publishDate, PublishDate = publishDate,
Category = new List<int>{ TorznabCatType.Other.ID }, Category = new List<int> { TorznabCatType.Other.ID },
Size = torrent.size, Size = torrent.size,
Files = torrent.nFiles, Files = torrent.nFiles,
Seeders = 1, Seeders = 1,

View File

@ -16,7 +16,7 @@ namespace Jackett.Common.Indexers.Meta
{ {
protected BaseMetaIndexer(string name, string id, string description, protected BaseMetaIndexer(string name, string id, string description,
IFallbackStrategyProvider fallbackStrategyProvider, IFallbackStrategyProvider fallbackStrategyProvider,
IResultFilterProvider resultFilterProvider,IIndexerConfigurationService configService, IResultFilterProvider resultFilterProvider, IIndexerConfigurationService configService,
WebClient client, Logger logger, ConfigurationData configData, IProtectionService ps, WebClient client, Logger logger, ConfigurationData configData, IProtectionService ps,
ICacheService cs, Func<IIndexer, bool> filter) ICacheService cs, Func<IIndexer, bool> filter)
: base(id: id, : base(id: id,

View File

@ -48,7 +48,7 @@ namespace Jackett.Common.Indexers.Meta
WebClient client, Logger logger, IProtectionService ps, ICacheService cs, Func<IIndexer, bool> filterFunc) WebClient client, Logger logger, IProtectionService ps, ICacheService cs, Func<IIndexer, bool> filterFunc)
: base(id: filter, : base(id: filter,
name: filter, name: filter,
description: "This feed includes all configured trackers filter by "+filter, description: "This feed includes all configured trackers filter by " + filter,
configService: configService, configService: configService,
client: client, client: client,
logger: logger, logger: logger,

View File

@ -147,7 +147,7 @@ namespace Jackett.Common.Indexers
releases.Add(release); releases.Add(release);
} }
} }
catch(Exception ex) catch (Exception ex)
{ {
OnParseError(jsonResponse.ContentString, ex); OnParseError(jsonResponse.ContentString, ex);
} }

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using AngleSharp.Dom; using AngleSharp.Dom;
using AngleSharp.Html.Dom; using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser; using AngleSharp.Html.Parser;
@ -16,7 +17,6 @@ using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils; using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients; using Jackett.Common.Utils.Clients;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Web;
using NLog; using NLog;
using static Jackett.Common.Models.IndexerConfig.ConfigurationData; using static Jackett.Common.Models.IndexerConfig.ConfigurationData;

View File

@ -82,8 +82,8 @@ namespace Jackett.Common.Indexers
private readonly int _maxDailyPages = 1; private readonly int _maxDailyPages = 1;
private readonly int _maxMoviesPages = 6; private readonly int _maxMoviesPages = 6;
private readonly int[] _allTvCategories = (new [] {TorznabCatType.TV }).Concat(TorznabCatType.TV.SubCategories).Select(c => c.ID).ToArray(); private readonly int[] _allTvCategories = (new[] { TorznabCatType.TV }).Concat(TorznabCatType.TV.SubCategories).Select(c => c.ID).ToArray();
private readonly int[] _allMoviesCategories = (new [] { TorznabCatType.Movies }).Concat(TorznabCatType.Movies.SubCategories).Select(c => c.ID).ToArray(); private readonly int[] _allMoviesCategories = (new[] { TorznabCatType.Movies }).Concat(TorznabCatType.Movies.SubCategories).Select(c => c.ID).ToArray();
private bool _includeVo; private bool _includeVo;
private bool _filterMovies; private bool _filterMovies;
@ -124,7 +124,8 @@ namespace Jackett.Common.Indexers
name: "NewPCT", name: "NewPCT",
description: "NewPCT - Descargar peliculas, series y estrenos torrent gratis", description: "NewPCT - Descargar peliculas, series y estrenos torrent gratis",
link: "https://pctmix.com/", link: "https://pctmix.com/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
@ -551,12 +552,13 @@ namespace Jackett.Common.Indexers
if (titleLower.Contains("[web screener]") || titleLower.Contains("[hd-tc]")) if (titleLower.Contains("[web screener]") || titleLower.Contains("[hd-tc]"))
quality = "TS Screener"; quality = "TS Screener";
} }
else if (titleParts.Length > 2) else if (titleParts.Length > 2)
quality = titleParts[1].Replace("]", "").Replace("MKV", "").Trim(); quality = titleParts[1].Replace("]", "").Replace("MKV", "").Trim();
// we have to guess the language (words DUAL or MULTI are not supported in Radarr) // we have to guess the language (words DUAL or MULTI are not supported in Radarr)
var language = "spanish"; var language = "spanish";
if (titleLower.Contains("latino")) language += " latino"; if (titleLower.Contains("latino"))
language += " latino";
if ((titleLower.Contains("castellano") && titleLower.Contains("ingles")) || if ((titleLower.Contains("castellano") && titleLower.Contains("ingles")) ||
(titleLower.Contains("spanish") && titleLower.Contains("english")) || (titleLower.Contains("spanish") && titleLower.Contains("english")) ||
titleLower.Contains("[es-en]") || titleLower.Contains("multilenguaje")) titleLower.Contains("[es-en]") || titleLower.Contains("multilenguaje"))

View File

@ -167,7 +167,7 @@ namespace Jackett.Common.Indexers
else if ((bool?)torrent.polish == true) else if ((bool?)torrent.polish == true)
descriptions.Add("Language: pl"); descriptions.Add("Language: pl");
if (language == "pl" && (((BoolConfigurationItem) configData.GetDynamic("LanguageTitle")).Value)) if (language == "pl" && (((BoolConfigurationItem)configData.GetDynamic("LanguageTitle")).Value))
title += " POLISH"; title += " POLISH";
var description = descriptions.Any() ? string.Join("<br />\n", descriptions) : null; var description = descriptions.Any() ? string.Join("<br />\n", descriptions) : null;

View File

@ -137,7 +137,8 @@ namespace Jackett.Common.Indexers
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
=> await PerformQueryWithRetry(query, true); => await PerformQueryWithRetry(query, true);
private async Task<IEnumerable<ReleaseInfo>> PerformQueryWithRetry(TorznabQuery query, bool retry) { private async Task<IEnumerable<ReleaseInfo>> PerformQueryWithRetry(TorznabQuery query, bool retry)
{
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
// check the token and renewal if necessary // check the token and renewal if necessary

View File

@ -54,7 +54,7 @@ namespace Jackett.Common.Indexers
// requestDelay for API Limit (1 request per 2 seconds) // requestDelay for API Limit (1 request per 2 seconds)
webclient.requestDelay = 2.1; webclient.requestDelay = 2.1;
AddCategoryMapping(401, TorznabCatType.Movies, "Movies"); AddCategoryMapping(401, TorznabCatType.Movies, "Movies");
AddCategoryMapping(402, TorznabCatType.TV, "TV Series"); AddCategoryMapping(402, TorznabCatType.TV, "TV Series");
AddCategoryMapping(406, TorznabCatType.AudioVideo, "Music Videos"); AddCategoryMapping(406, TorznabCatType.AudioVideo, "Music Videos");

View File

@ -1493,7 +1493,7 @@ namespace Jackett.Common.Indexers
var qDetailsLink = row.QuerySelector("td.t-title-col > div.t-title > a.tLink"); var qDetailsLink = row.QuerySelector("td.t-title-col > div.t-title > a.tLink");
var details = new Uri(SiteLink + "forum/" + qDetailsLink.GetAttribute("href")); var details = new Uri(SiteLink + "forum/" + qDetailsLink.GetAttribute("href"));
var category = GetCategoryOfRelease(row); var category = GetCategoryOfRelease(row);
var size = GetSizeOfRelease(row); var size = GetSizeOfRelease(row);
@ -1672,7 +1672,7 @@ namespace Jackett.Common.Indexers
{ {
var fullTitle = input; var fullTitle = input;
var squareBracketTags = input.FindSubstringsBetween('[', ']', includeOpeningAndClosing:true); var squareBracketTags = input.FindSubstringsBetween('[', ']', includeOpeningAndClosing: true);
input = input.RemoveSubstrings(squareBracketTags); input = input.RemoveSubstrings(squareBracketTags);
var roundBracketTags = input.FindSubstringsBetween('(', ')', includeOpeningAndClosing: true); var roundBracketTags = input.FindSubstringsBetween('(', ')', includeOpeningAndClosing: true);

View File

@ -65,7 +65,7 @@ namespace Jackett.Common.Indexers
cacheService: cs, cacheService: cs,
configData: new ConfigurationDataPasskey() configData: new ConfigurationDataPasskey()
) )
{ {
Encoding = Encoding.UTF8; Encoding = Encoding.UTF8;
Language = "fr-fr"; Language = "fr-fr";
Type = "semi-private"; Type = "semi-private";
@ -143,7 +143,7 @@ namespace Jackett.Common.Indexers
{"ENGLISH", "ENGLISH"}, {"ENGLISH", "ENGLISH"},
{"MULTI.ENGLISH", "MULTI.ENGLISH" }, {"MULTI.ENGLISH", "MULTI.ENGLISH" },
{"VOSTFR", "VOSTFR"}, {"VOSTFR", "VOSTFR"},
{"MULTI.VOSTFR", "MULTI.VOSTFR"} {"MULTI.VOSTFR", "MULTI.VOSTFR"}
}) })
{ Value = "FRENCH" }; { Value = "FRENCH" };
; ;

View File

@ -41,7 +41,7 @@ namespace Jackett.Common.Indexers
logger: l, logger: l,
p: ps, p: ps,
cacheService: cs, cacheService: cs,
configData: new ConfigurationDataBasicLoginWithEmail()) configData: new ConfigurationDataBasicLoginWithEmail())
{ {
Encoding = Encoding.UTF8; Encoding = Encoding.UTF8;
Language = "ru-ru"; Language = "ru-ru";
@ -98,13 +98,17 @@ namespace Jackett.Common.Indexers
} }
// If the search string is empty use the latest releases // If the search string is empty use the latest releases
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
await EnsureAuthorized(); await EnsureAuthorized();
WebResult result; WebResult result;
if (query.IsTest || string.IsNullOrWhiteSpace(query.SearchTerm)) { if (query.IsTest || string.IsNullOrWhiteSpace(query.SearchTerm))
{
result = await RequestWithCookiesAndRetryAsync(SiteLink); result = await RequestWithCookiesAndRetryAsync(SiteLink);
} else { }
else
{
// Prepare the search query // Prepare the search query
var queryParameters = new NameValueCollection var queryParameters = new NameValueCollection
{ {
@ -164,7 +168,7 @@ namespace Jackett.Common.Indexers
Details = uri, Details = uri,
DownloadVolumeFactor = 0, DownloadVolumeFactor = 0,
UploadVolumeFactor = 1, UploadVolumeFactor = 1,
Category = new[]{ TorznabCatType.TVAnime.ID } Category = new[] { TorznabCatType.TVAnime.ID }
}; };
foreach (var t in r.QuerySelectorAll("a[data-toggle]")) foreach (var t in r.QuerySelectorAll("a[data-toggle]"))
@ -191,13 +195,15 @@ namespace Jackett.Common.Indexers
return releases; return releases;
} }
private string composeBaseTitle(IElement release) { private string composeBaseTitle(IElement release)
{
var titleDiv = release.QuerySelector("section:nth-of-type(2) > div.card > article:nth-of-type(1) > div.card-header"); var titleDiv = release.QuerySelector("section:nth-of-type(2) > div.card > article:nth-of-type(1) > div.card-header");
return titleDiv.QuerySelector("h3").Text() + " " + titleDiv.QuerySelector("p").Text(); return titleDiv.QuerySelector("h3").Text() + " " + titleDiv.QuerySelector("p").Text();
} }
// Appending id to differentiate between different quality versions // Appending id to differentiate between different quality versions
private bool IsAuthorized(WebResult result) { private bool IsAuthorized(WebResult result)
{
return result.ContentString.Contains("/logout"); return result.ContentString.Contains("/logout");
} }

View File

@ -61,7 +61,7 @@ namespace Jackett.Common.Indexers
// requestDelay for API Limit (1 request per 2 seconds) // requestDelay for API Limit (1 request per 2 seconds)
webclient.requestDelay = 2.1; webclient.requestDelay = 2.1;
AddCategoryMapping(38, TorznabCatType.Movies, "Movie Packs"); AddCategoryMapping(38, TorznabCatType.Movies, "Movie Packs");
AddCategoryMapping(10, TorznabCatType.MoviesSD, "Movies: SD"); AddCategoryMapping(10, TorznabCatType.MoviesSD, "Movies: SD");
AddCategoryMapping(35, TorznabCatType.MoviesSD, "Movies: SD Ro"); AddCategoryMapping(35, TorznabCatType.MoviesSD, "Movies: SD Ro");

View File

@ -150,7 +150,7 @@ namespace Jackett.Common.Indexers
release.Guid = new Uri(d.Magnet); release.Guid = new Uri(d.Magnet);
// The API doesn't tell us file size, so give an estimate based on resolution // The API doesn't tell us file size, so give an estimate based on resolution
if(string.Equals(d.Res, "1080")) if (string.Equals(d.Res, "1080"))
release.Size = 1395864371; // 1.3GB release.Size = 1395864371; // 1.3GB
else if (string.Equals(d.Res, "720")) else if (string.Equals(d.Res, "720"))
release.Size = 734003200; // 700MB release.Size = 734003200; // 700MB

View File

@ -90,7 +90,7 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(24, TorznabCatType.MoviesUHD, "Film 4K"); AddCategoryMapping(24, TorznabCatType.MoviesUHD, "Film 4K");
AddCategoryMapping(26, TorznabCatType.TV, "TV DK"); AddCategoryMapping(26, TorznabCatType.TV, "TV DK");
AddCategoryMapping(27, TorznabCatType.TV, "TV NO"); AddCategoryMapping(27, TorznabCatType.TV, "TV NO");
AddCategoryMapping(28, TorznabCatType.TV, "TV FI"); AddCategoryMapping(28, TorznabCatType.TV, "TV FI");
} }
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson) public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)

View File

@ -36,7 +36,7 @@ namespace Jackett.Common.Indexers
{ {
MovieSearchParam.Q MovieSearchParam.Q
}, },
MusicSearchParams = new List<MusicSearchParam> MusicSearchParams = new List<MusicSearchParam>
{ {
MusicSearchParam.Q MusicSearchParam.Q
}, },

View File

@ -157,7 +157,7 @@ namespace Jackett.Common.Indexers
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
if (((BoolConfigurationItem) configData.GetDynamic("freeleech")).Value) if (((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value)
searchUrl += "facets/tags%3AFREELEECH/"; searchUrl += "facets/tags%3AFREELEECH/";
if (query.IsImdbQuery) if (query.IsImdbQuery)

View File

@ -36,7 +36,8 @@ namespace Jackett.Common.Indexers
name: "TorrentMafya", name: "TorrentMafya",
description: "TorrentMafya is a Turkish general torrent tracker ", description: "TorrentMafya is a Turkish general torrent tracker ",
link: "https://www.torrentmafya.org/", link: "https://www.torrentmafya.org/",
caps: new TorznabCapabilities { caps: new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam> TvSearchParams = new List<TvSearchParam>
{ {
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
@ -57,7 +58,7 @@ namespace Jackett.Common.Indexers
Language = "tr-tr"; Language = "tr-tr";
Type = "public"; Type = "public";
AddCategoryMapping("games", TorznabCatType.PCGames,"Oyun"); AddCategoryMapping("games", TorznabCatType.PCGames, "Oyun");
AddCategoryMapping("programs", TorznabCatType.PC, "Program"); AddCategoryMapping("programs", TorznabCatType.PC, "Program");
AddCategoryMapping("movies", TorznabCatType.Movies, "Film"); AddCategoryMapping("movies", TorznabCatType.Movies, "Film");
AddCategoryMapping("tv", TorznabCatType.TV, "Dizi"); AddCategoryMapping("tv", TorznabCatType.TV, "Dizi");
@ -97,17 +98,20 @@ namespace Jackett.Common.Indexers
if (classes.Contains("fa-gamepad")) if (classes.Contains("fa-gamepad"))
{ {
result.Add(TorznabCatType.PCGames.ID); result.Add(TorznabCatType.PCGames.ID);
} else if (classes.Contains("fa-film")) }
else if (classes.Contains("fa-film"))
{ {
result.Add(TorznabCatType.Movies.ID); result.Add(TorznabCatType.Movies.ID);
} else if (classes.Contains("fa-tv")) }
else if (classes.Contains("fa-tv"))
{ {
result.Add(TorznabCatType.TV.ID); result.Add(TorznabCatType.TV.ID);
} }
else if (classes.Contains("fa-microchip")) else if (classes.Contains("fa-microchip"))
{ {
result.Add(TorznabCatType.PC.ID); result.Add(TorznabCatType.PC.ID);
} else if (classes.Contains("fa-android")) }
else if (classes.Contains("fa-android"))
{ {
result.Add(TorznabCatType.PCMobileAndroid.ID); result.Add(TorznabCatType.PCMobileAndroid.ID);
} }
@ -134,7 +138,7 @@ namespace Jackett.Common.Indexers
var detailsLink = new Uri(firstColumn.QuerySelector("a").GetAttribute("href")); var detailsLink = new Uri(firstColumn.QuerySelector("a").GetAttribute("href"));
var category = ParseReleaseCategory(firstColumn.QuerySelector("i")?.ClassList); var category = ParseReleaseCategory(firstColumn.QuerySelector("i")?.ClassList);
var seederContent = mainColumn.QuerySelector("span.sayiGonderen")?.TextContent; var seederContent = mainColumn.QuerySelector("span.sayiGonderen")?.TextContent;
var leecherContent = mainColumn.QuerySelector("span.sayiIndiren")?.TextContent; var leecherContent = mainColumn.QuerySelector("span.sayiIndiren")?.TextContent;
int.TryParse(seederContent, out var seeders); int.TryParse(seederContent, out var seeders);
int.TryParse(leecherContent, out var leechers); int.TryParse(leecherContent, out var leechers);
return new ReleaseInfo return new ReleaseInfo

View File

@ -74,7 +74,8 @@ namespace Jackett.Common.Indexers
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var searchUrl = CreateSearchUrl(query); var searchUrl = CreateSearchUrl(query);
if (string.IsNullOrWhiteSpace(searchUrl)) return new List<ReleaseInfo>(); if (string.IsNullOrWhiteSpace(searchUrl))
return new List<ReleaseInfo>();
var response = await RequestWithCookiesAndRetryAsync(searchUrl); var response = await RequestWithCookiesAndRetryAsync(searchUrl);

View File

@ -128,7 +128,7 @@ namespace Jackett.Common.Indexers
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString(); var searchString = query.GetQueryString();
var queryCollection = new NameValueCollection {{"apikey", ConfigData.Key.Value}}; var queryCollection = new NameValueCollection { { "apikey", ConfigData.Key.Value } };
queryCollection.Add("limit", "50"); // Default 30 queryCollection.Add("limit", "50"); // Default 30
//queryCollection.Add("ponly", true); // Torrents with products only //queryCollection.Add("ponly", true); // Torrents with products only
@ -162,7 +162,7 @@ namespace Jackett.Common.Indexers
foreach (var row in jsonContent.Value<JArray>("rows")) foreach (var row in jsonContent.Value<JArray>("rows"))
{ {
var dateTime = new DateTime(1970,1,1,0,0,0,0,DateTimeKind.Utc); var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var id = row.Value<string>("id"); var id = row.Value<string>("id");
var details = new Uri(SiteLink + "details.php?id=" + id); var details = new Uri(SiteLink + "details.php?id=" + id);

View File

@ -65,7 +65,8 @@ namespace Jackett.Common.Indexers
return IndexerConfigurationStatus.Completed; return IndexerConfigurationStatus.Completed;
} }
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) { protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString(); var searchString = query.GetQueryString();

View File

@ -154,7 +154,7 @@ namespace Jackett.Common.Indexers
var captchaImageResponse = await RequestWithCookiesAsync(captchaUrl, loginPage.Cookies, RequestType.GET, LandingUrl); var captchaImageResponse = await RequestWithCookiesAsync(captchaUrl, loginPage.Cookies, RequestType.GET, LandingUrl);
var captchaText = new StringConfigurationItem("Captcha Text"); var captchaText = new StringConfigurationItem("Captcha Text");
var captchaImage = new DisplayImageConfigurationItem("Captcha Image") { Value = captchaImageResponse.ContentBytes}; var captchaImage = new DisplayImageConfigurationItem("Captcha Image") { Value = captchaImageResponse.ContentBytes };
configData.AddDynamic("CaptchaText", captchaText); configData.AddDynamic("CaptchaText", captchaText);
configData.AddDynamic("CaptchaImage", captchaImage); configData.AddDynamic("CaptchaImage", captchaImage);

View File

@ -268,9 +268,9 @@ namespace Jackett.Common.Indexers
// Warning 1998 is async method with no await calls inside // Warning 1998 is async method with no await calls inside
// TODO: Remove pragma by wrapping return in Task.FromResult and removing async // TODO: Remove pragma by wrapping return in Task.FromResult and removing async
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson) public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{ {
// Provider not yet configured // Provider not yet configured
IsConfigured = false; IsConfigured = false;
@ -320,7 +320,8 @@ namespace Jackett.Common.Indexers
} }
// Multiple page support // Multiple page support
var nextPage = 1; var followingPages = true; var nextPage = 1;
var followingPages = true;
do do
{ {
@ -393,7 +394,7 @@ namespace Jackett.Common.Indexers
return release; return release;
})); }));
nextPage++; nextPage++;
} }
else else
{ {
@ -409,9 +410,9 @@ namespace Jackett.Common.Indexers
} }
// Stop ? // Stop ?
if(query.IsTmdbQuery && MaxPagesBypassForTMDB) if (query.IsTmdbQuery && MaxPagesBypassForTMDB)
{ {
if(nextPage > MaxPagesHardLimit) if (nextPage > MaxPagesHardLimit)
{ {
logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page hard limit reached."); logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page hard limit reached.");
break; break;
@ -421,15 +422,17 @@ namespace Jackett.Common.Indexers
} }
else else
{ {
if(torrentsCount < 32) if (torrentsCount < 32)
{ {
logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due max available results reached."); logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due max available results reached.");
break; break;
} else if(nextPage > MaxPages) }
else if (nextPage > MaxPages)
{ {
logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page limit reached."); logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to page limit reached.");
break; break;
} else if (query.IsTest) }
else if (query.IsTest)
{ {
logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to index test query."); logger.Info("\nXthor - Stopping follow of next page " + nextPage + " due to index test query.");
break; break;
@ -440,8 +443,8 @@ namespace Jackett.Common.Indexers
// Check if there is duplicate and return unique rows - Xthor API can be very buggy ! // Check if there is duplicate and return unique rows - Xthor API can be very buggy !
var uniqReleases = releases.GroupBy(x => x.Guid).Select(x => x.First()).ToList(); var uniqReleases = releases.GroupBy(x => x.Guid).Select(x => x.First()).ToList();
var errorPercentage = 1 - ((double) uniqReleases.Count() / releases.Count()); var errorPercentage = 1 - ((double)uniqReleases.Count() / releases.Count());
if(errorPercentage >= 0.25) if (errorPercentage >= 0.25)
{ {
logger.Warn("\nXthor - High percentage error detected: " + string.Format("{0:0.0%}", errorPercentage) + "\nWe strongly recommend that you lower max page to 1, as there is no benefit to grab additionnals.\nTracker API sent us duplicated pages with same results, even if we deduplicate returned rows, please consider to lower as it's unnecessary and increase time used for query for the same result."); logger.Warn("\nXthor - High percentage error detected: " + string.Format("{0:0.0%}", errorPercentage) + "\nWe strongly recommend that you lower max page to 1, as there is no benefit to grab additionnals.\nTracker API sent us duplicated pages with same results, even if we deduplicate returned rows, please consider to lower as it's unnecessary and increase time used for query for the same result.");
} }

View File

@ -240,7 +240,7 @@ namespace Jackett.Common.Indexers
{ {
// The first page set the cookies and the session_id // The first page set the cookies and the session_id
CookieHeader = ""; CookieHeader = "";
var result = await RequestWithCookiesAsync(Login1Url, ""); var result = await RequestWithCookiesAsync(Login1Url, "");
var parser = new HtmlParser(); var parser = new HtmlParser();
var dom = parser.ParseDocument(result.ContentString); var dom = parser.ParseDocument(result.ContentString);
var sessionId = dom.QuerySelector("input#session_id")?.GetAttribute("value"); var sessionId = dom.QuerySelector("input#session_id")?.GetAttribute("value");

View File

@ -11,7 +11,7 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
public ConfigurationDataFileList() public ConfigurationDataFileList()
: base("Note this is <b>not</b> your <i>password</i>.<ul><li>Login to the FileList Website</li><li>Click on the <b>Profile</b> link</li><li>Scroll down to the <b>Reset Passkey</b> section</li><li>Copy the <b>passkey</b>.</li><li>Also be aware of not leaving a trailing blank at the end of the passkey after pasting it here.</li></ul>") : base("Note this is <b>not</b> your <i>password</i>.<ul><li>Login to the FileList Website</li><li>Click on the <b>Profile</b> link</li><li>Scroll down to the <b>Reset Passkey</b> section</li><li>Copy the <b>passkey</b>.</li><li>Also be aware of not leaving a trailing blank at the end of the passkey after pasting it here.</li></ul>")
{ {
IncludeRomanianReleases = new BoolConfigurationItem("IncludeRomanianReleases") { Value = false}; IncludeRomanianReleases = new BoolConfigurationItem("IncludeRomanianReleases") { Value = false };
CatWarning = new DisplayInfoConfigurationItem("CatWarning", "When mapping TV ensure you add category 5000 in addition to 5030, 5040."); CatWarning = new DisplayInfoConfigurationItem("CatWarning", "When mapping TV ensure you add category 5000 in addition to 5030, 5040.");
} }
} }

View File

@ -22,7 +22,7 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
{"6", "VP9"}, {"6", "VP9"},
{"4", "XviD"} {"4", "XviD"}
}) })
{ Values = new [] { "0", "1", "5", "2", "3", "6", "4" } }; { Values = new[] { "0", "1", "5", "2", "3", "6", "4" } };
Mediums = new MultiSelectConfigurationItem("Medium", new Dictionary<string, string>() Mediums = new MultiSelectConfigurationItem("Medium", new Dictionary<string, string>()
{ {
@ -33,14 +33,14 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
{"5", "Remux"}, {"5", "Remux"},
{"6", "WEB-DL"} {"6", "WEB-DL"}
}) })
{ Values = new [] { "0", "1", "4", "3", "5", "6" } }; { Values = new[] { "0", "1", "4", "3", "5", "6" } };
Origins = new MultiSelectConfigurationItem("Origin", new Dictionary<string, string>() Origins = new MultiSelectConfigurationItem("Origin", new Dictionary<string, string>()
{ {
{"0", "Undefined"}, {"0", "Undefined"},
{"1", "Internal"} {"1", "Internal"}
}) })
{ Values = new [] { "0", "1" } }; { Values = new[] { "0", "1" } };
} }
} }
} }

View File

@ -15,10 +15,10 @@ namespace Jackett.Common.Models.IndexerConfig.Bespoke
: base() : base()
{ {
StripRussianLetters = new BoolConfigurationItem("Strip Russian Letters") { Value = true }; StripRussianLetters = new BoolConfigurationItem("Strip Russian Letters") { Value = true };
MoveTagsInfo = new DisplayInfoConfigurationItem("Move Tags Info", "<b>About moving tags:</b> "+ MoveTagsInfo = new DisplayInfoConfigurationItem("Move Tags Info", "<b>About moving tags:</b> " +
"We define a tag as a part of the release title between round or square brackets. "+ "We define a tag as a part of the release title between round or square brackets. " +
"If the release title contains tags then these options will move those tags and their brackets to the end of the release title. "+ "If the release title contains tags then these options will move those tags and their brackets to the end of the release title. " +
"Moving only the first tags will try to detect where the actual title of the release begins, and move only the tags that are found before that point. "+ "Moving only the first tags will try to detect where the actual title of the release begins, and move only the tags that are found before that point. " +
"Enabling both options will enable moving of all tags."); "Enabling both options will enable moving of all tags.");
MoveFirstTagsToEndOfReleaseTitle = new BoolConfigurationItem("Move first tags to end of release title") { Value = false }; MoveFirstTagsToEndOfReleaseTitle = new BoolConfigurationItem("Move first tags to end of release title") { Value = false };
MoveAllTagsToEndOfReleaseTitle = new BoolConfigurationItem("Move all tags to end of release title") { Value = false }; MoveAllTagsToEndOfReleaseTitle = new BoolConfigurationItem("Move all tags to end of release title") { Value = false };

View File

@ -17,7 +17,7 @@ namespace Jackett.Common.Models.IndexerConfig
public HiddenStringConfigurationItem CookieHeader { get; private set; } = new HiddenStringConfigurationItem(name: "CookieHeader"); public HiddenStringConfigurationItem CookieHeader { get; private set; } = new HiddenStringConfigurationItem(name: "CookieHeader");
public HiddenStringConfigurationItem LastError { get; private set; } = new HiddenStringConfigurationItem(name: "LastError"); public HiddenStringConfigurationItem LastError { get; private set; } = new HiddenStringConfigurationItem(name: "LastError");
public StringConfigurationItem SiteLink { get; private set; } = new StringConfigurationItem(name: "Site Link"); public StringConfigurationItem SiteLink { get; private set; } = new StringConfigurationItem(name: "Site Link");
public TagsConfigurationItem Tags { get; private set; } = new TagsConfigurationItem(name: "Tags", charSet:"A-Za-z0-9\\-\\._~"); public TagsConfigurationItem Tags { get; private set; } = new TagsConfigurationItem(name: "Tags", charSet: "A-Za-z0-9\\-\\._~");
public ConfigurationData() public ConfigurationData()
{ {

View File

@ -9,7 +9,7 @@ namespace Jackett.Common.Models.IndexerConfig
public ConfigurationDataCookie(string instructionMessageOptional = null) public ConfigurationDataCookie(string instructionMessageOptional = null)
{ {
Cookie = new StringConfigurationItem("Cookie"); Cookie = new StringConfigurationItem("Cookie");
CookieInstructions = new DisplayInfoConfigurationItem("Cookie Instructions", CookieInstructions = new DisplayInfoConfigurationItem("Cookie Instructions",
"Please enter the cookie for the site manually. <a href=\"https://github.com/Jackett/Jackett/wiki/Finding-cookies\" target=\"_blank\">See here</a> on how get the cookies." + "Please enter the cookie for the site manually. <a href=\"https://github.com/Jackett/Jackett/wiki/Finding-cookies\" target=\"_blank\">See here</a> on how get the cookies." +
"<br>Example cookie header (usually longer than this):<br><code>PHPSESSID=8rk27odm; ipsconnect_63ad9c=1; more_stuff=etc;</code>"); "<br>Example cookie header (usually longer than this):<br><code>PHPSESSID=8rk27odm; ipsconnect_63ad9c=1; more_stuff=etc;</code>");
Instructions = new DisplayInfoConfigurationItem("", instructionMessageOptional); Instructions = new DisplayInfoConfigurationItem("", instructionMessageOptional);

View File

@ -83,7 +83,7 @@ namespace Jackett.Common.Models
Categories = new TorznabCapabilitiesCategories(); Categories = new TorznabCapabilitiesCategories();
} }
public void ParseCardigannSearchModes(Dictionary<string,List<string>> modes) public void ParseCardigannSearchModes(Dictionary<string, List<string>> modes)
{ {
if (modes == null || !modes.Any()) if (modes == null || !modes.Any())
throw new Exception("At least one search mode is required"); throw new Exception("At least one search mode is required");
@ -148,7 +148,7 @@ namespace Jackett.Common.Models
foreach (var paramStr in paramsList) foreach (var paramStr in paramsList)
if (Enum.TryParse(paramStr, true, out MusicSearchParam param)) if (Enum.TryParse(paramStr, true, out MusicSearchParam param))
if (!MusicSearchParams.Contains(param)) if (!MusicSearchParams.Contains(param))
MusicSearchParams.Add(param); MusicSearchParams.Add(param);
else else
throw new Exception($"Duplicate music-search param: {paramStr}"); throw new Exception($"Duplicate music-search param: {paramStr}");
else else

View File

@ -262,7 +262,7 @@ namespace Jackett.Common.Models
BooksOther, BooksOther,
BooksForeign BooksForeign
}); });
Other.SubCategories.AddRange(new List<TorznabCategory> {OtherMisc, OtherHashed}); Other.SubCategories.AddRange(new List<TorznabCategory> { OtherMisc, OtherHashed });
} }
public static string GetCatDesc(int torznabCatId) => public static string GetCatDesc(int torznabCatId) =>

View File

@ -48,7 +48,7 @@ namespace Jackett.Common.Services
{ {
// do not cache test queries! // do not cache test queries!
if (query.IsTest) if (query.IsTest)
return; return;
lock (_cache) lock (_cache)
{ {
@ -72,7 +72,7 @@ namespace Jackett.Common.Services
var trackerCache = _cache[indexer.Id]; var trackerCache = _cache[indexer.Id];
var queryHash = GetQueryHash(query); var queryHash = GetQueryHash(query);
if (trackerCache.Queries.ContainsKey(queryHash)) if (trackerCache.Queries.ContainsKey(queryHash))
trackerCache.Queries[queryHash] = trackerCacheQuery; // should not happen, just in case trackerCache.Queries[queryHash] = trackerCacheQuery; // should not happen, just in case
else else
trackerCache.Queries.Add(queryHash, trackerCacheQuery); trackerCache.Queries.Add(queryHash, trackerCacheQuery);
@ -94,7 +94,7 @@ namespace Jackett.Common.Services
if (!_cache.ContainsKey(indexer.Id)) if (!_cache.ContainsKey(indexer.Id))
return null; return null;
var trackerCache = _cache[indexer.Id]; var trackerCache = _cache[indexer.Id];
var queryHash = GetQueryHash(query); var queryHash = GetQueryHash(query);
var cacheHit = trackerCache.Queries.ContainsKey(queryHash); var cacheHit = trackerCache.Queries.ContainsKey(queryHash);
@ -184,7 +184,7 @@ namespace Jackett.Common.Services
// remove cached results just in case user disabled cache recently // remove cached results just in case user disabled cache recently
_cache.Clear(); _cache.Clear();
_logger.Debug("CACHE IsCacheEnabled => false"); _logger.Debug("CACHE IsCacheEnabled => false");
} }
return _serverConfig.CacheEnabled; return _serverConfig.CacheEnabled;
} }

View File

@ -91,7 +91,7 @@ namespace Jackett.Common.Services
{ {
// In cases where the app data folder is the same as "$(cwd)/Jackett" we don't need to perform a migration // In cases where the app data folder is the same as "$(cwd)/Jackett" we don't need to perform a migration
var fullConfigPath = Path.GetFullPath("Jackett"); var fullConfigPath = Path.GetFullPath("Jackett");
if (GetAppDataFolder() != fullConfigPath && ! File.Exists(Path.Combine(fullConfigPath, "jackett"))) if (GetAppDataFolder() != fullConfigPath && !File.Exists(Path.Combine(fullConfigPath, "jackett")))
{ {
PerformMigration(fullConfigPath); PerformMigration(fullConfigPath);
} }
@ -135,7 +135,8 @@ namespace Jackett.Common.Services
} }
// Don't remove configs that have been migrated to the same folder // Don't remove configs that have been migrated to the same folder
if (GetAppDataFolder() != oldDirectory) { if (GetAppDataFolder() != oldDirectory)
{
Directory.Delete(oldDirectory, true); Directory.Delete(oldDirectory, true);
} }
} }

View File

@ -125,7 +125,7 @@ namespace Jackett.Common.Services
var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer"); var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer");
var nativeIndexers = indexerTypes.Select(type => var nativeIndexers = indexerTypes.Select(type =>
{ {
var constructorArgumentTypes = new [] { typeof(IIndexerConfigurationService), typeof(WebClient), typeof(Logger), typeof(IProtectionService), typeof(ICacheService) }; var constructorArgumentTypes = new[] { typeof(IIndexerConfigurationService), typeof(WebClient), typeof(Logger), typeof(IProtectionService), typeof(ICacheService) };
var constructor = type.GetConstructor(constructorArgumentTypes); var constructor = type.GetConstructor(constructorArgumentTypes);
if (constructor != null) if (constructor != null)
{ {
@ -238,7 +238,7 @@ namespace Jackett.Common.Services
.Concat( .Concat(
indexers.Values.SelectMany(x => x.Tags).Distinct() indexers.Values.SelectMany(x => x.Tags).Distinct()
.Select(tag => (filter: FilterFunc.Tag.ToFilter(tag), func: FilterFunc.Tag.ToFunc(tag))) .Select(tag => (filter: FilterFunc.Tag.ToFilter(tag), func: FilterFunc.Tag.ToFunc(tag)))
).Select(x => new KeyValuePair<string, IWebIndexer>(x.filter, CreateFilterIndexer(x.filter, x.func))); ).Select(x => new KeyValuePair<string, IWebIndexer>(x.filter, CreateFilterIndexer(x.filter, x.func)));
availableFilters = new ConcurrentDictionary<string, IWebIndexer>(predefinedFilters); availableFilters = new ConcurrentDictionary<string, IWebIndexer>(predefinedFilters);
} }
@ -335,9 +335,9 @@ namespace Jackett.Common.Services
cacheService, cacheService,
filterFunc filterFunc
) )
{ {
Indexers = indexers.Values Indexers = indexers.Values
}; };
} }
private (IFallbackStrategyProvider fallbackStrategyProvider, IResultFilterProvider resultFilterProvider) private (IFallbackStrategyProvider fallbackStrategyProvider, IResultFilterProvider resultFilterProvider)

View File

@ -39,7 +39,7 @@ namespace Jackett.Common.Utils.Clients
trustedCertificates.TryGetValue(hash, out var hosts); trustedCertificates.TryGetValue(hash, out var hosts);
if (hosts != null && hosts.Contains(request.Host)) if (hosts != null && hosts.Contains(request.Host))
return true; return true;
// Throw exception with certificate details, this will cause a "Exception User-Unhandled" when running it in the Visual Studio debugger. // Throw exception with certificate details, this will cause a "Exception User-Unhandled" when running it in the Visual Studio debugger.
// The certificate is only available inside this function, so we can't catch it at the calling method. // The certificate is only available inside this function, so we can't catch it at the calling method.

View File

@ -42,7 +42,7 @@ namespace Jackett.Common.Utils.Clients
trustedCertificates.TryGetValue(hash, out var hosts); trustedCertificates.TryGetValue(hash, out var hosts);
if (hosts != null && hosts.Contains(request.RequestUri.Host)) if (hosts != null && hosts.Contains(request.RequestUri.Host))
return true; return true;
// Throw exception with certificate details, this will cause a "Exception User-Unhandled" when running it in the Visual Studio debugger. // Throw exception with certificate details, this will cause a "Exception User-Unhandled" when running it in the Visual Studio debugger.
// The certificate is only available inside this function, so we can't catch it at the calling method. // The certificate is only available inside this function, so we can't catch it at the calling method.

View File

@ -60,7 +60,7 @@ namespace Jackett.Common.Utils.Clients
{ {
// in case of error in DNS resolution, we use a fake proxy to avoid leaking the user IP (disabling proxy) // in case of error in DNS resolution, we use a fake proxy to avoid leaking the user IP (disabling proxy)
// https://github.com/Jackett/Jackett/issues/8826 // https://github.com/Jackett/Jackett/issues/8826
var addresses = new [] { new IPAddress(2130706433) }; // 127.0.0.1 var addresses = new[] { new IPAddress(2130706433) }; // 127.0.0.1
try try
{ {
addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result; addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result;

View File

@ -10,8 +10,8 @@ namespace Jackett.Common.Utils
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
// NOTE: we are not checking non-ascii characters and we should // NOTE: we are not checking non-ascii characters and we should
private static readonly Regex _CookieRegex = new Regex(@"([^\(\)<>@,;:\\""/\[\]\?=\{\}\s]+)=([^,;\\""\s]+)"); private static readonly Regex _CookieRegex = new Regex(@"([^\(\)<>@,;:\\""/\[\]\?=\{\}\s]+)=([^,;\\""\s]+)");
private static readonly char[] InvalidKeyChars = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t', '\n'}; private static readonly char[] InvalidKeyChars = { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t', '\n' };
private static readonly char[] InvalidValueChars = {'"', ',', ';', '\\', ' ', '\t', '\n'}; private static readonly char[] InvalidValueChars = { '"', ',', ';', '\\', ' ', '\t', '\n' };
public static Dictionary<string, string> CookieHeaderToDictionary(string cookieHeader) public static Dictionary<string, string> CookieHeaderToDictionary(string cookieHeader)
{ {

View File

@ -99,7 +99,7 @@ namespace Jackett.Common.Utils
throw new Exception("FromFuzzyTime parsing failed"); throw new Exception("FromFuzzyTime parsing failed");
} }
private static DateTime FromFuzzyPastTime(string str, string format, DateTime now) private static DateTime FromFuzzyPastTime(string str, string format, DateTime now)
{ {
var result = FromFuzzyTime(str, format); var result = FromFuzzyTime(str, format);

View File

@ -24,7 +24,7 @@ namespace Jackett.Common.Utils.FilterFuncs
if (string.IsNullOrWhiteSpace(source)) if (string.IsNullOrWhiteSpace(source))
return null; return null;
var parts = source.Split(new []{Separator}, 2); var parts = source.Split(new[] { Separator }, 2);
if (parts.Length != 2) if (parts.Length != 2)
return null; return null;
if (!string.Equals(parts[0], ID, StringComparison.InvariantCultureIgnoreCase)) if (!string.Equals(parts[0], ID, StringComparison.InvariantCultureIgnoreCase))

View File

@ -37,7 +37,7 @@ namespace Jackett.Common.Utils.FilterFuncs
return Not(FromFilter(source.Substring(1))); return Not(FromFilter(source.Substring(1)));
if (source.Contains(Separator)) if (source.Contains(Separator))
{ {
var parts = source.Split(new[] {Separator}, 2); var parts = source.Split(new[] { Separator }, 2);
if (parts.Length == 2 && components.TryGetValue(parts[0], out var toFunc)) if (parts.Length == 2 && components.TryGetValue(parts[0], out var toFunc))
return toFunc(parts[1]); return toFunc(parts[1]);
} }

View File

@ -23,7 +23,7 @@ namespace Jackett.Common.Utils
{"tr", "udp://open.stealth.si:80/announce"} {"tr", "udp://open.stealth.si:80/announce"}
}; };
private static readonly string _TrackersEncoded = _Trackers.GetQueryString(null,true); private static readonly string _TrackersEncoded = _Trackers.GetQueryString(null, true);
public static Uri InfoHashToPublicMagnet(string infoHash, string title) public static Uri InfoHashToPublicMagnet(string infoHash, string title)
{ {

View File

@ -83,7 +83,7 @@ namespace Jackett.Server.Controllers
[HttpPost] [HttpPost]
[Route("{indexerId?}/Config")] [Route("{indexerId?}/Config")]
[TypeFilter(typeof(RequiresIndexer))] [TypeFilter(typeof(RequiresIndexer))]
public async Task<IActionResult> UpdateConfig([FromBody]Common.Models.DTO.ConfigItem[] config) public async Task<IActionResult> UpdateConfig([FromBody] Common.Models.DTO.ConfigItem[] config)
{ {
// invalidate cache for this indexer // invalidate cache for this indexer
cacheService.CleanIndexerCache(CurrentIndexer); cacheService.CleanIndexerCache(CurrentIndexer);

View File

@ -139,7 +139,7 @@ namespace Jackett.Server.Controllers
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery)) if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
{ {
context.Result = ResultsController.GetErrorActionResult(context.RouteData, HttpStatusCode.BadRequest, 201, context.Result = ResultsController.GetErrorActionResult(context.RouteData, HttpStatusCode.BadRequest, 201,
$"{resultController.CurrentIndexer.Id} does not support the requested query. " + $"{resultController.CurrentIndexer.Id} does not support the requested query. " +
"Please check the capabilities (t=caps) and make sure the search mode and parameters are supported."); "Please check the capabilities (t=caps) and make sure the search mode and parameters are supported.");
@ -302,7 +302,7 @@ namespace Jackett.Server.Controllers
[Route("[action]/{ignored?}")] [Route("[action]/{ignored?}")]
[HttpGet] [HttpGet]
public async Task<IActionResult> Torznab([FromQuery]TorznabRequest request) public async Task<IActionResult> Torznab([FromQuery] TorznabRequest request)
{ {
if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase)) if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase))
{ {
@ -482,7 +482,7 @@ namespace Jackett.Server.Controllers
[Route("[action]/{ignored?}")] [Route("[action]/{ignored?}")]
[HttpGet] [HttpGet]
public async Task<TorrentPotatoResponse> Potato([FromQuery]TorrentPotatoRequest request) public async Task<TorrentPotatoResponse> Potato([FromQuery] TorrentPotatoRequest request)
{ {
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery); var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);

View File

@ -44,7 +44,7 @@ namespace Jackett.Server.Controllers
} }
[HttpPost] [HttpPost]
public IActionResult AdminPassword([FromBody]string password) public IActionResult AdminPassword([FromBody] string password)
{ {
var oldPassword = serverConfig.AdminPassword; var oldPassword = serverConfig.AdminPassword;
if (string.IsNullOrEmpty(password)) if (string.IsNullOrEmpty(password))
@ -71,7 +71,7 @@ namespace Jackett.Server.Controllers
[ActionName("Config")] [ActionName("Config")]
[HttpPost] [HttpPost]
public IActionResult UpdateConfig([FromBody]Common.Models.DTO.ServerConfig config) public IActionResult UpdateConfig([FromBody] Common.Models.DTO.ServerConfig config)
{ {
var webHostRestartNeeded = false; var webHostRestartNeeded = false;

View File

@ -11,7 +11,7 @@ using NLog;
namespace Jackett.Server.Services namespace Jackett.Server.Services
{ {
// This code is Windows specific but we are already doing the checks our way // This code is Windows specific but we are already doing the checks our way
#pragma warning disable CA1416 #pragma warning disable CA1416
public class ServiceConfigService : IServiceConfigService public class ServiceConfigService : IServiceConfigService
{ {

View File

@ -17,7 +17,7 @@ namespace Jackett.Test.Common.Helpers
//https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider?view=netcore-2.0 //https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider?view=netcore-2.0
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_codePagesToTest = new []{ _codePagesToTest = new[]{
Encoding.UTF8, Encoding.UTF8,
Encoding.ASCII, Encoding.ASCII,
Encoding.GetEncoding("iso-8859-1"), Encoding.GetEncoding("iso-8859-1"),
@ -26,7 +26,7 @@ namespace Jackett.Test.Common.Helpers
Encoding.GetEncoding("windows-1251") } Encoding.GetEncoding("windows-1251") }
; ;
_stringsToTest = new [] _stringsToTest = new[]
{ {
"Test! אני לא יודע עברית, אבל אני מאמין שזה טקסט חוקי! $ # 2 אני תוהה אם אמוג'י יהיה נתמך 🐀.", "Test! אני לא יודע עברית, אבל אני מאמין שזה טקסט חוקי! $ # 2 אני תוהה אם אמוג'י יהיה נתמך 🐀.",
"Å[ÉfÉBÉìÉOÇÕìÔǵÇ≠ǻǢ", "Å[ÉfÉBÉìÉOÇÕìÔǵÇ≠ǻǢ",

View File

@ -74,7 +74,7 @@ namespace Jackett.Test.Common.Indexers
query = new TorznabQuery // with child category query = new TorznabQuery // with child category
{ {
Categories = new [] { TorznabCatType.MoviesSD.ID } Categories = new[] { TorznabCatType.MoviesSD.ID }
}; };
filteredResults = indexer._FilterResults(query, results).ToList(); filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(2, filteredResults.Count); Assert.AreEqual(2, filteredResults.Count);
@ -83,7 +83,7 @@ namespace Jackett.Test.Common.Indexers
query = new TorznabQuery // with parent category query = new TorznabQuery // with parent category
{ {
Categories = new [] { TorznabCatType.Movies.ID } Categories = new[] { TorznabCatType.Movies.ID }
}; };
filteredResults = indexer._FilterResults(query, results).ToList(); filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(3, filteredResults.Count); Assert.AreEqual(3, filteredResults.Count);
@ -93,7 +93,7 @@ namespace Jackett.Test.Common.Indexers
query = new TorznabQuery // with custom category query = new TorznabQuery // with custom category
{ {
Categories = new [] { 100004 } Categories = new[] { 100004 }
}; };
filteredResults = indexer._FilterResults(query, results).ToList(); filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(2, filteredResults.Count); Assert.AreEqual(2, filteredResults.Count);
@ -207,7 +207,7 @@ namespace Jackett.Test.Common.Indexers
{ {
var indexer = new TestWebIndexer(); var indexer = new TestWebIndexer();
indexer._AddMultiCategoryMapping(TorznabCatType.MoviesHD,19, 18); indexer._AddMultiCategoryMapping(TorznabCatType.MoviesHD, 19, 18);
Assert.AreEqual(1, indexer.TorznabCaps.Categories.GetTorznabCategoryTree().Count); Assert.AreEqual(1, indexer.TorznabCaps.Categories.GetTorznabCategoryTree().Count);
} }
@ -220,7 +220,7 @@ namespace Jackett.Test.Common.Indexers
// you can find more complex tests in TorznabCapabilitiesCategoriesTests.cs // you can find more complex tests in TorznabCapabilitiesCategoriesTests.cs
var query = new TorznabQuery // int category with subcategories (parent cat) var query = new TorznabQuery // int category with subcategories (parent cat)
{ {
Categories = new [] { TorznabCatType.Movies.ID } Categories = new[] { TorznabCatType.Movies.ID }
}; };
var trackerCats = indexer._MapTorznabCapsToTrackers(query); var trackerCats = indexer._MapTorznabCapsToTrackers(query);
Assert.AreEqual(2, trackerCats.Count); Assert.AreEqual(2, trackerCats.Count);

View File

@ -15,7 +15,7 @@ namespace Jackett.Test.Common.Indexers
{ {
var definition = new IndexerDefinition // minimun indexer definition var definition = new IndexerDefinition // minimun indexer definition
{ {
Links = new List<string>{ "https://example.com" }, Links = new List<string> { "https://example.com" },
Caps = new capabilitiesBlock Caps = new capabilitiesBlock
{ {
Modes = new Dictionary<string, List<string>> Modes = new Dictionary<string, List<string>>
@ -53,7 +53,7 @@ namespace Jackett.Test.Common.Indexers
definition = new IndexerDefinition // test categories (same as in C# indexer) definition = new IndexerDefinition // test categories (same as in C# indexer)
{ {
Links = new List<string>{ "https://example.com" }, Links = new List<string> { "https://example.com" },
Caps = new capabilitiesBlock Caps = new capabilitiesBlock
{ {
Modes = new Dictionary<string, List<string>> Modes = new Dictionary<string, List<string>>
@ -110,7 +110,7 @@ namespace Jackett.Test.Common.Indexers
definition = new IndexerDefinition // test search modes definition = new IndexerDefinition // test search modes
{ {
Links = new List<string>{ "https://example.com" }, Links = new List<string> { "https://example.com" },
Caps = new capabilitiesBlock Caps = new capabilitiesBlock
{ {
Modes = new Dictionary<string, List<string>> Modes = new Dictionary<string, List<string>>

View File

@ -27,7 +27,7 @@ namespace Jackett.Test.Common.Indexers
yield return new TestCaseData("[1080p] Tokyo Revengers 02").Returns("[1080p] Tokyo Revengers E02"); yield return new TestCaseData("[1080p] Tokyo Revengers 02").Returns("[1080p] Tokyo Revengers E02");
yield return new TestCaseData("[1080p] Mairimashita! Iruma-kun 2nd Season 01").Returns("[1080p] Mairimashita! Iruma-kun S2E01"); yield return new TestCaseData("[1080p] Mairimashita! Iruma-kun 2nd Season 01").Returns("[1080p] Mairimashita! Iruma-kun S2E01");
yield return new TestCaseData("[540p] Seijo no Maryoku wa Bannou Desu 02 v2 (Multi)").Returns("[540p] Seijo no Maryoku wa Bannou Desu E02 v2 (Multi)"); yield return new TestCaseData("[540p] Seijo no Maryoku wa Bannou Desu 02 v2 (Multi)").Returns("[540p] Seijo no Maryoku wa Bannou Desu E02 v2 (Multi)");
yield return new TestCaseData("[1080p] Yuukoku no Moriarty Part 2 01 (Multi)").Returns("[1080p] Yuukoku no Moriarty S2E01 (Multi)"); yield return new TestCaseData("[1080p] Yuukoku no Moriarty Part 2 01 (Multi)").Returns("[1080p] Yuukoku no Moriarty S2E01 (Multi)");
} }
} }
} }

View File

@ -50,8 +50,8 @@ namespace Jackett.Test.Common.Models
{ {
Link = link Link = link
}) })
{ {
Releases = new List<ReleaseInfo> Releases = new List<ReleaseInfo>
{ {
new ReleaseInfo // these fields are from websites and they can be problematic new ReleaseInfo // these fields are from websites and they can be problematic
{ {
@ -69,7 +69,7 @@ namespace Jackett.Test.Common.Models
Origin = new TestIndexer() Origin = new TestIndexer()
} }
} }
}; };
var xml = resultPage.ToXml(link); var xml = resultPage.ToXml(link);
Assert.AreEqual(5, Regex.Matches(xml, validText).Count); Assert.AreEqual(5, Regex.Matches(xml, validText).Count);

View File

@ -196,7 +196,7 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // int category with subcategories (parent cat) query = new TorznabQuery // int category with subcategories (parent cat)
{ {
Categories = new [] { TorznabCatType.Movies.ID } Categories = new[] { TorznabCatType.Movies.ID }
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(2, trackerCats.Count); Assert.AreEqual(2, trackerCats.Count);
@ -205,7 +205,7 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // string child category query = new TorznabQuery // string child category
{ {
Categories = new [] { TorznabCatType.MoviesSD.ID } Categories = new[] { TorznabCatType.MoviesSD.ID }
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(1, trackerCats.Count); Assert.AreEqual(1, trackerCats.Count);
@ -217,7 +217,7 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // duplicate category (1 torznab cat => 2 indexer cats) query = new TorznabQuery // duplicate category (1 torznab cat => 2 indexer cats)
{ {
Categories = new [] { TorznabCatType.ConsoleXBox.ID } Categories = new[] { TorznabCatType.ConsoleXBox.ID }
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(2, trackerCats.Count); Assert.AreEqual(2, trackerCats.Count);
@ -226,7 +226,7 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // custom cat "integer" query = new TorznabQuery // custom cat "integer"
{ {
Categories = new [] { 100044 } // Console/Xbox_c Categories = new[] { 100044 } // Console/Xbox_c
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(1, trackerCats.Count); Assert.AreEqual(1, trackerCats.Count);
@ -234,7 +234,7 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // custom cat "string" query = new TorznabQuery // custom cat "string"
{ {
Categories = new [] { 137107 } // Console/Wii_c Categories = new[] { 137107 } // Console/Wii_c
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(1, trackerCats.Count); Assert.AreEqual(1, trackerCats.Count);
@ -242,14 +242,14 @@ namespace Jackett.Test.Common.Models
query = new TorznabQuery // unknown category query = new TorznabQuery // unknown category
{ {
Categories = new [] { 9999 } Categories = new[] { 9999 }
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(0, trackerCats.Count); Assert.AreEqual(0, trackerCats.Count);
query = new TorznabQuery // unknown custom cat query = new TorznabQuery // unknown custom cat
{ {
Categories = new [] { 100001 } Categories = new[] { 100001 }
}; };
trackerCats = tcc.MapTorznabCapsToTrackers(query); trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(0, trackerCats.Count); Assert.AreEqual(0, trackerCats.Count);
@ -270,7 +270,7 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(2030, torznabCats[0]); Assert.AreEqual(2030, torznabCats[0]);
// "integer" id with custom cats. 44 and 40 maps to ConsoleXbox but different custom cat // "integer" id with custom cats. 44 and 40 maps to ConsoleXbox but different custom cat
torznabCats = tcc.MapTrackerCatToNewznab("44").ToList(); torznabCats = tcc.MapTrackerCatToNewznab("44").ToList();
Assert.AreEqual(2, torznabCats.Count); Assert.AreEqual(2, torznabCats.Count);
Assert.AreEqual(1040, torznabCats[0]); Assert.AreEqual(1040, torznabCats[0]);
Assert.AreEqual(100044, torznabCats[1]); Assert.AreEqual(100044, torznabCats[1]);
@ -280,7 +280,7 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(100040, torznabCats[1]); Assert.AreEqual(100040, torznabCats[1]);
// "string" id with custom cats // "string" id with custom cats
torznabCats = tcc.MapTrackerCatToNewznab("con_wii").ToList(); torznabCats = tcc.MapTrackerCatToNewznab("con_wii").ToList();
Assert.AreEqual(2, torznabCats.Count); Assert.AreEqual(2, torznabCats.Count);
Assert.AreEqual(1030, torznabCats[0]); Assert.AreEqual(1030, torznabCats[0]);
Assert.AreEqual(137107, torznabCats[1]); Assert.AreEqual(137107, torznabCats[1]);
@ -330,25 +330,25 @@ namespace Jackett.Test.Common.Models
{ {
var tcc = CreateTestDataset(); var tcc = CreateTestDataset();
Assert.AreEqual( new[] { TorznabCatType.Movies.ID }, // parent cat Assert.AreEqual(new[] { TorznabCatType.Movies.ID }, // parent cat
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID })); tcc.SupportedCategories(new[] { TorznabCatType.Movies.ID }));
Assert.AreEqual( new[] { TorznabCatType.MoviesSD.ID }, // child cat Assert.AreEqual(new[] { TorznabCatType.MoviesSD.ID }, // child cat
tcc.SupportedCategories(new []{ TorznabCatType.MoviesSD.ID })); tcc.SupportedCategories(new[] { TorznabCatType.MoviesSD.ID }));
Assert.AreEqual( new[] { TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID }, // parent & child cat Assert.AreEqual(new[] { TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID }, // parent & child cat
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID })); tcc.SupportedCategories(new[] { TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID }));
Assert.AreEqual( new[] { 100040 }, // custom cat Assert.AreEqual(new[] { 100040 }, // custom cat
tcc.SupportedCategories(new []{ 100040 })); tcc.SupportedCategories(new[] { 100040 }));
Assert.AreEqual( new[] { TorznabCatType.Movies.ID }, // mixed good and bad Assert.AreEqual(new[] { TorznabCatType.Movies.ID }, // mixed good and bad
tcc.SupportedCategories(new []{ TorznabCatType.Movies.ID, 9999 })); tcc.SupportedCategories(new[] { TorznabCatType.Movies.ID, 9999 }));
Assert.AreEqual( new int[] {}, // not supported child cat Assert.AreEqual(new int[] { }, // not supported child cat
tcc.SupportedCategories(new []{ TorznabCatType.Movies3D.ID })); tcc.SupportedCategories(new[] { TorznabCatType.Movies3D.ID }));
Assert.AreEqual( new int[] {}, // unknown cat Assert.AreEqual(new int[] { }, // unknown cat
tcc.SupportedCategories(new []{ 9999 })); tcc.SupportedCategories(new[] { 9999 }));
Assert.AreEqual( new int[] {}, // unknown custom cat Assert.AreEqual(new int[] { }, // unknown custom cat
tcc.SupportedCategories(new []{ 100001 })); tcc.SupportedCategories(new[] { 100001 }));
Assert.AreEqual( new int[]{}, // empty list Assert.AreEqual(new int[] { }, // empty list
tcc.SupportedCategories(new int[]{})); tcc.SupportedCategories(new int[] { }));
Assert.AreEqual( new int[] {}, // null Assert.AreEqual(new int[] { }, // null
tcc.SupportedCategories(null)); tcc.SupportedCategories(null));
} }

View File

@ -87,7 +87,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"bad", new List<string> {"q"}} // bad search mode {"bad", new List<string> {"q"}} // bad search mode
@ -100,7 +101,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string> {"bad"}} // search mode with bad parameters {"search", new List<string> {"bad"}} // search mode with bad parameters
@ -141,7 +143,8 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(new List<TvSearchParam> { TvSearchParam.Q, TvSearchParam.TvdbId }, torznabCaps.TvSearchParams); Assert.AreEqual(new List<TvSearchParam> { TvSearchParam.Q, TvSearchParam.TvdbId }, torznabCaps.TvSearchParams);
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -155,7 +158,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -197,7 +201,8 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(new List<MovieSearchParam> { MovieSearchParam.Q, MovieSearchParam.ImdbId }, torznabCaps.MovieSearchParams); Assert.AreEqual(new List<MovieSearchParam> { MovieSearchParam.Q, MovieSearchParam.ImdbId }, torznabCaps.MovieSearchParams);
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -211,7 +216,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -253,7 +259,8 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(new List<MusicSearchParam> { MusicSearchParam.Q, MusicSearchParam.Label }, torznabCaps.MusicSearchParams); Assert.AreEqual(new List<MusicSearchParam> { MusicSearchParam.Q, MusicSearchParam.Label }, torznabCaps.MusicSearchParams);
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -267,7 +274,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -309,7 +317,8 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(new List<BookSearchParam> { BookSearchParam.Q, BookSearchParam.Title }, torznabCaps.BookSearchParams); Assert.AreEqual(new List<BookSearchParam> { BookSearchParam.Q, BookSearchParam.Title }, torznabCaps.BookSearchParams);
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -323,7 +332,8 @@ namespace Jackett.Test.Common.Models
} }
torznabCaps = new TorznabCapabilities(); torznabCaps = new TorznabCapabilities();
try { try
{
torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>> torznabCaps.ParseCardigannSearchModes(new Dictionary<string, List<string>>
{ {
{"search", new List<string>{"q"}}, {"search", new List<string>{"q"}},
@ -406,7 +416,7 @@ namespace Jackett.Test.Common.Models
// test categories // test categories
torznabCaps = new TorznabCapabilities(); // child category torznabCaps = new TorznabCapabilities(); // child category
torznabCaps.Categories.AddCategoryMapping("c1", TorznabCatType.MoviesSD); torznabCaps.Categories.AddCategoryMapping("c1", TorznabCatType.MoviesSD);
xDocument = torznabCaps.GetXDocument(); xDocument = torznabCaps.GetXDocument();
var xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList(); var xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
Assert.AreEqual(1, xDocumentCategories?.Count); Assert.AreEqual(1, xDocumentCategories?.Count);
@ -418,7 +428,7 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentSubCategories?[0].Attribute("name")?.Value); Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentSubCategories?[0].Attribute("name")?.Value);
torznabCaps = new TorznabCapabilities(); // parent (with description generates a custom cat) and child category torznabCaps = new TorznabCapabilities(); // parent (with description generates a custom cat) and child category
torznabCaps.Categories.AddCategoryMapping("1", TorznabCatType.Movies, "Classic Movies"); torznabCaps.Categories.AddCategoryMapping("1", TorznabCatType.Movies, "Classic Movies");
torznabCaps.Categories.AddCategoryMapping("c2", TorznabCatType.MoviesSD); torznabCaps.Categories.AddCategoryMapping("c2", TorznabCatType.MoviesSD);
xDocument = torznabCaps.GetXDocument(); xDocument = torznabCaps.GetXDocument();
xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList(); xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
@ -474,20 +484,20 @@ namespace Jackett.Test.Common.Models
torznabCaps1 = new TorznabCapabilities torznabCaps1 = new TorznabCapabilities
{ {
SearchAvailable = false, SearchAvailable = false,
TvSearchParams = new List<TvSearchParam> {TvSearchParam.Q}, TvSearchParams = new List<TvSearchParam> { TvSearchParam.Q },
MovieSearchParams = new List<MovieSearchParam> {MovieSearchParam.Q}, MovieSearchParams = new List<MovieSearchParam> { MovieSearchParam.Q },
MusicSearchParams = new List<MusicSearchParam> {MusicSearchParam.Q}, MusicSearchParams = new List<MusicSearchParam> { MusicSearchParam.Q },
BookSearchParams = new List<BookSearchParam> {BookSearchParam.Q} BookSearchParams = new List<BookSearchParam> { BookSearchParam.Q }
}; };
torznabCaps1.Categories.AddCategoryMapping("1", TorznabCatType.Movies); torznabCaps1.Categories.AddCategoryMapping("1", TorznabCatType.Movies);
torznabCaps1.Categories.AddCategoryMapping("c1", new TorznabCategory(100001, "CustomCat1")); torznabCaps1.Categories.AddCategoryMapping("c1", new TorznabCategory(100001, "CustomCat1"));
torznabCaps2 = new TorznabCapabilities torznabCaps2 = new TorznabCapabilities
{ {
SearchAvailable = false, SearchAvailable = false,
TvSearchParams = new List<TvSearchParam> {TvSearchParam.Season}, TvSearchParams = new List<TvSearchParam> { TvSearchParam.Season },
MovieSearchParams = new List<MovieSearchParam> {MovieSearchParam.ImdbId}, MovieSearchParams = new List<MovieSearchParam> { MovieSearchParam.ImdbId },
MusicSearchParams = new List<MusicSearchParam> {MusicSearchParam.Artist}, MusicSearchParams = new List<MusicSearchParam> { MusicSearchParam.Artist },
BookSearchParams = new List<BookSearchParam> {BookSearchParam.Title} BookSearchParams = new List<BookSearchParam> { BookSearchParam.Title }
}; };
torznabCaps2.Categories.AddCategoryMapping("2", TorznabCatType.TVAnime); torznabCaps2.Categories.AddCategoryMapping("2", TorznabCatType.TVAnime);
torznabCaps2.Categories.AddCategoryMapping("c2", new TorznabCategory(100002, "CustomCat2")); torznabCaps2.Categories.AddCategoryMapping("c2", new TorznabCategory(100002, "CustomCat2"));

View File

@ -44,7 +44,7 @@ namespace Jackett.Test.Common.Utils
{ {
// malformed cookies // malformed cookies
var cookieHeader = "__cfduidd6237f041586694295; __cf_;bm TlOng; good_cookie=value"; var cookieHeader = "__cfduidd6237f041586694295; __cf_;bm TlOng; good_cookie=value";
var expectedCookieDictionary = new Dictionary<string, string> {{"good_cookie", "value"},}; var expectedCookieDictionary = new Dictionary<string, string> { { "good_cookie", "value" }, };
CollectionAssert.AreEqual(expectedCookieDictionary, CookieUtil.CookieHeaderToDictionary(cookieHeader)); CollectionAssert.AreEqual(expectedCookieDictionary, CookieUtil.CookieHeaderToDictionary(cookieHeader));
} }
@ -78,7 +78,7 @@ namespace Jackett.Test.Common.Utils
{"__cf_=bm", "34234234"} {"__cf_=bm", "34234234"}
}; };
var ex = Assert.Throws<FormatException>(() => CookieUtil.CookieDictionaryToHeader(cookieDictionary)); var ex = Assert.Throws<FormatException>(() => CookieUtil.CookieDictionaryToHeader(cookieDictionary));
Assert.AreEqual( "The cookie '__cf_=bm=34234234' is malformed.", ex.Message); Assert.AreEqual("The cookie '__cf_=bm=34234234' is malformed.", ex.Message);
} }
[Test] [Test]
@ -90,7 +90,7 @@ namespace Jackett.Test.Common.Utils
{"__cf_bm", "34234 234"} {"__cf_bm", "34234 234"}
}; };
var ex = Assert.Throws<FormatException>(() => CookieUtil.CookieDictionaryToHeader(cookieDictionary)); var ex = Assert.Throws<FormatException>(() => CookieUtil.CookieDictionaryToHeader(cookieDictionary));
Assert.AreEqual( "The cookie '__cf_bm=34234 234' is malformed.", ex.Message); Assert.AreEqual("The cookie '__cf_bm=34234 234' is malformed.", ex.Message);
} }
[Test] [Test]

View File

@ -63,11 +63,11 @@ namespace Jackett.Test.Common.Utils
// there are few tests because we are using a well known library // there are few tests because we are using a well known library
var now = DateTime.Now; var now = DateTime.Now;
Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 4, 20, 19, new TimeSpan(-4, -30, 0)).DateTime, Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 4, 20, 19, new TimeSpan(-4, -30, 0)).DateTime,
DateTimeUtil.FromFuzzyTime("21 Jun 2010 04:20:19 -0430 blah")); DateTimeUtil.FromFuzzyTime("21 Jun 2010 04:20:19 -0430 blah"));
Assert.AreEqual(new DateTime(2005, 6, 10, 10, 30, 0), Assert.AreEqual(new DateTime(2005, 6, 10, 10, 30, 0),
DateTimeUtil.FromFuzzyTime("June 10, 2005 10:30AM", "UK")); DateTimeUtil.FromFuzzyTime("June 10, 2005 10:30AM", "UK"));
Assert.AreEqual(new DateTime(now.Year, now.Month, now.Day, 19, 54, 0), Assert.AreEqual(new DateTime(now.Year, now.Month, now.Day, 19, 54, 0),
DateTimeUtil.FromFuzzyTime("today 19:54")); DateTimeUtil.FromFuzzyTime("today 19:54"));
Assert.True((now - DateTimeUtil.FromFuzzyTime("Yesterday at 10:20 pm")).TotalSeconds <= 3600 * 24); // 1 day Assert.True((now - DateTimeUtil.FromFuzzyTime("Yesterday at 10:20 pm")).TotalSeconds <= 3600 * 24); // 1 day
Assert.True((now - DateTimeUtil.FromFuzzyTime("Sunday at 14:30")).TotalSeconds <= 3600 * 24 * 7); // 1 week Assert.True((now - DateTimeUtil.FromFuzzyTime("Sunday at 14:30")).TotalSeconds <= 3600 * 24 * 7); // 1 week
@ -118,7 +118,7 @@ namespace Jackett.Test.Common.Utils
Assert.True((now - DateTimeUtil.FromUnknown("Saturday at 00:20", relativeFrom: now)).TotalSeconds <= 3600 * 24 * 7); Assert.True((now - DateTimeUtil.FromUnknown("Saturday at 00:20", relativeFrom: now)).TotalSeconds <= 3600 * 24 * 7);
Assert.True((now - DateTimeUtil.FromUnknown("sunday at 22:00", relativeFrom: now)).TotalSeconds <= 3600 * 24 * 7); Assert.True((now - DateTimeUtil.FromUnknown("sunday at 22:00", relativeFrom: now)).TotalSeconds <= 3600 * 24 * 7);
Assert.AreEqual(new DateTime(2020, 10, 31, 3, 8, 27, DateTimeKind.Utc).ToLocalTime(), Assert.AreEqual(new DateTime(2020, 10, 31, 3, 8, 27, DateTimeKind.Utc).ToLocalTime(),
DateTimeUtil.FromUnknown("1604113707", relativeFrom: now)); DateTimeUtil.FromUnknown("1604113707", relativeFrom: now));
var refDate = new DateTime(2021, 03, 12, 12, 00, 00, DateTimeKind.Local); var refDate = new DateTime(2021, 03, 12, 12, 00, 00, DateTimeKind.Local);
@ -153,13 +153,13 @@ namespace Jackett.Test.Common.Utils
{ {
var now = DateTime.Now; var now = DateTime.Now;
Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 4, 20, 19, new TimeSpan(-4, 0, 0)).ToLocalTime().DateTime, Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 4, 20, 19, new TimeSpan(-4, 0, 0)).ToLocalTime().DateTime,
DateTimeUtil.ParseDateTimeGoLang("21-06-2010 04:20:19 -04:00", "02-01-2006 15:04:05 -07:00")); DateTimeUtil.ParseDateTimeGoLang("21-06-2010 04:20:19 -04:00", "02-01-2006 15:04:05 -07:00"));
Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 0, 0, 0, new TimeSpan(-5, -30, 0)).ToLocalTime().DateTime, Assert.AreEqual(new DateTimeOffset(2010, 6, 21, 0, 0, 0, new TimeSpan(-5, -30, 0)).ToLocalTime().DateTime,
DateTimeUtil.ParseDateTimeGoLang("2010-06-21 -05:30", "2006-01-02 -07:00")); DateTimeUtil.ParseDateTimeGoLang("2010-06-21 -05:30", "2006-01-02 -07:00"));
var refDate = new DateTime(2021, 03, 12, 12, 00, 00, DateTimeKind.Local); var refDate = new DateTime(2021, 03, 12, 12, 00, 00, DateTimeKind.Local);
Assert.AreEqual(new DateTime(refDate.Year - 1, 9, 14, 7, 0, 0), Assert.AreEqual(new DateTime(refDate.Year - 1, 9, 14, 7, 0, 0),
DateTimeUtil.ParseDateTimeGoLang("7am Sep. 14", "3pm Jan. 2", relativeFrom:refDate)); DateTimeUtil.ParseDateTimeGoLang("7am Sep. 14", "3pm Jan. 2", relativeFrom: refDate));
// bad cases // bad cases
try try

View File

@ -13,7 +13,7 @@ namespace Jackett.Test.Common.Utils
[Test] [Test]
public void GetQueryStringTests() public void GetQueryStringTests()
{ {
#region Encoding Tests #region Encoding Tests
//Add windows-1251 to Encoding list if not present //Add windows-1251 to Encoding list if not present
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@ -41,9 +41,9 @@ namespace Jackett.Test.Common.Utils
//Encoding should make values websafe, but not keys //Encoding should make values websafe, but not keys
StringAssert.Contains("space key=space+value", encodingNvc.GetQueryString()); StringAssert.Contains("space key=space+value", encodingNvc.GetQueryString());
#endregion #endregion
#region Separator Tests #region Separator Tests
var separatorNvc = new NameValueCollection var separatorNvc = new NameValueCollection
{ {
@ -62,9 +62,9 @@ namespace Jackett.Test.Common.Utils
Assert.AreEqual(noSeparator, separatorNvc.GetQueryString(separator: null)); Assert.AreEqual(noSeparator, separatorNvc.GetQueryString(separator: null));
Assert.AreEqual(noSeparator, separatorNvc.GetQueryString(separator: string.Empty)); Assert.AreEqual(noSeparator, separatorNvc.GetQueryString(separator: string.Empty));
#endregion #endregion
#region Split Keys Tests #region Split Keys Tests
var duplicateKeysNvc = new NameValueCollection var duplicateKeysNvc = new NameValueCollection
{ {
@ -84,9 +84,9 @@ namespace Jackett.Test.Common.Utils
Assert.AreEqual( Assert.AreEqual(
"key1=value&key1=duplicate&key2=value2", duplicateKeysNvc.GetQueryString(duplicateKeysIfMulti: true)); "key1=value&key1=duplicate&key2=value2", duplicateKeysNvc.GetQueryString(duplicateKeysIfMulti: true));
#endregion #endregion
#region Edge Case Tests #region Edge Case Tests
//Throws NullReferenceException if the NameValueCollection is null in all cases //Throws NullReferenceException if the NameValueCollection is null in all cases
Assert.Throws<NullReferenceException>(() => ((NameValueCollection)null).GetQueryString()); Assert.Throws<NullReferenceException>(() => ((NameValueCollection)null).GetQueryString());
@ -94,7 +94,7 @@ namespace Jackett.Test.Common.Utils
//Returns empty string on empty collection in all cases //Returns empty string on empty collection in all cases
Assert.AreEqual(string.Empty, new NameValueCollection().GetQueryString()); Assert.AreEqual(string.Empty, new NameValueCollection().GetQueryString());
#endregion #endregion
} }
[Test] [Test]

View File

@ -9,9 +9,9 @@ using Newtonsoft.Json.Linq;
namespace Jackett.Test.TestHelpers namespace Jackett.Test.TestHelpers
{ {
public class TestWebIndexer: BaseWebIndexer public class TestWebIndexer : BaseWebIndexer
{ {
public TestWebIndexer(): public TestWebIndexer() :
base(id: "test_id", base(id: "test_id",
name: "test_name", name: "test_name",
description: "test_description", description: "test_description",
@ -26,7 +26,7 @@ namespace Jackett.Test.TestHelpers
{ {
Encoding = Encoding.UTF8; Encoding = Encoding.UTF8;
Language = "en-us"; Language = "en-us";
Type = "private"; Type = "private";
} }
public override string[] AlternativeSiteLinks { get; protected set; } = { public override string[] AlternativeSiteLinks { get; protected set; } = {