mirror of
https://github.com/Jackett/Jackett.git
synced 2025-10-01 16:04:07 +02:00
fix(indexers): fixed wihd, added ssl support and misc things (#1666)
* docs(config): add warning on wihd config to use classic view only * refactor(wihd): refactor indexer, optimized dev mode, added freeleech and SSL * fix(indexers): removed T411 orginal tracker closed tracker by gov * refactor(clean): removed old orphan config files * docs(readme): updated for wihd
This commit is contained in:
@@ -227,7 +227,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Ultimate Gamer Club
|
||||
* ULTRAHDCLUB
|
||||
* Waffles
|
||||
* World-In-HD [![(invite needed)][inviteneeded]](#)
|
||||
* World-In-HD
|
||||
* WorldOfP2P
|
||||
* x264
|
||||
* XSpeeds
|
||||
|
@@ -1,278 +0,0 @@
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class T411 : BaseWebIndexer
|
||||
{
|
||||
const string ApiUrl = "https://api.t411.al";
|
||||
const string AuthUrl = ApiUrl + "/auth";
|
||||
const string SearchUrl = ApiUrl + "/torrents/search/";
|
||||
const string TermsUrl = ApiUrl + "/terms/tree";
|
||||
const string DownloadUrl = ApiUrl + "/torrents/download/";
|
||||
private string CommentsUrl { get { return SiteLink + "torrents/"; } }
|
||||
|
||||
new ConfigurationDataLoginTokin configData
|
||||
{
|
||||
get { return (ConfigurationDataLoginTokin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
private Dictionary<int, List<int>> _mediaCategoryMapping = new Dictionary<int, List<int>>();
|
||||
|
||||
public T411(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "T411",
|
||||
description: "French Torrent Tracker",
|
||||
link: "https://t411.al/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataLoginTokin())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
Type = "semi-private";
|
||||
Language = "fr-fr";
|
||||
|
||||
// 210, FilmVidéo
|
||||
AddCategoryMapping(210, 402, TorznabCatType.Movies, "Vidéoclips");
|
||||
AddCategoryMapping(210, 433, TorznabCatType.TV, "Série TV");
|
||||
AddCategoryMapping(210, 455, TorznabCatType.TVAnime, "Animation");
|
||||
AddCategoryMapping(210, 631, TorznabCatType.Movies, "Film");
|
||||
AddCategoryMapping(210, 633, TorznabCatType.Movies, "Concert");
|
||||
AddCategoryMapping(210, 634, TorznabCatType.TVDocumentary, "Documentaire");
|
||||
AddCategoryMapping(210, 635, TorznabCatType.TV, "Spectacle");
|
||||
AddCategoryMapping(210, 636, TorznabCatType.TVSport, "Sport");
|
||||
AddCategoryMapping(210, 637, TorznabCatType.TVAnime, "Animation Série");
|
||||
AddCategoryMapping(210, 639, TorznabCatType.TV, "Emission TV");
|
||||
|
||||
// 233, Application
|
||||
AddCategoryMapping(233, 234, TorznabCatType.PC, "Linux");
|
||||
AddCategoryMapping(233, 235, TorznabCatType.PCMac, "MacOS");
|
||||
AddCategoryMapping(233, 236, TorznabCatType.PC, "Windows");
|
||||
AddCategoryMapping(233, 625, TorznabCatType.PCPhoneOther, "Smartphone");
|
||||
AddCategoryMapping(233, 627, TorznabCatType.PCPhoneOther, "Tablette");
|
||||
AddCategoryMapping(233, 629, TorznabCatType.PC, "Autre");
|
||||
AddCategoryMapping(233, 638, TorznabCatType.PC, "Formation");
|
||||
|
||||
// 395, Audio
|
||||
AddCategoryMapping(395, 400, TorznabCatType.Audio, "Karaoke");
|
||||
AddCategoryMapping(395, 403, TorznabCatType.Audio, "Samples");
|
||||
AddCategoryMapping(395, 623, TorznabCatType.Audio, "Musique");
|
||||
AddCategoryMapping(395, 642, TorznabCatType.Audio, "Podcast Radio");
|
||||
|
||||
// 404, eBook
|
||||
AddCategoryMapping(404, 405, TorznabCatType.Books, "Audio");
|
||||
AddCategoryMapping(404, 406, TorznabCatType.Books, "Bds");
|
||||
AddCategoryMapping(404, 407, TorznabCatType.Books, "Comics");
|
||||
AddCategoryMapping(404, 408, TorznabCatType.Books, "Livres");
|
||||
AddCategoryMapping(404, 409, TorznabCatType.Books, "Mangas");
|
||||
AddCategoryMapping(404, 410, TorznabCatType.Books, "Presse");
|
||||
|
||||
// 456, xXx
|
||||
AddCategoryMapping(456, 461, TorznabCatType.XXX, "eBooks");
|
||||
AddCategoryMapping(456, 462, TorznabCatType.XXX, "Jeux vidéo");
|
||||
AddCategoryMapping(456, 632, TorznabCatType.XXX, "Video");
|
||||
AddCategoryMapping(456, 641, TorznabCatType.XXX, "Animation");
|
||||
|
||||
// 624, Jeu vidéo
|
||||
AddCategoryMapping(624, 239, TorznabCatType.PCGames, "Linux");
|
||||
AddCategoryMapping(624, 245, TorznabCatType.PCMac, "MacOS");
|
||||
AddCategoryMapping(624, 246, TorznabCatType.PCGames, "Windows");
|
||||
AddCategoryMapping(624, 307, TorznabCatType.ConsoleNDS, "Nintendo");
|
||||
AddCategoryMapping(624, 308, TorznabCatType.ConsolePS4, "Sony");
|
||||
AddCategoryMapping(624, 309, TorznabCatType.ConsoleXbox, "Microsoft");
|
||||
AddCategoryMapping(624, 626, TorznabCatType.PCPhoneOther, "Smartphone");
|
||||
AddCategoryMapping(624, 628, TorznabCatType.PCPhoneOther, "Tablette");
|
||||
AddCategoryMapping(624, 630, TorznabCatType.ConsoleOther, "Autre");
|
||||
}
|
||||
|
||||
private void AddCategoryMapping(int trackerMediaCategory, int trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
|
||||
{
|
||||
AddCategoryMapping(trackerCategory, newznabCategory, trackerCategoryDesc);
|
||||
if (!_mediaCategoryMapping.ContainsKey(trackerMediaCategory))
|
||||
_mediaCategoryMapping.Add(trackerMediaCategory, new List<int>());
|
||||
_mediaCategoryMapping[trackerMediaCategory].Add(trackerCategory);
|
||||
}
|
||||
|
||||
private KeyValuePair<int, List<int>> GetCategoryFromSubCat(int subCategory)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _mediaCategoryMapping.First(pair => pair.Value.Contains(subCategory));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new KeyValuePair<int, List<int>>(0, new List<int>() { 0 }); //If the provided category does not exist, we return 0 (ALL)
|
||||
}
|
||||
}
|
||||
|
||||
async Task<string> GetAuthToken(bool forceFetch = false)
|
||||
{
|
||||
if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
|
||||
{
|
||||
return configData.ApiToken.Value;
|
||||
}
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var response = await PostDataWithCookies(AuthUrl, pairs);
|
||||
var responseContent = response.Content;
|
||||
var jsonResponse = JObject.Parse(responseContent);
|
||||
if (jsonResponse["error"] != null)
|
||||
{
|
||||
throw new ApplicationException((string)jsonResponse["error"]);
|
||||
}
|
||||
configData.ApiToken.Value = (string)jsonResponse["token"];
|
||||
configData.LastTokenFetchDateTime = DateTime.Now;
|
||||
return configData.ApiToken.Value;
|
||||
}
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
Exception tokenFetchEx = null;
|
||||
try
|
||||
{
|
||||
await GetAuthToken(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
|
||||
}
|
||||
|
||||
await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
|
||||
{
|
||||
throw tokenFetchEx;
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
// API doesn't support getting the latest torrents, searching for the empty string will cause an error and all torrents returned
|
||||
var searchUrl = SearchUrl + HttpUtility.UrlEncode(query.SanitizedSearchTerm).Replace("+", "%20");
|
||||
searchUrl += "?offset=0&limit=200&cat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Key;
|
||||
|
||||
// handle special term search for tvsearch
|
||||
var queryStringOverride = query.SanitizedSearchTerm;
|
||||
switch (query.QueryType)
|
||||
{
|
||||
case "tvsearch":
|
||||
// T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
|
||||
// So here we take LastOrDefault from the category ids, so if the query specify an animation tv serie, we select the correct id.
|
||||
searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.LastOrDefault();
|
||||
if (query.Season >= 1 && query.Season <= 30)
|
||||
{
|
||||
var seasonTermValue = 967 + query.Season;
|
||||
searchUrl += "&term[45][]=" + seasonTermValue;
|
||||
queryStringOverride += " " + query.Season;
|
||||
}
|
||||
|
||||
if (query.Episode != null)
|
||||
{
|
||||
int episodeInt;
|
||||
int episodeCategoryOffset = 936;
|
||||
ParseUtil.TryCoerceInt(query.Episode, out episodeInt);
|
||||
if (episodeInt >= 1 && episodeInt <= 8)
|
||||
episodeCategoryOffset = 936;
|
||||
else if (episodeInt >= 9 && episodeInt <= 30)
|
||||
episodeCategoryOffset = 937;
|
||||
else if (episodeInt >= 31)
|
||||
episodeCategoryOffset = 1057;
|
||||
searchUrl += "&term[46][]=" + (episodeCategoryOffset + episodeInt);
|
||||
queryStringOverride += " " + query.Episode;
|
||||
}
|
||||
break;
|
||||
case "movie":
|
||||
// T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
|
||||
// So here we take FirstOrDefault from the category ids, so if the query specify an animation movie, we select the correct id.
|
||||
searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.FirstOrDefault();
|
||||
break;
|
||||
}
|
||||
|
||||
var headers = new Dictionary<string, string>();
|
||||
headers.Add("Authorization", await GetAuthToken());
|
||||
|
||||
var response = await RequestStringWithCookies(searchUrl, null, null, headers);
|
||||
var results = response.Content;
|
||||
|
||||
var jsonStart = results.IndexOf('{');
|
||||
var jsonLength = results.Length - jsonStart;
|
||||
var jsonResult = JObject.Parse(results.Substring(jsonStart));
|
||||
try
|
||||
{
|
||||
var items = (JArray)jsonResult["torrents"];
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.GetType() == typeof(JValue))
|
||||
{
|
||||
logger.Debug(string.Format("{0}: skipping torrent ID {1} (pending release without details)", ID, item.ToString()));
|
||||
continue;
|
||||
}
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.DownloadVolumeFactor = 1;
|
||||
var torrentId = (string)item["id"];
|
||||
release.Link = new Uri(DownloadUrl + torrentId);
|
||||
release.Title = (string)item["name"];
|
||||
|
||||
if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title, null, queryStringOverride))
|
||||
continue;
|
||||
|
||||
if ((string)item["isVerified"] == "1")
|
||||
release.Description = "Verified";
|
||||
release.Comments = new Uri(CommentsUrl + (string)item["rewritename"]);
|
||||
release.Guid = release.Comments;
|
||||
|
||||
var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
|
||||
release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;
|
||||
release.Size = ParseUtil.CoerceLong((string)item["size"]);
|
||||
release.Category = MapTrackerCatToNewznab((string)item["category"]);
|
||||
release.Grabs = ParseUtil.CoerceLong((string)item["times_completed"]);
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results, ex);
|
||||
}
|
||||
return releases;
|
||||
}
|
||||
|
||||
public override async Task<byte[]> Download(Uri link)
|
||||
{
|
||||
var headers = new Dictionary<string, string>();
|
||||
headers.Add("Authorization", await GetAuthToken());
|
||||
|
||||
var response = await RequestBytesWithCookies(link.AbsoluteUri, null, RequestType.GET, null, null, headers);
|
||||
return response.Content;
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@ using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System.IO;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -29,7 +30,7 @@ namespace Jackett.Indexers
|
||||
private bool Latency { get { return ConfigData.Latency.Value; } }
|
||||
private bool DevMode { get { return ConfigData.DevMode.Value; } }
|
||||
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
|
||||
private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
|
||||
private static string Directory => Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name.ToLower(), MethodBase.GetCurrentMethod().DeclaringType?.Name.ToLower());
|
||||
|
||||
private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
|
||||
private CQ fDom = null;
|
||||
@@ -44,13 +45,13 @@ namespace Jackett.Indexers
|
||||
: base(
|
||||
name: "WiHD",
|
||||
description: "Your World in High Definition",
|
||||
link: "http://world-in-hd.net/",
|
||||
link: "https://world-in-hd.net/",
|
||||
caps: new TorznabCapabilities(),
|
||||
configService: configService,
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
downloadBase: "http://world-in-hd.net/torrents/download/",
|
||||
downloadBase: "https://world-in-hd.net/torrents/download/",
|
||||
configData: new ConfigurationDataWiHD())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
@@ -215,8 +216,7 @@ namespace Jackett.Indexers
|
||||
var request = buildQuery(searchTerm, query, searchUrl);
|
||||
|
||||
// Getting results & Store content
|
||||
WebClientStringResult results = await queryExec(request);
|
||||
fDom = results.Content;
|
||||
fDom = await queryExec(request);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -271,10 +271,7 @@ namespace Jackett.Indexers
|
||||
var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
|
||||
|
||||
// Getting results & Store content
|
||||
WebClientStringResult pageResults = await queryExec(pageRequest);
|
||||
|
||||
// Assign response
|
||||
fDom = pageResults.Content;
|
||||
fDom = await queryExec(pageRequest);
|
||||
|
||||
// Process page results
|
||||
var additionalPageRows = findTorrentRows();
|
||||
@@ -296,7 +293,7 @@ namespace Jackett.Indexers
|
||||
// Category
|
||||
string categoryID = tRow.Find(".category > img").Attr("src").Split('/').Last().ToString();
|
||||
string categoryName = tRow.Find(".category > img").Attr("title").ToString();
|
||||
output("Category: " + MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName)) + " (" + categoryName + ")");
|
||||
output("Category: " + MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName)).First().ToString() + " (" + categoryName + ")");
|
||||
|
||||
// Uploader
|
||||
string uploader = tRow.Find(".uploader > span > a").Attr("title").ToString();
|
||||
@@ -345,19 +342,31 @@ namespace Jackett.Indexers
|
||||
Uri downloadLink = new Uri(SiteLink + download);
|
||||
output("Download Link: " + downloadLink.AbsoluteUri);
|
||||
|
||||
// Freeleech
|
||||
int downloadVolumeFactor = 1;
|
||||
if (tRow.Find(".fl-item").Length >= 1)
|
||||
{
|
||||
downloadVolumeFactor = 0;
|
||||
output("FreeLeech =)");
|
||||
}
|
||||
|
||||
// Building release infos
|
||||
var release = new ReleaseInfo();
|
||||
release.Category = MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName));
|
||||
release.Title = name;
|
||||
release.Seeders = seeders;
|
||||
release.Peers = seeders + leechers;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 345600;
|
||||
release.PublishDate = clock;
|
||||
release.Size = size;
|
||||
release.Guid = detailsLink;
|
||||
release.Comments = commentsLink;
|
||||
release.Link = downloadLink;
|
||||
var release = new ReleaseInfo()
|
||||
{
|
||||
Category = MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName)),
|
||||
Title = name,
|
||||
Seeders = seeders,
|
||||
Peers = seeders + leechers,
|
||||
MinimumRatio = 1,
|
||||
MinimumSeedTime = 345600,
|
||||
PublishDate = clock,
|
||||
Size = size,
|
||||
Guid = detailsLink,
|
||||
Comments = commentsLink,
|
||||
Link = downloadLink,
|
||||
UploadVolumeFactor = 1,
|
||||
DownloadVolumeFactor = downloadVolumeFactor
|
||||
};
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
@@ -448,9 +457,9 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryExec(string request)
|
||||
private async Task<String> queryExec(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
String results = null;
|
||||
|
||||
// Switch in we are in DEV mode with Hard Drive Cache or not
|
||||
if (DevMode && CacheMode)
|
||||
@@ -471,28 +480,40 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryCache(string request)
|
||||
private async Task<String> queryCache(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
String results;
|
||||
|
||||
// Create Directory if not exist
|
||||
System.IO.Directory.CreateDirectory(directory);
|
||||
System.IO.Directory.CreateDirectory(Directory);
|
||||
|
||||
// Clean Storage Provider Directory from outdated cached queries
|
||||
cleanCacheStorage();
|
||||
|
||||
// Remove timestamp from query
|
||||
string file = string.Join("&", Regex.Split(request, "&").Where(s => !Regex.IsMatch(s, @"_=\d")).ToList());
|
||||
// File Name
|
||||
string fileName = StringUtil.HashSHA1(request) + ".json";
|
||||
|
||||
// Create fingerprint for request
|
||||
file = directory + file.GetHashCode() + ".json";
|
||||
string file = Path.Combine(Directory, fileName);
|
||||
|
||||
// Checking modes states
|
||||
if (System.IO.File.Exists(file))
|
||||
if (File.Exists(file))
|
||||
{
|
||||
// File exist... loading it right now !
|
||||
output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
|
||||
results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
|
||||
output("Loading results from hard drive cache ..." + fileName);
|
||||
try
|
||||
{
|
||||
using (StreamReader fileReader = File.OpenText(file))
|
||||
{
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
results = (String)serializer.Deserialize(fileReader, typeof(String));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
output("Error loading cached results ! " + e.Message, "error");
|
||||
results = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -500,8 +521,12 @@ namespace Jackett.Indexers
|
||||
results = await queryTracker(request);
|
||||
|
||||
// Cached file didn't exist for our query, writing it right now !
|
||||
output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
|
||||
System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
|
||||
output("Writing results to hard drive cache ..." + fileName);
|
||||
using (StreamWriter fileWriter = File.CreateText(file))
|
||||
{
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
serializer.Serialize(fileWriter, results);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -511,7 +536,7 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryTracker(string request)
|
||||
private async Task<String> queryTracker(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
|
||||
@@ -523,14 +548,14 @@ namespace Jackett.Indexers
|
||||
results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
|
||||
|
||||
// Return results from tracker
|
||||
return results;
|
||||
return results.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean Hard Drive Cache Storage
|
||||
/// </summary>
|
||||
/// <param name="force">Force Provider Folder deletion</param>
|
||||
private void cleanCacheStorage(Boolean force = false)
|
||||
private void cleanCacheStorage(bool force = false)
|
||||
{
|
||||
// Check cleaning method
|
||||
if (force)
|
||||
@@ -539,10 +564,10 @@ namespace Jackett.Indexers
|
||||
output("\nDeleting Provider Storage folder and all files recursively ...");
|
||||
|
||||
// Check if directory exist
|
||||
if (System.IO.Directory.Exists(directory))
|
||||
if (System.IO.Directory.Exists(Directory))
|
||||
{
|
||||
// Delete storage directory of provider
|
||||
System.IO.Directory.Delete(directory, true);
|
||||
System.IO.Directory.Delete(Directory, true);
|
||||
output("-> Storage folder deleted successfully.");
|
||||
}
|
||||
else
|
||||
@@ -553,11 +578,11 @@ namespace Jackett.Indexers
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
var i = 0;
|
||||
// Check if there is file older than ... and delete them
|
||||
output("\nCleaning Provider Storage folder... in progress.");
|
||||
System.IO.Directory.GetFiles(directory)
|
||||
.Select(f => new System.IO.FileInfo(f))
|
||||
System.IO.Directory.GetFiles(Directory)
|
||||
.Select(f => new FileInfo(f))
|
||||
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
|
||||
.ToList()
|
||||
.ForEach(f =>
|
||||
|
@@ -193,7 +193,6 @@
|
||||
<Compile Include="Indexers\AnimeTorrents.cs" />
|
||||
<Compile Include="Indexers\7tor.cs" />
|
||||
<Compile Include="Indexers\EliteTracker.cs" />
|
||||
<Compile Include="Indexers\T411.cs" />
|
||||
<Compile Include="Indexers\Torrentech.cs" />
|
||||
<Compile Include="Indexers\notwhatcd.cs" />
|
||||
<Compile Include="Indexers\Redacted.cs" />
|
||||
@@ -254,8 +253,6 @@
|
||||
<Compile Include="Models\GitHub\Release.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataNorbits.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataXthor.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataPhxBit.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataBlueTigers.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataAbnormal.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataWiHD.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilterAndPasskey.cs" />
|
||||
@@ -288,7 +285,6 @@
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataNCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataAnimeBytes.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataStrike.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataUrl.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ISerializableConfig.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataPinNumber.cs" />
|
||||
@@ -324,7 +320,6 @@
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationData.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCookie.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataRuTor.cs" />
|
||||
<Compile Include="CookieContainerExtensions.cs" />
|
||||
<Compile Include="Utils\Clients\WebRequest.cs" />
|
||||
<Compile Include="Utils\DataUrl.cs" />
|
||||
|
@@ -1,63 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataBlueTigers : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public DisplayItem Instructions { get; set; }
|
||||
public BoolItem French { get; set; }
|
||||
public BoolItem English { get; set; }
|
||||
public BoolItem Spanish { get; set; }
|
||||
|
||||
public ConfigurationDataBlueTigers(string displayInstructions)
|
||||
{
|
||||
Username = new StringItem { Name = "Username", Value = "" };
|
||||
Password = new StringItem { Name = "Password", Value = "" };
|
||||
Instructions = new DisplayItem(displayInstructions) { Name = "" };
|
||||
French = new BoolItem { Name = "French", Value = true };
|
||||
English = new BoolItem { Name = "English", Value = true };
|
||||
Spanish = new BoolItem { Name = "Spanish", Value = true };
|
||||
}
|
||||
|
||||
public ConfigurationDataBlueTigers(JToken json)
|
||||
{
|
||||
ConfigurationDataNCore configData = new ConfigurationDataNCore();
|
||||
|
||||
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
|
||||
foreach (var config in configArray)
|
||||
{
|
||||
string propertyName = UppercaseFirst((string)config.id);
|
||||
switch (propertyName)
|
||||
{
|
||||
case "Username":
|
||||
Username = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Password":
|
||||
Password = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "French":
|
||||
French = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "English":
|
||||
English = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Spanish":
|
||||
Spanish = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string UppercaseFirst(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return string.Empty;
|
||||
return char.ToUpper(s[0]) + s.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
class ConfigurationDataPhxBit : ConfigurationData
|
||||
{
|
||||
public HiddenItem PassKey { get; set; }
|
||||
public DisplayItem CredentialsWarning { get; private set; }
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public DisplayItem PagesWarning { get; private set; }
|
||||
public StringItem Pages { get; private set; }
|
||||
public DisplayItem SecurityWarning { get; private set; }
|
||||
public BoolItem Latency { get; private set; }
|
||||
public BoolItem Browser { get; private set; }
|
||||
public DisplayItem LatencyWarning { get; private set; }
|
||||
public StringItem LatencyStart { get; private set; }
|
||||
public StringItem LatencyEnd { get; private set; }
|
||||
public DisplayItem HeadersWarning { get; private set; }
|
||||
public StringItem HeaderAccept { get; private set; }
|
||||
public StringItem HeaderAcceptLang { get; private set; }
|
||||
public BoolItem HeaderDNT { get; private set; }
|
||||
public BoolItem HeaderUpgradeInsecure { get; private set; }
|
||||
public StringItem HeaderUserAgent { get; private set; }
|
||||
public DisplayItem DevWarning { get; private set; }
|
||||
public BoolItem DevMode { get; private set; }
|
||||
public BoolItem HardDriveCache { get; private set; }
|
||||
public StringItem HardDriveCacheKeepTime { get; private set; }
|
||||
|
||||
public ConfigurationDataPhxBit()
|
||||
: base()
|
||||
{
|
||||
PassKey = new HiddenItem { Name = "PassKey", Value = "" };
|
||||
CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
|
||||
Username = new StringItem { Name = "Username (Required)", Value = "" };
|
||||
Password = new StringItem { Name = "Password (Required)", Value = "" };
|
||||
PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li></ul>") { Name = "Preferences" };
|
||||
Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
|
||||
SecurityWarning = new DisplayItem("<b>Security Configuration</b> (<i>Read this area carefully !</i>),<br /><br /> <ul><li><b>Latency Simulation</b> will simulate human browsing with Jacket by pausing Jacket for an random time between each request, to fake a real content browsing.</li><li><b>Browser Simulation</b> will simulate a real human browser by injecting additionals headers when doing requests to tracker.</li></ul>") { Name = "Security" };
|
||||
Latency = new BoolItem() { Name = "Latency Simulation (Optional)", Value = false };
|
||||
Browser = new BoolItem() { Name = "Browser Simulation (Optional)", Value = true };
|
||||
LatencyWarning = new DisplayItem("<b>Latency Configuration</b> (<i>Required if latency simulation enabled</i>),<br /><br/> <ul><li>By filling this range, <b>Jackett will make a random timed pause</b> <u>between requests</u> to tracker <u>to simulate a real browser</u>.</li><li>MilliSeconds <b>only</b></li></ul>") { Name = "Simulate Latency" };
|
||||
LatencyStart = new StringItem { Name = "Minimum Latency (ms)", Value = "1589" };
|
||||
LatencyEnd = new StringItem { Name = "Maximum Latency (ms)", Value = "3674" };
|
||||
HeadersWarning = new DisplayItem("<b>Browser Headers Configuration</b> (<i>Required if browser simulation enabled</i>),<br /><br /> <ul><li>By filling these fields, <b>Jackett will inject headers</b> with your values <u>to simulate a real browser</u>.</li><li>You can get <b>your browser values</b> here: <a href='https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' target='blank'>www.whatismybrowser.com</a></li></ul><br /><i><b>Note that</b> some headers are not necessary because they are injected automatically by this provider such as Accept_Encoding, Connection, Host or X-Requested-With</i>") { Name = "Injecting headers" };
|
||||
HeaderAccept = new StringItem { Name = "Accept", Value = "" };
|
||||
HeaderAcceptLang = new StringItem { Name = "Accept-Language", Value = "" };
|
||||
HeaderDNT = new BoolItem { Name = "DNT", Value = false };
|
||||
HeaderUpgradeInsecure = new BoolItem { Name = "Upgrade-Insecure-Requests", Value = false };
|
||||
HeaderUserAgent = new StringItem { Name = "User-Agent", Value = "" };
|
||||
DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
|
||||
DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
|
||||
HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
|
||||
HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataRuTor : ConfigurationData
|
||||
{
|
||||
[JsonProperty]
|
||||
public StringItem Url { get; private set; }
|
||||
[JsonProperty]
|
||||
public BoolItem StripRussian { get; private set; }
|
||||
|
||||
public ConfigurationDataRuTor()
|
||||
{
|
||||
}
|
||||
|
||||
public ConfigurationDataRuTor(string defaultUrl)
|
||||
{
|
||||
Url = new StringItem { Name = "Url", Value = defaultUrl };
|
||||
StripRussian = new BoolItem() { Name = "StripRusNamePrefix", Value = true };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataStrike : ConfigurationDataUrl
|
||||
{
|
||||
public DisplayItem StrikeWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataStrike(string url) : base(url)
|
||||
{
|
||||
StrikeWarning = new DisplayItem("This indexer does not support RSS Sync, only Search") { Name = "Warning" };
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,10 +30,10 @@
|
||||
public ConfigurationDataWiHD()
|
||||
: base()
|
||||
{
|
||||
CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
|
||||
CredentialsWarning = new DisplayItem("<b> YOU MUST USE CLASSIC VIEW ON WIHD !</b><br /> In order to use this provider with Jackett, take a look in your settings on the tracker before proceeding...<br /><br /><b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
|
||||
Username = new StringItem { Name = "Username (Required)", Value = "" };
|
||||
Password = new StringItem { Name = "Password (Required)", Value = "" };
|
||||
PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li><li><b>Exclusive Only</b> let you search <u>only</u> for torrents which are marked Exclusive.</li><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li><li><b>Reseed Only</b> let you search <u>only</u> for torrents which need to be seeded.</li></ul>") { Name = "Preferences" };
|
||||
PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li><li><b>Exclusive Only</b> let you search <u>only</u> for torrents which are marked Exclusive.</li><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li><li><b>Reseed Only</b> let you search <u>only</u> for torrents which need to be seeded.</li></ul>") { Name = "Preferences" };
|
||||
Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
|
||||
Exclusive = new BoolItem() { Name = "Exclusive Only (Optional)", Value = false };
|
||||
Freeleech = new BoolItem() { Name = "Freeleech Only (Optional)", Value = false };
|
||||
|
Reference in New Issue
Block a user