mirror of
https://github.com/Jackett/Jackett.git
synced 2025-12-24 14:57:09 +01:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd2abddb09 | ||
|
|
5135748d1d | ||
|
|
0fc3d224ab | ||
|
|
ac07cc34cd | ||
|
|
3730e05f20 | ||
|
|
2644fd813e | ||
|
|
ece16d1075 | ||
|
|
3b13fa84a4 | ||
|
|
cda5ea3207 | ||
|
|
0746616b43 | ||
|
|
28199ab4be | ||
|
|
b29c578adb | ||
|
|
b42f2a0972 | ||
|
|
040deb2bfb | ||
|
|
ef8b4e685e | ||
|
|
364860199c | ||
|
|
3f2a6fd3f7 | ||
|
|
2671cf00e0 | ||
|
|
6a6941d01c | ||
|
|
5b3862bc3d | ||
|
|
0452f5ad06 | ||
|
|
264fc995b2 | ||
|
|
acc75acb9c | ||
|
|
a5b1332f95 | ||
|
|
8871a631b1 | ||
|
|
bfb58f53f5 | ||
|
|
d14717c88e | ||
|
|
d8ff110d8b |
@@ -39,6 +39,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Immortalseed
|
||||
* IPTorrents
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
* NCore
|
||||
* NextGen
|
||||
* PhxBit
|
||||
@@ -46,6 +47,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* PrivateHD
|
||||
* RevolutionTT
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneTime
|
||||
* Shazbat
|
||||
* SpeedCD
|
||||
@@ -54,9 +56,11 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* TorrentDay
|
||||
* TorrentLeech
|
||||
* TorrentShack
|
||||
* TransmitheNet
|
||||
* TV Chaos UK
|
||||
* World-In-HD
|
||||
* XSpeeds
|
||||
* Xthor
|
||||
|
||||
#### Installation on Windows
|
||||
|
||||
@@ -95,7 +99,7 @@ You can get additional logging with the switches "-t -l". Please post logs if y
|
||||
Please supply as much information about the problem you are experiencing as possible. Your issue has a much greater chance of being resolved if logs are supplied so that we can see what is going on. Creating an issue with '### isn't working' doesn't help anyone to fix the problem.
|
||||
|
||||
### Contributing
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/zone117x/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project. We currently only support private trackers.
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/Jackett/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project. We currently only support private trackers.
|
||||
|
||||
|
||||
### Screenshots
|
||||
|
||||
@@ -60,6 +60,9 @@ namespace Jackett.Console
|
||||
[Option('n', "IgnoreSslErrors", HelpText = "[true/false] Linux Libcurl - Ignores invalid SSL certificates")]
|
||||
public bool? IgnoreSslErrors { get; set; }
|
||||
|
||||
[Option('d', "DataFolder", HelpText = "Specify the location of the data folder (Must be admin on Windows) eg. --DataFolder=\"D:\\Your Data\\Jackett\\\"")]
|
||||
public string DataFolder { get; set; }
|
||||
|
||||
[ParserState]
|
||||
public IParserState LastParserState { get; set; }
|
||||
}
|
||||
|
||||
@@ -99,6 +99,13 @@ namespace JackettConsole
|
||||
Engine.Logger.Info("Curl will ignore SSL certificate errors.");
|
||||
}
|
||||
|
||||
// Choose Data Folder
|
||||
if (!string.IsNullOrWhiteSpace(options.DataFolder))
|
||||
{
|
||||
Startup.CustomDataFolder = options.DataFolder.Replace("\"", string.Empty).Replace("'", string.Empty).Replace(@"\\", @"\");
|
||||
Engine.Logger.Info("Jackett Data will be stored in: " + Startup.CustomDataFolder);
|
||||
}
|
||||
|
||||
/* ====== Actions ===== */
|
||||
|
||||
// Install service
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 38 KiB |
BIN
src/Jackett/Content/logos/myanonamouse.png
Normal file
BIN
src/Jackett/Content/logos/myanonamouse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
src/Jackett/Content/logos/scenefz.png
Normal file
BIN
src/Jackett/Content/logos/scenefz.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
BIN
src/Jackett/Content/logos/xthor.png
Normal file
BIN
src/Jackett/Content/logos/xthor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
@@ -56,13 +56,18 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(23, TorznabCatType.Audio);
|
||||
}
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var incomingConfig = new ConfigurationDataBasicLogin();
|
||||
incomingConfig.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", incomingConfig.Username.Value },
|
||||
{ "password", incomingConfig.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "login", "Login" },
|
||||
{ "keeplogged", "1" }
|
||||
};
|
||||
@@ -74,7 +79,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = response.Content;
|
||||
dom["#loginform > table"].Remove();
|
||||
var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Jackett.Indexers
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php?/{0}/dl.torrent"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php?id={0}"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace Jackett.Indexers
|
||||
private string UseLink { get { return (this.configData.AlternateLink.Value != null && this.configData.AlternateLink.Value != "" ? this.configData.AlternateLink.Value : SiteLink); } }
|
||||
private string BrowseUrl { get { return UseLink + "browse.php"; } }
|
||||
private string LoginUrl { get { return UseLink + "takelogin.php"; } }
|
||||
private string LoginReferer { get { return UseLink + "login.php"; } }
|
||||
private List<String> KnownURLs = new List<String>{ "https://www.bitsoup.me/","https://www.bitsoup.org/"};
|
||||
private string LoginReferer { get { return UseLink + "login.php"; } }
|
||||
private List<String> KnownURLs = new List<String> { "https://www.bitsoup.me/", "https://www.bitsoup.org/" };
|
||||
|
||||
new NxtGnConfigurationData configData
|
||||
new ConfigurationDataBasicLoginWithAlternateLink configData
|
||||
{
|
||||
get { return (NxtGnConfigurationData)base.configData; }
|
||||
get { return (ConfigurationDataBasicLoginWithAlternateLink)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ namespace Jackett.Indexers
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new NxtGnConfigurationData())
|
||||
configData: new ConfigurationDataBasicLoginWithAlternateLink())
|
||||
{
|
||||
this.configData.DisplayText.Value = this.DisplayName + " has multiple URLs. The default (" + this.SiteLink + ") can be changed by entering a new value in the box below.";
|
||||
this.configData.DisplayText.Value += "The following are some known URLs for " + this.DisplayName;
|
||||
this.configData.DisplayText.Value += "<ul><li>" + String.Join("</li><li>", this.KnownURLs.ToArray()) + "</li></ul>";
|
||||
this.configData.Instructions.Value = this.DisplayName + " has multiple URLs. The default (" + this.SiteLink + ") can be changed by entering a new value in the box below.";
|
||||
this.configData.Instructions.Value += "The following are some known URLs for " + this.DisplayName;
|
||||
this.configData.Instructions.Value += "<ul><li>" + String.Join("</li><li>", this.KnownURLs.ToArray()) + "</li></ul>";
|
||||
|
||||
//AddCategoryMapping("624", TorznabCatType.Console);
|
||||
//AddCategoryMapping("307", TorznabCatType.ConsoleNDS);
|
||||
@@ -158,12 +158,12 @@ namespace Jackett.Indexers
|
||||
{
|
||||
configData.AlternateLink.Value = null;
|
||||
throw new Exception("AlternateLink must be a valid url.");
|
||||
}
|
||||
}
|
||||
}
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
|
||||
|
||||
};
|
||||
|
||||
var loginPage = await RequestStringWithCookies(UseLink, string.Empty);
|
||||
@@ -188,11 +188,12 @@ namespace Jackett.Indexers
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
|
||||
queryCollection.Add("search", string.IsNullOrWhiteSpace(searchString)? "" : searchString);
|
||||
queryCollection.Add("search", string.IsNullOrWhiteSpace(searchString) ? "" : searchString);
|
||||
if (trackerCats.Count > 1)
|
||||
{
|
||||
for (var ct = 0; ct < trackerCats.Count; ct++) queryCollection.Add("cat" + (ct+1), trackerCats.ElementAt(ct));
|
||||
} else
|
||||
for (var ct = 0; ct < trackerCats.Count; ct++) queryCollection.Add("cat" + (ct + 1), trackerCats.ElementAt(ct));
|
||||
}
|
||||
else
|
||||
{
|
||||
queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
|
||||
}
|
||||
@@ -242,23 +243,5 @@ namespace Jackett.Indexers
|
||||
OnParseError(results, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public class NxtGnConfigurationData : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public DisplayItem DisplayText { get; private set; }
|
||||
public StringItem AlternateLink { get; set; }
|
||||
|
||||
|
||||
public NxtGnConfigurationData()
|
||||
{
|
||||
Username = new StringItem { Name = "Username" };
|
||||
Password = new StringItem { Name = "Password" };
|
||||
DisplayText = new DisplayItem("") { Name = "" };
|
||||
AlternateLink = new StringItem { Name = "AlternateLinks" };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,11 +21,13 @@ namespace Jackett.Indexers
|
||||
{
|
||||
public class IPTorrents : BaseIndexer, IIndexer
|
||||
{
|
||||
private string BrowseUrl { get { return SiteLink + "t"; } }
|
||||
private string UseLink { get { return (!String.IsNullOrEmpty(this.configData.AlternateLink.Value) ? this.configData.AlternateLink.Value : SiteLink); } }
|
||||
private string BrowseUrl { get { return UseLink + "t"; } }
|
||||
private List<String> KnownURLs = new List<String> { "https://nemo.iptorrents.com/", "https://ipt.rocks/" };
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
new ConfigurationDataBasicLoginWithAlternateLink configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
get { return (ConfigurationDataBasicLoginWithAlternateLink)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
@@ -38,8 +40,12 @@ namespace Jackett.Indexers
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
configData: new ConfigurationDataBasicLoginWithAlternateLink())
|
||||
{
|
||||
this.configData.Instructions.Value = this.DisplayName + " has multiple URLs. The default (" + this.SiteLink + ") can be changed by entering a new value in the box below.";
|
||||
this.configData.Instructions.Value += "The following are some known URLs for " + this.DisplayName;
|
||||
this.configData.Instructions.Value += "<ul><li>" + String.Join("</li><li>", this.KnownURLs.ToArray()) + "</li></ul>";
|
||||
|
||||
AddCategoryMapping(72, TorznabCatType.Movies);
|
||||
AddCategoryMapping(77, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(89, TorznabCatType.MoviesSD);
|
||||
@@ -92,9 +98,9 @@ namespace Jackett.Indexers
|
||||
};
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = SiteLink,
|
||||
Url = UseLink,
|
||||
Type = RequestType.POST,
|
||||
Referer = SiteLink,
|
||||
Referer = UseLink,
|
||||
PostData = pairs
|
||||
};
|
||||
var response = await webclient.GetString(request);
|
||||
@@ -156,7 +162,7 @@ namespace Jackett.Indexers
|
||||
}
|
||||
|
||||
release.Description = release.Title;
|
||||
release.Guid = new Uri(SiteLink + qTitleLink.Attr("href").Substring(1));
|
||||
release.Guid = new Uri(UseLink + qTitleLink.Attr("href").Substring(1));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
var descString = qRow.Find(".t_ctime").Text();
|
||||
@@ -165,7 +171,7 @@ namespace Jackett.Indexers
|
||||
release.PublishDate = DateTimeUtil.FromTimeAgo(dateString);
|
||||
|
||||
var qLink = row.ChildElements.ElementAt(3).Cq().Children("a");
|
||||
release.Link = new Uri(SiteLink + HttpUtility.UrlEncode(qLink.Attr("href").TrimStart('/')));
|
||||
release.Link = new Uri(UseLink + HttpUtility.UrlEncode(qLink.Attr("href").TrimStart('/')));
|
||||
|
||||
var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
|
||||
242
src/Jackett/Indexers/MyAnonamouse.cs
Normal file
242
src/Jackett/Indexers/MyAnonamouse.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using CsQuery;
|
||||
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.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Myanonamouse : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "tor/js/loadSearch2.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public Myanonamouse(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
|
||||
: base(name: "Myanonamouse",
|
||||
description: "Friendliness, Warmth and Sharing",
|
||||
link: "https://www.myanonamouse.net/",
|
||||
caps: new TorznabCapabilities(TorznabCatType.Books,
|
||||
TorznabCatType.AudioAudiobook,
|
||||
TorznabCatType.BooksComics,
|
||||
TorznabCatType.BooksEbook,
|
||||
TorznabCatType.BooksMagazines,
|
||||
TorznabCatType.BooksTechnical),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
AddCategoryMapping("61", TorznabCatType.BooksComics);
|
||||
AddCategoryMapping("91", TorznabCatType.BooksTechnical);
|
||||
AddCategoryMapping("80", TorznabCatType.BooksTechnical);
|
||||
AddCategoryMapping("79", TorznabCatType.BooksMagazines);
|
||||
AddCategoryMapping("39", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("49", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("50", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("83", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("51", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("97", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("40", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("41", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("106", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("42", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("52", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("98", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("54", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("55", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("43", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("99", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("84", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("44", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("56", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("137", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("45", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("57", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("85", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("87", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("119", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("88", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("58", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("59", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("46", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("47", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("53", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("89", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("100", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("108", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("48", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("111", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("60", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("71", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("72", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("90", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("73", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("101", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("62", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("63", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("107", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("64", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("74", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("102", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("76", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("77", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("65", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("103", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("115", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("66", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("78", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("138", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("67", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("92", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("118", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("94", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("120", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("95", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("81", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("82", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("68", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("69", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("75", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("96", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("104", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("109", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("70", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("112", TorznabCatType.BooksEbook);
|
||||
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "email", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "returnto", "/" }
|
||||
};
|
||||
|
||||
var preRequest = await RequestStringWithCookiesAndRetry(LoginUrl, string.Empty);
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, preRequest.Cookies, true, SearchUrl, SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Search Results"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom["table.main table td.text"].Text().Trim().Replace("\n\t", " ");
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
NameValueCollection qParams = new NameValueCollection();
|
||||
qParams.Add("tor[text]", query.GetQueryString());
|
||||
qParams.Add("tor[srchIn][title]", "true");
|
||||
qParams.Add("tor[srchIn][author]", "true");
|
||||
qParams.Add("tor[searchType]", "all");
|
||||
qParams.Add("tor[searchIn]", "torrents");
|
||||
qParams.Add("tor[hash]", "");
|
||||
qParams.Add("tor[sortType]", "default");
|
||||
qParams.Add("tor[startNumber]", "0");
|
||||
|
||||
List<string> catList = MapTorznabCapsToTrackers(query);
|
||||
if (catList.Any())
|
||||
{
|
||||
foreach (string cat in catList)
|
||||
{
|
||||
qParams.Add("tor[cat][]", cat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qParams.Add("tor[cat][]", "0");
|
||||
}
|
||||
|
||||
string urlSearch = SearchUrl;
|
||||
if (qParams.Count > 0)
|
||||
{
|
||||
urlSearch += $"?{qParams.GetQueryString()}";
|
||||
}
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(urlSearch);
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
var rows = dom["table[class='newTorTable'] > tbody > tr"];
|
||||
|
||||
foreach (IDomObject row in rows)
|
||||
{
|
||||
CQ torrentData = row.OuterHTML;
|
||||
CQ cells = row.Cq().Find("td");
|
||||
|
||||
if (cells.Any() && torrentData.Find("a[class='directDownload']").Any())
|
||||
{
|
||||
string title = torrentData.Find("a[class='title']").First().Text().Trim();
|
||||
string author = torrentData.Find("a[class='author']").First().Text().Trim();
|
||||
Uri link = new Uri(SiteLink + torrentData.Find("a[class='directDownload']").First().Attr("href").Trim().TrimStart('/'));
|
||||
Uri guid = new Uri(SiteLink + torrentData.Find("a[class='directDownload']").First().Attr("href").Trim().TrimStart('/'));
|
||||
long size = ReleaseInfo.GetBytes(cells.Elements.ElementAt(4).Cq().Text().Split('[')[1].TrimEnd(']'));
|
||||
int seeders = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Find("p").ElementAt(0).Cq().Text());
|
||||
int leechers = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Find("p").ElementAt(1).Cq().Text());
|
||||
|
||||
string pubDateStr = cells.Elements.ElementAt(5).Cq().Text().Split('[')[0];
|
||||
DateTime publishDate = DateTime.Parse(pubDateStr).ToLocalTime();
|
||||
|
||||
long category = 0;
|
||||
string cat = torrentData.Find("a[class='newCatLink']").First().Attr("href").Remove(0, "/tor/browse.php?tor[cat][]]=".Length);
|
||||
long.TryParse(cat, out category);
|
||||
|
||||
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.Title = String.IsNullOrEmpty(author) ? title : String.Format("{0} by {1}", title, author);
|
||||
release.Guid = guid;
|
||||
release.Link = link;
|
||||
release.PublishDate = publishDate;
|
||||
release.Size = size;
|
||||
release.Description = release.Title;
|
||||
release.Seeders = seeders;
|
||||
release.Peers = seeders + leechers;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.Category = MapTrackerCatToNewznab(category.ToString());
|
||||
release.Comments = guid;
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Jackett.Indexers
|
||||
private string SearchUrl { get { return SiteLink + "sphinx.php"; } }
|
||||
private string TorrentCommentUrl { get { return TorrentDescriptionUrl; } }
|
||||
private string TorrentDescriptionUrl { get { return SiteLink + "torrent.php?id="; } }
|
||||
private string TorrentDownloadUrl { get { return SiteLink + "get.php?action=torrent&id={id}&passkey={passkey}"; } }
|
||||
private string TorrentDownloadUrl { get { return SiteLink + "get.php?action=private&id={id}&passkey={passkey}"; } }
|
||||
private bool Latency { get { return ConfigData.Latency.Value; } }
|
||||
private bool DevMode { get { return ConfigData.DevMode.Value; } }
|
||||
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
|
||||
@@ -51,7 +51,7 @@ namespace Jackett.Indexers
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
downloadBase: "https://phxbit.com/torrents.php?action=download&id=",
|
||||
downloadBase: "https://phxbit.com/get.php?action=private",
|
||||
configData: new ConfigurationDataPhxBit())
|
||||
{
|
||||
// Clean capabilities
|
||||
@@ -80,6 +80,7 @@ namespace Jackett.Indexers
|
||||
|
||||
// Anime
|
||||
AddCategoryMapping(1, TorznabCatType.TVAnime); // ANIME
|
||||
AddCategoryMapping(28, TorznabCatType.TVAnime); // MANGA ANIME
|
||||
|
||||
// Documentaries
|
||||
AddCategoryMapping(17, TorznabCatType.TVDocumentary); // DOCS
|
||||
@@ -99,7 +100,6 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(30, TorznabCatType.ConsolePSP); // GAMES
|
||||
AddCategoryMapping(31, TorznabCatType.ConsoleNDS); // GAMES
|
||||
AddCategoryMapping(8, TorznabCatType.BooksEbook); // EBOOKS
|
||||
AddCategoryMapping(28, TorznabCatType.BooksEbook); // EBOOKS MANGA
|
||||
AddCategoryMapping(11, TorznabCatType.BooksEbook); // EBOOKS AUDIO
|
||||
AddCategoryMapping(35, TorznabCatType.PCPhoneAndroid); // ANDROID
|
||||
}
|
||||
@@ -332,8 +332,8 @@ namespace Jackett.Indexers
|
||||
long size = ReleaseInfo.GetBytes(sizeStr);
|
||||
output("Size: " + sizeStr + " (" + size + " bytes)");
|
||||
|
||||
// Health
|
||||
int percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8) > img").Attr("alt").ToString(), @"\d+").Value);
|
||||
// Health
|
||||
int percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8) > img").Attr("alt").ToString(), @"\d+").Value);
|
||||
output("Health: " + percent + "%");
|
||||
|
||||
// Publish DateToString
|
||||
|
||||
125
src/Jackett/Indexers/SceneFZ.cs
Normal file
125
src/Jackett/Indexers/SceneFZ.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Jackett.Utils.Clients;
|
||||
using NLog;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Models;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using CsQuery;
|
||||
using System.Web;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class SceneFZ : BaseIndexer, IIndexer
|
||||
{
|
||||
string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
|
||||
string BrowseUrl { get { return SiteLink + "ajax_browse.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public SceneFZ(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "SceneFZ",
|
||||
description: "Torrent tracker. Tracking over 50.000 torrent files.",
|
||||
link: "http://scenefz.net/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
AddCategoryMapping(32, TorznabCatType.Movies);
|
||||
AddCategoryMapping(33, TorznabCatType.TV);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string>
|
||||
{
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Please wait..."), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom[".tableinborder:eq(1) td"].Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchUrl = BrowseUrl;
|
||||
var searchString = query.GetQueryString();
|
||||
|
||||
var cats = MapTorznabCapsToTrackers(query);
|
||||
string cat = "0";
|
||||
|
||||
if (cats.Count == 1)
|
||||
{
|
||||
cat = cats[0];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchString) || cat != "0")
|
||||
searchUrl += string.Format("?search={0}¶m_val=0&complex_search=0&incldead=mc{1}&orderby=added&sort=desc", HttpUtility.UrlEncode(searchString), cat);
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
|
||||
var results = response.Content;
|
||||
try
|
||||
{
|
||||
CQ dom = results;
|
||||
var rows = dom["td#browse-middle-td"];
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
var qTitleLink = qRow.Find("table tbody tr:eq(0) td a").First();
|
||||
release.Title = qRow.Find("table tbody tr:eq(0) td a b").Text().Trim();
|
||||
release.Description = release.Title;
|
||||
release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
//24.04.2016 16:44:57
|
||||
var dateStr = qRow.Find("table tbody tr:eq(1) td:eq(4)").Html().Replace(" ", " ").Trim();
|
||||
release.PublishDate = DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture).AddHours(-2);
|
||||
|
||||
var qLink = qRow.First().Next().Find("a");
|
||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||
|
||||
var sizeStr = qRow.Find("table tbody tr:eq(1) td b").Text().Trim();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(",", "."));
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find("table tbody tr:eq(1) td:eq(1) b:eq(0) font").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find("table tbody tr:eq(1) td:eq(1) b:eq(1) font").Text().Trim()) + release.Seeders;
|
||||
|
||||
var catId = qRow.First().Prev().Find("a").Attr("onclick").Substring(21, 2);
|
||||
release.Category = MapTrackerCatToNewznab(catId);
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Jackett.Indexers
|
||||
{
|
||||
public class SpeedCD : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "take.login.php"; } }
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
@@ -70,24 +70,39 @@ namespace Jackett.Indexers
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
await DoLogin();
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
private async Task DoLogin()
|
||||
{
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink);
|
||||
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom["h5"].First().Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var loggedInCheck = await RequestStringWithCookies(SearchUrl);
|
||||
if (!loggedInCheck.Content.Contains("/logout.php"))
|
||||
{
|
||||
//Cookie appears to expire after a period of time or logging in to the site via browser
|
||||
await DoLogin();
|
||||
}
|
||||
|
||||
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
NameValueCollection qParams = new NameValueCollection();
|
||||
|
||||
@@ -61,9 +61,12 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(44, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(1, TorznabCatType.MoviesSD);
|
||||
|
||||
// Music foreign
|
||||
// Music packs
|
||||
// Music videos
|
||||
// Music
|
||||
AddCategoryMapping(17, TorznabCatType.AudioMP3);
|
||||
AddCategoryMapping(44, TorznabCatType.AudioLossless);
|
||||
AddCategoryMapping(23, TorznabCatType.AudioForeign);
|
||||
AddCategoryMapping(41, TorznabCatType.AudioOther);
|
||||
AddCategoryMapping(16, TorznabCatType.AudioVideo);
|
||||
|
||||
AddCategoryMapping(4, TorznabCatType.PCGames);
|
||||
// ps3
|
||||
|
||||
@@ -151,6 +151,10 @@ namespace Jackett.Indexers
|
||||
release.Link = new Uri(SiteLink + qRow.Find(".quickdownload > a").Attr("href").Substring(1));
|
||||
|
||||
var dateString = qRow.Find(".name")[0].InnerText.Trim().Replace(" ", string.Empty).Replace("Addedinon", string.Empty);
|
||||
|
||||
//Fix for issue 2016-04-30
|
||||
dateString = dateString.Replace("\r", "").Replace("\n", "");
|
||||
|
||||
//"2015-04-25 23:38:12"
|
||||
//"yyyy-MMM-dd hh:mm:ss"
|
||||
release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Jackett.Indexers
|
||||
public class TransmitheNet : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?action=basic&order_by=time&order_way=desc&search_type=0&taglist=&tags_type=0"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
@@ -70,7 +70,7 @@ namespace Jackett.Indexers
|
||||
Url = SearchUrl;
|
||||
else
|
||||
{
|
||||
Url = $"{SearchUrl}?searchtext={HttpUtility.UrlEncode(query.GetQueryString())}";
|
||||
Url = $"{SearchUrl}&searchtext={HttpUtility.UrlEncode(query.GetQueryString())}";
|
||||
}
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(Url);
|
||||
@@ -101,7 +101,10 @@ namespace Jackett.Indexers
|
||||
}
|
||||
else
|
||||
{
|
||||
title = title.Remove(title.LastIndexOf("."));
|
||||
if (title.Length > 5 && title.Substring(title.Length - 5).Contains("."))
|
||||
{
|
||||
title = title.Remove(title.LastIndexOf("."));
|
||||
}
|
||||
}
|
||||
|
||||
release.Title = title;
|
||||
|
||||
592
src/Jackett/Indexers/Xthor.cs
Normal file
592
src/Jackett/Indexers/Xthor.cs
Normal file
@@ -0,0 +1,592 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider for Xthor Private French Tracker
|
||||
/// </summary>
|
||||
public class Xthor : BaseIndexer, IIndexer
|
||||
{
|
||||
private static string ApiEndpoint => "https://api.xthor.bz/";
|
||||
private string TorrentCommentUrl => TorrentDescriptionUrl;
|
||||
private string TorrentDescriptionUrl => SiteLink + "details.php?id={id}";
|
||||
private bool DevMode => ConfigData.DevMode.Value;
|
||||
private bool CacheMode => ConfigData.HardDriveCache.Value;
|
||||
private static string Directory => System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType?.Name + "\\";
|
||||
public Dictionary<string, string> EmulatedBrowserHeaders { get; } = new Dictionary<string, string>();
|
||||
private ConfigurationDataXthor ConfigData => (ConfigurationDataXthor)configData;
|
||||
|
||||
public Xthor(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
|
||||
: base(
|
||||
name: "Xthor",
|
||||
description: "General French Private Tracker",
|
||||
link: "https://xthor.bz/",
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
downloadBase: "https://xthor.bz/download.php?torrent=",
|
||||
configData: new ConfigurationDataXthor())
|
||||
{
|
||||
// Clean capabilities
|
||||
TorznabCaps.Categories.Clear();
|
||||
|
||||
// Movies
|
||||
AddCategoryMapping(6, TorznabCatType.MoviesSD); // XVID
|
||||
AddCategoryMapping(7, TorznabCatType.MoviesSD); // X264
|
||||
AddCategoryMapping(95, TorznabCatType.MoviesSD); // WEBRIP
|
||||
AddCategoryMapping(5, TorznabCatType.MoviesHD); // HD 720P
|
||||
AddCategoryMapping(4, TorznabCatType.MoviesHD); // HD 1080P X264
|
||||
AddCategoryMapping(100, TorznabCatType.MoviesHD); // HD 1080P X265
|
||||
AddCategoryMapping(94, TorznabCatType.MoviesHD); // WEBDL
|
||||
AddCategoryMapping(1, TorznabCatType.MoviesBluRay); // FULL BLURAY
|
||||
AddCategoryMapping(2, TorznabCatType.MoviesBluRay); // BLURAY REMUX
|
||||
AddCategoryMapping(3, TorznabCatType.MoviesBluRay); // FULL BLURAY 3D
|
||||
AddCategoryMapping(8, TorznabCatType.MoviesDVD); // FULL DVD
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesOther); // VOSTFR
|
||||
AddCategoryMapping(36, TorznabCatType.XXX); // XXX
|
||||
|
||||
// Series
|
||||
AddCategoryMapping(14, TorznabCatType.TVSD); // SD VF
|
||||
AddCategoryMapping(16, TorznabCatType.TVSD); // SD VF VOSTFR
|
||||
AddCategoryMapping(15, TorznabCatType.TVHD); // HD VF
|
||||
AddCategoryMapping(17, TorznabCatType.TVHD); // HD VF VOSTFR
|
||||
AddCategoryMapping(13, TorznabCatType.TVOTHER); // PACK
|
||||
AddCategoryMapping(98, TorznabCatType.TVOTHER); // PACK VOSTFR HD
|
||||
AddCategoryMapping(16, TorznabCatType.TVOTHER); // PACK VOSTFR SD
|
||||
AddCategoryMapping(30, TorznabCatType.TVOTHER); // EMISSIONS
|
||||
AddCategoryMapping(34, TorznabCatType.TVOTHER); // EMISSIONS
|
||||
AddCategoryMapping(33, TorznabCatType.TVOTHER); // SHOWS
|
||||
|
||||
// Anime
|
||||
AddCategoryMapping(31, TorznabCatType.TVAnime); // MOVIES ANIME
|
||||
AddCategoryMapping(32, TorznabCatType.TVAnime); // SERIES ANIME
|
||||
|
||||
// Documentaries
|
||||
AddCategoryMapping(12, TorznabCatType.TVDocumentary); // DOCS
|
||||
|
||||
// Music
|
||||
AddCategoryMapping(20, TorznabCatType.AudioVideo); // CONCERT
|
||||
|
||||
// Other
|
||||
AddCategoryMapping(21, TorznabCatType.PC); // PC
|
||||
AddCategoryMapping(22, TorznabCatType.PCMac); // PC
|
||||
AddCategoryMapping(25, TorznabCatType.PCGames); // GAMES
|
||||
AddCategoryMapping(26, TorznabCatType.ConsoleXbox360); // GAMES
|
||||
AddCategoryMapping(28, TorznabCatType.ConsoleWii); // GAMES
|
||||
AddCategoryMapping(27, TorznabCatType.ConsolePS3); // GAMES
|
||||
AddCategoryMapping(29, TorznabCatType.ConsoleNDS); // GAMES
|
||||
AddCategoryMapping(24, TorznabCatType.BooksEbook); // EBOOKS
|
||||
AddCategoryMapping(96, TorznabCatType.BooksEbook); // EBOOKS MAGAZINES
|
||||
AddCategoryMapping(99, TorznabCatType.BooksEbook); // EBOOKS ANIME
|
||||
AddCategoryMapping(23, TorznabCatType.PCPhoneAndroid); // ANDROID
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure our Provider
|
||||
/// </summary>
|
||||
/// <param name="configJson">Our params in Json</param>
|
||||
/// <returns>Configuration state</returns>
|
||||
#pragma warning disable 1998
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
#pragma warning restore 1998
|
||||
{
|
||||
// Provider not yet configured
|
||||
IsConfigured = false;
|
||||
|
||||
// Retrieve config values set by Jackett's user
|
||||
ConfigData.LoadValuesFromJson(configJson);
|
||||
|
||||
// Check & Validate Config
|
||||
ValidateConfig();
|
||||
|
||||
// Setting our data for a better emulated browser (maximum security)
|
||||
// TODO: Encoded Content not supported by Jackett at this time
|
||||
// emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
|
||||
|
||||
// Clean headers
|
||||
EmulatedBrowserHeaders.Clear();
|
||||
|
||||
// Inject headers
|
||||
EmulatedBrowserHeaders.Add("Accept", "application/json-rpc, application/json");
|
||||
EmulatedBrowserHeaders.Add("Content-Type", "application/json-rpc");
|
||||
|
||||
// Tracker is now configured
|
||||
IsConfigured = true;
|
||||
|
||||
// Saving data
|
||||
SaveConfig();
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute our search query
|
||||
/// </summary>
|
||||
/// <param name="query">Query</param>
|
||||
/// <returns>Releases</returns>
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchTerm = query.GetQueryString();
|
||||
|
||||
// Check cache first so we don't query the server (if search term used or not in dev mode)
|
||||
if(!DevMode && !string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
lock (cache)
|
||||
{
|
||||
// Remove old cache items
|
||||
CleanCache();
|
||||
|
||||
// Search in cache
|
||||
var cachedResult = cache.FirstOrDefault(i => i.Query == searchTerm);
|
||||
if (cachedResult != null)
|
||||
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
// Build our query
|
||||
var request = BuildQuery(searchTerm, query, ApiEndpoint);
|
||||
|
||||
// Getting results & Store content
|
||||
var results = await QueryExec(request);
|
||||
|
||||
try
|
||||
{
|
||||
// Deserialize our Json Response
|
||||
var xthorResponse = JsonConvert.DeserializeObject<XthorResponse>(results.Content);
|
||||
|
||||
// Check Tracker's State
|
||||
CheckApiState(xthorResponse.error);
|
||||
|
||||
// If contains torrents
|
||||
if (xthorResponse.torrents != null)
|
||||
{
|
||||
// Adding each torrent row to releases
|
||||
releases.AddRange(xthorResponse.torrents.Select(torrent => new ReleaseInfo
|
||||
{
|
||||
// Mapping data
|
||||
Category = MapTrackerCatToNewznab(torrent.category.ToString()),
|
||||
Title = torrent.name, Seeders = torrent.seeders,
|
||||
Peers = torrent.seeders + torrent.leechers,
|
||||
MinimumRatio = 1,
|
||||
MinimumSeedTime = 345600,
|
||||
PublishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.added),
|
||||
Size = torrent.size,
|
||||
Guid = new Uri(TorrentDescriptionUrl.Replace("{id}", torrent.id.ToString())),
|
||||
Comments = new Uri(TorrentCommentUrl.Replace("{id}", torrent.id.ToString())),
|
||||
Link = new Uri(torrent.download_link)
|
||||
}));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
|
||||
}
|
||||
|
||||
// Return found releases
|
||||
return releases;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Response from Tracker's API
|
||||
/// </summary>
|
||||
public class XthorResponse
|
||||
{
|
||||
public XthorError error { get; set; }
|
||||
public XthorUser user { get; set; }
|
||||
public List<XthorTorrent> torrents { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State of API
|
||||
/// </summary>
|
||||
public class XthorError
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string descr { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User Informations
|
||||
/// </summary>
|
||||
public class XthorUser
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string username { get; set; }
|
||||
public long uploaded { get; set; }
|
||||
public long downloaded { get; set; }
|
||||
public int uclass { get; set; } // Class is a reserved keyword.
|
||||
public decimal bonus_point { get; set; }
|
||||
public int hits_and_run { get; set; }
|
||||
public string avatar_url { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Torrent Informations
|
||||
/// </summary>
|
||||
public class XthorTorrent
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int category { get; set; }
|
||||
public int seeders { get; set; }
|
||||
public int leechers { get; set; }
|
||||
public string name { get; set; }
|
||||
public int times_completed { get; set; }
|
||||
public long size { get; set; }
|
||||
public int added { get; set; }
|
||||
public int freeleech { get; set; }
|
||||
public int numfiles { get; set; }
|
||||
public string release_group { get; set; }
|
||||
public string download_link { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build query to process
|
||||
/// </summary>
|
||||
/// <param name="term">Term to search</param>
|
||||
/// <param name="query">Torznab Query for categories mapping</param>
|
||||
/// <param name="url">Search url for provider</param>
|
||||
/// <returns>URL to query for parsing and processing results</returns>
|
||||
private string BuildQuery(string term, TorznabQuery query, string url)
|
||||
{
|
||||
var parameters = new NameValueCollection();
|
||||
var categoriesList = MapTorznabCapsToTrackers(query);
|
||||
|
||||
// Passkey
|
||||
parameters.Add("passkey", ConfigData.PassKey.Value);
|
||||
|
||||
// If search term provided
|
||||
if (!string.IsNullOrWhiteSpace(term))
|
||||
{
|
||||
// Add search term
|
||||
// ReSharper disable once AssignNullToNotNullAttribute
|
||||
parameters.Add("search", HttpUtility.UrlEncode(term));
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters.Add("search", string.Empty);
|
||||
// Showing all torrents (just for output function)
|
||||
term = "all";
|
||||
}
|
||||
|
||||
// Loop on Categories needed
|
||||
switch (categoriesList.Count)
|
||||
{
|
||||
case 0:
|
||||
// No category
|
||||
parameters.Add("category", string.Empty);
|
||||
break;
|
||||
case 1:
|
||||
// One category
|
||||
parameters.Add("category", categoriesList[0]);
|
||||
break;
|
||||
default:
|
||||
// Multiple Categories
|
||||
string categories = null;
|
||||
foreach (var category in categoriesList)
|
||||
{
|
||||
// Initiate our categories parameter
|
||||
if (categoriesList.First() == category)
|
||||
{
|
||||
categories = categoriesList[0];
|
||||
}
|
||||
// Adding next categories
|
||||
categories += "+" + category;
|
||||
}
|
||||
// Add categories
|
||||
if (categories != null) parameters.Add("category", categories);
|
||||
break;
|
||||
}
|
||||
|
||||
// If Only Freeleech Enabled
|
||||
if (ConfigData.Freeleech.Value)
|
||||
{
|
||||
parameters.Add("freeleech", "1");
|
||||
}
|
||||
|
||||
// Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong category param)
|
||||
url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
|
||||
|
||||
Output("\nBuilded query for \"" + term + "\"... " + url);
|
||||
|
||||
// Return our search url
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switch Method for Querying
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> QueryExec(string request)
|
||||
{
|
||||
WebClientStringResult results;
|
||||
|
||||
// Switch in we are in DEV mode with Hard Drive Cache or not
|
||||
if (DevMode && CacheMode)
|
||||
{
|
||||
// Check Cache before querying and load previous results if available
|
||||
results = await QueryCache(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Querying tracker directly
|
||||
results = await QueryTracker(request);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Torrents Page from Cache by Query Provided
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> QueryCache(string request)
|
||||
{
|
||||
WebClientStringResult results;
|
||||
|
||||
// Create Directory if not exist
|
||||
System.IO.Directory.CreateDirectory(Directory);
|
||||
|
||||
// Clean Storage Provider Directory from outdated cached queries
|
||||
CleanCacheStorage();
|
||||
|
||||
// Create fingerprint for request
|
||||
string file = Directory + request.GetHashCode() + ".json";
|
||||
|
||||
// Checking modes states
|
||||
if (System.IO.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));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No cached file found, querying tracker directly
|
||||
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));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Torrents Page from Tracker by Query Provided
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> QueryTracker(string request)
|
||||
{
|
||||
// Cache mode not enabled or cached file didn't exist for our query
|
||||
Output("\nQuerying tracker for results....");
|
||||
|
||||
// Build WebRequest for index
|
||||
var myIndexRequest = new WebRequest()
|
||||
{
|
||||
Type = RequestType.GET,
|
||||
Url = request,
|
||||
Headers = EmulatedBrowserHeaders
|
||||
};
|
||||
|
||||
// Request our first page
|
||||
var results = await webclient.GetString(myIndexRequest);
|
||||
|
||||
// Return results from tracker
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check API's state
|
||||
/// </summary>
|
||||
/// <param name="state">State of API</param>
|
||||
private void CheckApiState(XthorError state)
|
||||
{
|
||||
// Switch on state
|
||||
switch (state.code)
|
||||
{
|
||||
case 0:
|
||||
// Everything OK
|
||||
Output("\nAPI State : Everything OK ... -> " + state.descr);
|
||||
break;
|
||||
case 1:
|
||||
// Passkey not found
|
||||
Output("\nAPI State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
|
||||
throw new Exception("API State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
|
||||
case 2:
|
||||
// No results
|
||||
Output("\nAPI State : No results for query ... -> " + state.descr);
|
||||
break;
|
||||
case 3:
|
||||
// Power Saver
|
||||
Output("\nAPI State : Power Saver mode, only cached query with no parameters available ... -> " + state.descr);
|
||||
break;
|
||||
case 4:
|
||||
// DDOS Attack, API disabled
|
||||
Output("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
|
||||
throw new Exception("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
|
||||
default:
|
||||
// Unknown state
|
||||
Output("\nAPI State : Unknown state, aborting querying ... -> " + state.descr);
|
||||
throw new Exception("API State : Unknown state, aborting querying ... -> " + state.descr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean Hard Drive Cache Storage
|
||||
/// </summary>
|
||||
/// <param name="force">Force Provider Folder deletion</param>
|
||||
private void CleanCacheStorage(bool force = false)
|
||||
{
|
||||
// Check cleaning method
|
||||
if(force)
|
||||
{
|
||||
// Deleting Provider Storage folder and all files recursively
|
||||
Output("\nDeleting Provider Storage folder and all files recursively ...");
|
||||
|
||||
// Check if directory exist
|
||||
if(System.IO.Directory.Exists(Directory))
|
||||
{
|
||||
// Delete storage directory of provider
|
||||
System.IO.Directory.Delete(Directory, true);
|
||||
Output("-> Storage folder deleted successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// No directory, so nothing to do
|
||||
Output("-> No Storage folder found for this provider !");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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))
|
||||
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
|
||||
.ToList()
|
||||
.ForEach(f => {
|
||||
Output("Deleting cached file << " + f.Name + " >> ... done.");
|
||||
f.Delete();
|
||||
i++;
|
||||
});
|
||||
|
||||
// Inform on what was cleaned during process
|
||||
if(i > 0) {
|
||||
Output("-> Deleted " + i + " cached files during cleaning.");
|
||||
}
|
||||
else {
|
||||
Output("-> Nothing deleted during cleaning.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output message for logging or developpment (console)
|
||||
/// </summary>
|
||||
/// <param name="message">Message to output</param>
|
||||
/// <param name="level">Level for Logger</param>
|
||||
private void Output(string message, string level = "debug")
|
||||
{
|
||||
// Check if we are in dev mode
|
||||
if(DevMode)
|
||||
{
|
||||
// Output message to console
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send message to logger with level
|
||||
switch (level)
|
||||
{
|
||||
default:
|
||||
goto case "debug";
|
||||
case "debug":
|
||||
// Only if Debug Level Enabled on Jackett
|
||||
if (Engine.Logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug(message);
|
||||
}
|
||||
break;
|
||||
case "info":
|
||||
logger.Info(message);
|
||||
break;
|
||||
case "error":
|
||||
logger.Error(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate Config entered by user on Jackett
|
||||
/// </summary>
|
||||
private void ValidateConfig()
|
||||
{
|
||||
Output("\nValidating Settings ... \n");
|
||||
|
||||
// Check Passkey Setting
|
||||
if (string.IsNullOrEmpty(ConfigData.PassKey.Value))
|
||||
{
|
||||
throw new ExceptionWithConfigData("You must provide your passkey for this tracker to be allowed to use API !", ConfigData);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Validated Setting -- PassKey (auth) => " + ConfigData.PassKey.Value);
|
||||
}
|
||||
|
||||
// Check Dev Cache Settings
|
||||
if (ConfigData.HardDriveCache.Value)
|
||||
{
|
||||
Output("\nValidated Setting -- DEV Hard Drive Cache enabled");
|
||||
|
||||
// Check if Dev Mode enabled !
|
||||
if (!ConfigData.DevMode.Value)
|
||||
{
|
||||
throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
|
||||
}
|
||||
|
||||
// Check Cache Keep Time Setting
|
||||
if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
|
||||
{
|
||||
try
|
||||
{
|
||||
Output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete cache if previously existed
|
||||
CleanCacheStorage(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,6 +186,8 @@
|
||||
<Compile Include="Controllers\TorznabController.cs" />
|
||||
<Compile Include="Controllers\DownloadController.cs" />
|
||||
<Compile Include="Engine.cs" />
|
||||
<Compile Include="Indexers\MyAnonamouse.cs" />
|
||||
<Compile Include="Indexers\Xthor.cs" />
|
||||
<Compile Include="Indexers\PhxBit.cs" />
|
||||
<Compile Include="Indexers\AlphaRatio.cs" />
|
||||
<Compile Include="Indexers\BitSoup.cs" />
|
||||
@@ -215,20 +217,22 @@
|
||||
<Compile Include="Indexers\ImmortalSeed.cs" />
|
||||
<Compile Include="Indexers\FileList.cs" />
|
||||
<Compile Include="Indexers\Abstract\AvistazTracker.cs" />
|
||||
<Compile Include="Indexers\FrenchADN.cs" />
|
||||
<Compile Include="Indexers\FrenchAdn.cs" />
|
||||
<Compile Include="Indexers\TransmitheNet.cs" />
|
||||
<Compile Include="Indexers\WiHD.cs" />
|
||||
<Compile Include="Indexers\XSpeeds.cs" />
|
||||
<Compile Include="Models\GitHub\Asset.cs" />
|
||||
<Compile Include="Models\GitHub\Release.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\ConfigurationDataFrenchADN.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataFrenchAdn.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataWiHD.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilter.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAPIKey.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSSAndDisplay.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithAlternateLink.cs" />
|
||||
<Compile Include="Models\ManualSearchResult.cs" />
|
||||
<Compile Include="Indexers\TVChaosUK.cs" />
|
||||
<Compile Include="Indexers\NCore.cs" />
|
||||
@@ -238,6 +242,7 @@
|
||||
<Compile Include="Indexers\Pretome.cs" />
|
||||
<Compile Include="Indexers\PrivateHD.cs" />
|
||||
<Compile Include="Indexers\SceneAccess.cs" />
|
||||
<Compile Include="Indexers\SceneFZ.cs" />
|
||||
<Compile Include="Indexers\SceneTime.cs" />
|
||||
<Compile Include="Indexers\SpeedCD.cs" />
|
||||
<Compile Include="Indexers\TorrentDay.cs" />
|
||||
@@ -442,6 +447,12 @@
|
||||
<Content Include="Content\login.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\myanonamouse.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\xthor.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\phxbit.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -514,6 +525,9 @@
|
||||
<Content Include="Content\logos\sceneaccess.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\scenefz.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\scenetime.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
class ConfigurationDataFrenchADN : ConfigurationData
|
||||
internal class ConfigurationDataFrenchAdn : ConfigurationData
|
||||
{
|
||||
public DisplayItem CredentialsWarning { get; private set; }
|
||||
public StringItem Username { get; private set; }
|
||||
@@ -16,7 +16,7 @@
|
||||
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 HeaderDnt { get; private set; }
|
||||
public BoolItem HeaderUpgradeInsecure { get; private set; }
|
||||
public StringItem HeaderUserAgent { get; private set; }
|
||||
public DisplayItem DevWarning { get; private set; }
|
||||
@@ -24,8 +24,7 @@
|
||||
public BoolItem HardDriveCache { get; private set; }
|
||||
public StringItem HardDriveCacheKeepTime { get; private set; }
|
||||
|
||||
public ConfigurationDataFrenchADN()
|
||||
: base()
|
||||
public ConfigurationDataFrenchAdn()
|
||||
{
|
||||
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 = "" };
|
||||
@@ -41,7 +40,7 @@
|
||||
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 };
|
||||
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" };
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
class ConfigurationDataXthor : ConfigurationData
|
||||
{
|
||||
public DisplayItem CredentialsWarning { get; private set; }
|
||||
public StringItem PassKey { get; set; }
|
||||
public DisplayItem PagesWarning { get; private set; }
|
||||
public BoolItem Freeleech { 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 ConfigurationDataXthor()
|
||||
: base()
|
||||
{
|
||||
CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>PassKey</b> is your private key on your account</li></ul>") { Name = "Credentials" };
|
||||
PassKey = new StringItem { Name = "PassKey", Value = "" };
|
||||
PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li></ul>") { Name = "Preferences" };
|
||||
Freeleech = new BoolItem() { Name = "Freeleech Only (Optional)", Value = false };
|
||||
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" };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataBasicLoginWithAlternateLink : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public DisplayItem Instructions { get; private set; }
|
||||
public StringItem AlternateLink { get; set; }
|
||||
|
||||
public ConfigurationDataBasicLoginWithAlternateLink(string instructionMessageOptional = null)
|
||||
{
|
||||
Username = new StringItem { Name = "Username" };
|
||||
Password = new StringItem { Name = "Password" };
|
||||
Instructions = new DisplayItem(instructionMessageOptional) { Name = "" };
|
||||
AlternateLink = new StringItem { Name = "Alternate Link" };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -213,6 +213,11 @@ namespace Jackett.Services
|
||||
/// <returns></returns>
|
||||
public static string GetAppDataFolderStatic()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Startup.CustomDataFolder))
|
||||
{
|
||||
return Startup.CustomDataFolder;
|
||||
}
|
||||
|
||||
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
|
||||
|
||||
@@ -58,6 +58,12 @@ namespace Jackett
|
||||
set;
|
||||
}
|
||||
|
||||
public static string CustomDataFolder
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static string BasePath
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace Jackett.Utils.Clients
|
||||
|
||||
private async Task<WebClientByteResult> Run(WebRequest webRequest)
|
||||
{
|
||||
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
|
||||
|
||||
var cookies = new CookieContainer();
|
||||
if (!string.IsNullOrEmpty(webRequest.Cookies))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user