mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Abstracted & unified indexer config logic (logins are now saved), implemented indexer config migrations, fixed nCore implementation
This commit is contained in:
@@ -246,22 +246,24 @@ function newConfigModal(title, config, caps) {
|
||||
}
|
||||
|
||||
function getConfigModalJson(configForm) {
|
||||
var configJson = {};
|
||||
var configJson = [];
|
||||
configForm.find(".config-setup-form").children().each(function (i, el) {
|
||||
$el = $(el);
|
||||
var type = $el.data("type");
|
||||
var id = $el.data("id");
|
||||
var itemEntry = { id: id };
|
||||
switch (type) {
|
||||
case "hiddendata":
|
||||
configJson[id] = $el.find(".setup-item-hiddendata input").val();
|
||||
itemEntry.value = $el.find(".setup-item-hiddendata input").val();
|
||||
break;
|
||||
case "inputstring":
|
||||
configJson[id] = $el.find(".setup-item-inputstring input").val();
|
||||
itemEntry.value = $el.find(".setup-item-inputstring input").val();
|
||||
break;
|
||||
case "inputbool":
|
||||
configJson[id] = $el.find(".setup-item-inputbool input").is(":checked");
|
||||
itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked");
|
||||
break;
|
||||
}
|
||||
configJson.push(itemEntry)
|
||||
});
|
||||
return configJson;
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ namespace Jackett
|
||||
public string Cookies { get; private set; }
|
||||
public string Referer { get; private set; }
|
||||
public HttpMethod Method { get; private set; }
|
||||
public Dictionary<string, string> PostData { get; set; }
|
||||
public IEnumerable<KeyValuePair<string, string>> PostData { get; set; }
|
||||
|
||||
public CurlRequest(HttpMethod method, string url, string cookies = null, string referer = null)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ namespace Jackett
|
||||
{
|
||||
public List<string[]> HeaderList { get; private set; }
|
||||
public byte[] Content { get; private set; }
|
||||
public HttpStatusCode Status { get; private set;}
|
||||
public HttpStatusCode Status { get; private set; }
|
||||
public string Cookies { set; get; }
|
||||
|
||||
public CurlResponse(List<string[]> headers, byte[] content, HttpStatusCode s, string cookies)
|
||||
@@ -57,7 +57,7 @@ namespace Jackett
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<CurlResponse> PostAsync(string url, Dictionary<string, string> formData, string cookies = null, string referer = null)
|
||||
public static async Task<CurlResponse> PostAsync(string url, IEnumerable<KeyValuePair<string, string>> formData, string cookies = null, string referer = null)
|
||||
{
|
||||
var curlRequest = new CurlRequest(HttpMethod.Post, url, cookies, referer);
|
||||
curlRequest.PostData = formData;
|
||||
@@ -86,7 +86,7 @@ namespace Jackett
|
||||
easy.BufferSize = 64 * 1024;
|
||||
easy.UserAgent = BrowserUtil.ChromeUserAgent;
|
||||
easy.FollowLocation = false;
|
||||
easy.ConnectTimeout = 20;
|
||||
easy.ConnectTimeout = 20;
|
||||
|
||||
easy.WriteFunction = (byte[] buf, int size, int nmemb, object data) =>
|
||||
{
|
||||
@@ -109,7 +109,7 @@ namespace Jackett
|
||||
if (curlRequest.Method == HttpMethod.Post)
|
||||
{
|
||||
easy.Post = true;
|
||||
var postString = new FormUrlEncodedContent(curlRequest.PostData).ReadAsStringAsync().Result;
|
||||
var postString = StringUtil.PostDataFromDict(curlRequest.PostData);
|
||||
easy.PostFields = postString;
|
||||
easy.PostFieldSize = Encoding.UTF8.GetByteCount(postString);
|
||||
}
|
||||
@@ -125,7 +125,7 @@ namespace Jackett
|
||||
|
||||
easy.Perform();
|
||||
|
||||
if(easy.LastErrorCode != CurlCode.Ok)
|
||||
if (easy.LastErrorCode != CurlCode.Ok)
|
||||
{
|
||||
var message = "Error " + easy.LastErrorCode.ToString() + " " + easy.LastErrorDescription;
|
||||
if (null != OnErrorMessage)
|
||||
|
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett
|
||||
{
|
||||
|
@@ -14,6 +14,7 @@ using Jackett.Utils;
|
||||
using NLog;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils.Clients;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -31,16 +32,12 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
webclient = w;
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var incomingConfig = new ConfigurationDataBasicLogin();
|
||||
@@ -54,13 +51,13 @@ namespace Jackett.Indexers
|
||||
|
||||
// Do the login
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, string.Empty, true, SiteLink);
|
||||
await ConfigureIfOK(response.Cookies, response.Content!=null && response.Content.Contains("logout.php?"), () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
dom["#loginform > table"].Remove();
|
||||
var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
});
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php?"), () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
dom["#loginform > table"].Remove();
|
||||
var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
});
|
||||
}
|
||||
|
||||
void FillReleaseInfoFromJson(ReleaseInfo release, JObject r)
|
||||
|
@@ -25,7 +25,13 @@ namespace Jackett.Indexers
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "user/login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?filter_cat[1]=1"; } }
|
||||
public bool AllowRaws { get; private set; }
|
||||
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
||||
|
||||
new ConfigurationDataAnimeBytes configData
|
||||
{
|
||||
get { return (ConfigurationDataAnimeBytes)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l)
|
||||
: base(name: "AnimeBytes",
|
||||
@@ -34,19 +40,14 @@ namespace Jackett.Indexers
|
||||
manager: i,
|
||||
client: client,
|
||||
caps: new TorznabCapabilities(TorznabCatType.Anime),
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataAnimeBytes())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLoginAnimeBytes());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLoginAnimeBytes();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
lock (cache)
|
||||
{
|
||||
@@ -59,18 +60,18 @@ namespace Jackett.Indexers
|
||||
Url = LoginUrl
|
||||
});
|
||||
|
||||
CQ loginPageDom =loginPage.Content;
|
||||
CQ loginPageDom = loginPage.Content;
|
||||
var csrfToken = loginPageDom["input[name=\"csrf_token\"]"].Last();
|
||||
|
||||
// Build login form
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "csrf_token", csrfToken.Attr("value") },
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "keeplogged_sent", "true" },
|
||||
{ "keeplogged", "on" },
|
||||
{ "login", "Log In!" }
|
||||
};
|
||||
};
|
||||
|
||||
// Do the login
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
@@ -86,32 +87,26 @@ namespace Jackett.Indexers
|
||||
// Follow the redirect
|
||||
await FollowIfRedirect(response, request.Url, SearchUrl);
|
||||
|
||||
if (!(response.Content != null && response.Content.Contains("/user/logout")))
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/user/logout"), () =>
|
||||
{
|
||||
// Their login page appears to be broken and just gives a 500 error.
|
||||
throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", (ConfigurationData)config);
|
||||
}
|
||||
else
|
||||
{
|
||||
cookieHeader = response.Cookies;
|
||||
AllowRaws = config.IncludeRaw.Value;
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["cookies"] = cookieHeader;
|
||||
configSaveData["raws"] = AllowRaws;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
}
|
||||
throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", configData);
|
||||
});
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
// The old config used an array - just fail to load it
|
||||
if (!(jsonConfig["cookies"] is JArray))
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
cookieHeader = (string)jsonConfig["cookies"];
|
||||
AllowRaws = jsonConfig["raws"].Value<bool>();
|
||||
configData.CookieHeader.Value = jsonConfig.Value<string>("cookies");
|
||||
configData.IncludeRaw.Value = jsonConfig.Value<bool>("raws");
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
@@ -257,7 +252,7 @@ namespace Jackett.Indexers
|
||||
release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);
|
||||
|
||||
var infoLink = links.Get(1);
|
||||
release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
|
||||
release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
|
||||
release.Guid = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
|
||||
release.Link = new Uri(downloadLink.Attributes.GetAttribute("href"), UriKind.Relative);
|
||||
|
||||
@@ -337,7 +332,7 @@ namespace Jackett.Indexers
|
||||
var response = await webclient.GetBytes(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = SiteLink + link.ToString(),
|
||||
Cookies = cookieHeader
|
||||
Cookies = CookieHeader
|
||||
});
|
||||
|
||||
return response.Content;
|
||||
|
@@ -13,6 +13,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -20,11 +21,17 @@ namespace Jackett.Indexers
|
||||
|
||||
public class BB : BaseIndexer, IIndexer
|
||||
{
|
||||
private string BaseUrl { get { return StringUtil.FromBase64("aHR0cHM6Ly9iYWNvbmJpdHMub3JnLw=="); } }
|
||||
private string BaseUrl { get { return StringUtil.FromBase64("aHR0cHM6Ly9iYWNvbmJpdHMub3JnLw=="); } }
|
||||
private Uri BaseUri { get { return new Uri(BaseUrl); } }
|
||||
private string LoginUrl { get { return BaseUri + "login.php"; } }
|
||||
private string SearchUrl { get { return BaseUri + "torrents.php?searchstr={0}&searchtags=&tags_type=0&order_by=s3&order_way=desc&disablegrouping=1&filter_cat%5B10%5D=1"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BB(IIndexerManagerService i, Logger l, IWebClient w)
|
||||
: base(name: "bB",
|
||||
description: "bB",
|
||||
@@ -32,22 +39,17 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 },
|
||||
{ "keeplogged", "1" },
|
||||
{ "login", "Log In!" }
|
||||
};
|
||||
@@ -64,7 +66,7 @@ namespace Jackett.Indexers
|
||||
messages.Add(child.Cq().Text().Trim());
|
||||
}
|
||||
var message = string.Join(" ", messages);
|
||||
throw new ExceptionWithConfigData(message, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(message, configData);
|
||||
|
||||
});
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -21,6 +22,12 @@ namespace Jackett.Indexers
|
||||
public string SearchUrl { get { return SiteLink + "browse.php?only=0&hentai=1&incomplete=1&lossless=1&hd=1&multiaudio=1&bonus=1&c1=1&reorder=1&q="; } }
|
||||
public string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BakaBT(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "BakaBT",
|
||||
description: "Anime Community",
|
||||
@@ -28,19 +35,14 @@ namespace Jackett.Indexers
|
||||
caps: new TorznabCapabilities(TorznabCatType.Anime),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var loginForm = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
@@ -49,8 +51,8 @@ namespace Jackett.Indexers
|
||||
});
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "returnto", "/index.php" }
|
||||
};
|
||||
|
||||
@@ -61,7 +63,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = responseContent;
|
||||
var messageEl = dom[".error"].First();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using AutoMapper;
|
||||
using System.Threading;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -28,11 +29,17 @@ namespace Jackett.Indexers
|
||||
protected static List<CachedQueryResult> cache = new List<CachedQueryResult>();
|
||||
protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
|
||||
protected IWebClient webclient;
|
||||
protected string cookieHeader = "";
|
||||
protected string CookieHeader
|
||||
{
|
||||
get { return configData.CookieHeader.Value; }
|
||||
set { configData.CookieHeader.Value = value; }
|
||||
}
|
||||
|
||||
protected ConfigurationData configData;
|
||||
|
||||
private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
|
||||
|
||||
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, TorznabCapabilities caps = null)
|
||||
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, TorznabCapabilities caps = null)
|
||||
{
|
||||
if (!link.EndsWith("/"))
|
||||
throw new Exception("Site link must end with a slash.");
|
||||
@@ -44,17 +51,21 @@ namespace Jackett.Indexers
|
||||
indexerService = manager;
|
||||
webclient = client;
|
||||
|
||||
this.configData = configData;
|
||||
|
||||
if (caps == null)
|
||||
caps = TorznabCapsUtil.CreateDefaultTorznabTVCaps();
|
||||
TorznabCaps = caps;
|
||||
|
||||
}
|
||||
|
||||
protected int MapTrackerCatToNewznab(string input)
|
||||
{
|
||||
if (null != input) {
|
||||
if (null != input)
|
||||
{
|
||||
input = input.ToLowerInvariant();
|
||||
var mapping = categoryMapping.Where(m => m.TrackerCategory == input).FirstOrDefault();
|
||||
if(mapping!= null)
|
||||
if (mapping != null)
|
||||
{
|
||||
return mapping.NewzNabCategory;
|
||||
}
|
||||
@@ -67,15 +78,20 @@ namespace Jackett.Indexers
|
||||
return StringUtil.StripNonAlphaNumeric(type.Name.ToLowerInvariant());
|
||||
}
|
||||
|
||||
public void ResetBaseConfig()
|
||||
public virtual Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
cookieHeader = string.Empty;
|
||||
return Task.FromResult<ConfigurationData>(configData);
|
||||
}
|
||||
|
||||
public virtual void ResetBaseConfig()
|
||||
{
|
||||
CookieHeader = string.Empty;
|
||||
IsConfigured = false;
|
||||
}
|
||||
|
||||
protected void SaveConfig(JToken config)
|
||||
protected void SaveConfig()
|
||||
{
|
||||
indexerService.SaveConfig(this as IIndexer, config);
|
||||
indexerService.SaveConfig(this as IIndexer, configData.ToJson(forDisplay: false));
|
||||
}
|
||||
|
||||
protected void OnParseError(string results, Exception ex)
|
||||
@@ -125,55 +141,57 @@ namespace Jackett.Indexers
|
||||
{
|
||||
Url = overrideRedirectUrl ?? incomingResponse.RedirectingTo,
|
||||
Referer = referrer,
|
||||
Cookies = overrideCookies ?? cookieHeader
|
||||
Cookies = overrideCookies ?? CookieHeader
|
||||
});
|
||||
Mapper.Map(redirectedResponse, incomingResponse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void LoadCookieHeaderAndConfigure(JToken jsonConfig)
|
||||
protected void LoadLegacyCookieConfig(JToken jsonConfig)
|
||||
{
|
||||
cookieHeader = (string)jsonConfig["cookie_header"];
|
||||
if (!string.IsNullOrEmpty(cookieHeader))
|
||||
string legacyCookieHeader = (string)jsonConfig["cookie_header"];
|
||||
if (!string.IsNullOrEmpty(legacyCookieHeader))
|
||||
{
|
||||
IsConfigured = true;
|
||||
CookieHeader = legacyCookieHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy cookie key
|
||||
var jcookes = jsonConfig["cookies"];
|
||||
if (jcookes is JArray) {
|
||||
var array = (JArray)jsonConfig["cookies"];
|
||||
cookieHeader = string.Empty;
|
||||
var jcookies = jsonConfig["cookies"];
|
||||
if (jcookies is JArray)
|
||||
{
|
||||
var array = (JArray)jcookies;
|
||||
legacyCookieHeader = string.Empty;
|
||||
for (int i = 0; i < array.Count; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
cookieHeader += "; ";
|
||||
cookieHeader += array[i];
|
||||
legacyCookieHeader += "; ";
|
||||
legacyCookieHeader += array[i];
|
||||
}
|
||||
CookieHeader = legacyCookieHeader;
|
||||
}
|
||||
else
|
||||
cookieHeader = (string)jsonConfig["cookies"];
|
||||
|
||||
if (!string.IsNullOrEmpty(cookieHeader))
|
||||
else if (jcookies != null)
|
||||
{
|
||||
IsConfigured = true;
|
||||
CookieHeader = (string)jcookies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void SaveCookieHeaderAndConfigure()
|
||||
{
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["cookie_header"] = cookieHeader;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = !string.IsNullOrEmpty(cookieHeader);
|
||||
}
|
||||
|
||||
public virtual void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
LoadCookieHeaderAndConfigure(jsonConfig);
|
||||
if (jsonConfig is JArray)
|
||||
{
|
||||
configData.LoadValuesFromJson(jsonConfig);
|
||||
IsConfigured = true;
|
||||
}
|
||||
// read and upgrade old settings file format
|
||||
else if (jsonConfig is Object)
|
||||
{
|
||||
LoadLegacyCookieConfig(jsonConfig);
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
}
|
||||
}
|
||||
|
||||
public async virtual Task<byte[]> Download(Uri link)
|
||||
@@ -208,7 +226,7 @@ namespace Jackett.Indexers
|
||||
{
|
||||
Url = url,
|
||||
Type = RequestType.GET,
|
||||
Cookies = cookieHeader,
|
||||
Cookies = CookieHeader,
|
||||
Referer = referer
|
||||
};
|
||||
|
||||
@@ -229,7 +247,7 @@ namespace Jackett.Indexers
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(string.Format("On attempt {0} checking for results from {1}: {2}", (i + 1), DisplayName, e.Message));
|
||||
lastException= e;
|
||||
lastException = e;
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
@@ -243,7 +261,7 @@ namespace Jackett.Indexers
|
||||
{
|
||||
Url = url,
|
||||
Type = RequestType.GET,
|
||||
Cookies = cookieOverride ?? cookieHeader
|
||||
Cookies = cookieOverride ?? CookieHeader
|
||||
};
|
||||
|
||||
if (cookieOverride != null)
|
||||
@@ -251,26 +269,26 @@ namespace Jackett.Indexers
|
||||
return await webclient.GetBytes(request);
|
||||
}
|
||||
|
||||
protected async Task<WebClientStringResult> PostDataWithCookies(string url, Dictionary<string, string> data, string cookieOverride = null)
|
||||
protected async Task<WebClientStringResult> PostDataWithCookies(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null)
|
||||
{
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = url,
|
||||
Type = RequestType.POST,
|
||||
Cookies = cookieOverride ?? cookieHeader,
|
||||
Cookies = cookieOverride ?? CookieHeader,
|
||||
PostData = data
|
||||
};
|
||||
return await webclient.GetString(request);
|
||||
}
|
||||
|
||||
protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, Dictionary<string, string> data, string cookieOverride = null)
|
||||
protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null)
|
||||
{
|
||||
Exception lastException = null;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await PostDataWithCookies(url,data,cookieOverride);
|
||||
return await PostDataWithCookies(url, data, cookieOverride);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -283,7 +301,7 @@ namespace Jackett.Indexers
|
||||
throw lastException;
|
||||
}
|
||||
|
||||
protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, Dictionary<string, string> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer =null)
|
||||
protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, IEnumerable<KeyValuePair<string, string>> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer = null)
|
||||
{
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
@@ -313,8 +331,9 @@ namespace Jackett.Indexers
|
||||
{
|
||||
if (isLoggedin)
|
||||
{
|
||||
cookieHeader = cookies;
|
||||
SaveCookieHeaderAndConfigure();
|
||||
CookieHeader = cookies;
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -324,9 +343,9 @@ namespace Jackett.Indexers
|
||||
|
||||
public virtual IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> results)
|
||||
{
|
||||
foreach(var result in results)
|
||||
foreach (var result in results)
|
||||
{
|
||||
if(query.Categories.Length == 0 || query.Categories.Contains(result.Category) || result.Category == 0 || TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category))
|
||||
if (query.Categories.Length == 0 || query.Categories.Contains(result.Category) || result.Category == 0 || TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category))
|
||||
{
|
||||
yield return result;
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -21,6 +22,12 @@ namespace Jackett.Indexers
|
||||
private string SearchUrl { get { return SiteLink + "browse.php?c40=1&c44=1&c48=1&c89=1&c46=1&c45=1&searchin=title&incldead=0&search={0}"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php?torrent={0}"; } }
|
||||
|
||||
new ConfigurationDataCookie configData
|
||||
{
|
||||
get { return (ConfigurationDataCookie)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BeyondHD(IIndexerManagerService i, Logger l, IWebClient w)
|
||||
: base(name: "BeyondHD",
|
||||
description: "Without BeyondHD, your HDTV is just a TV",
|
||||
@@ -28,31 +35,25 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataCookie())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataCookie());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataCookie();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
cookieHeader = config.CookieHeader;
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var response = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = SiteLink,
|
||||
Cookies = cookieHeader
|
||||
Cookies = configData.Cookie.Value
|
||||
});
|
||||
|
||||
await ConfigureIfOK(cookieHeader, response.Content.Contains("logout.php"), () =>
|
||||
await ConfigureIfOK(CookieHeader, response.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
throw new ExceptionWithConfigData("Invalid cookie header", (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData("Invalid cookie header", configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?cat=0&search="; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php?/{0}/dl.torrent"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BitHdtv(IIndexerManagerService i, Logger l, IWebClient w)
|
||||
: base(name: "BIT-HDTV",
|
||||
description: "Home of high definition invites",
|
||||
@@ -30,24 +37,19 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 }
|
||||
};
|
||||
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink);
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php"), () =>
|
||||
@@ -57,7 +59,7 @@ namespace Jackett.Indexers
|
||||
messageEl.Children("a").Remove();
|
||||
messageEl.Children("style").Remove();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,12 @@ namespace Jackett.Indexers
|
||||
private string CaptchaUrl { get { return SiteLink + "visual.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataCaptchaLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataCaptchaLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BitMeTV(IIndexerManagerService i, Logger l, IWebClient c)
|
||||
: base(name: "BitMeTV",
|
||||
description: "TV Episode specialty tracker",
|
||||
@@ -33,46 +39,45 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataCaptchaLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
public override async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
var response = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = LoginUrl
|
||||
});
|
||||
cookieHeader = response.Cookies;
|
||||
CookieHeader = response.Cookies;
|
||||
var captchaImage = await RequestBytesWithCookies(CaptchaUrl);
|
||||
var config = new BmtvConfig();
|
||||
config.CaptchaImage.Value = captchaImage.Content;
|
||||
config.CaptchaCookie.Value = captchaImage.Cookies;
|
||||
return (ConfigurationData)config;
|
||||
configData.CaptchaImage.Value = captchaImage.Content;
|
||||
configData.CaptchaCookie.Value = captchaImage.Cookies;
|
||||
return configData;
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new BmtvConfig();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "secimage", config.CaptchaText.Value }
|
||||
};
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "secimage", configData.CaptchaText.Value }
|
||||
};
|
||||
|
||||
var response = await RequestLoginAndFollowRedirect(LoginPost, pairs, config.CaptchaCookie.Value, true);
|
||||
var response = await RequestLoginAndFollowRedirect(LoginPost, pairs, configData.CaptchaCookie.Value, true);
|
||||
await ConfigureIfOK(response.Cookies, response.Content.Contains("/logout.php"), async () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
var messageEl = dom["table tr > td.embedded > h2"].Last();
|
||||
var errorMessage = messageEl.Text();
|
||||
var captchaImage = await RequestBytesWithCookies(CaptchaUrl);
|
||||
config.CaptchaImage.Value = captchaImage.Content;
|
||||
config.CaptchaText.Value = "";
|
||||
config.CaptchaCookie.Value = captchaImage.Cookies;
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
configData.CaptchaImage.Value = captchaImage.Content;
|
||||
configData.CaptchaText.Value = "";
|
||||
configData.CaptchaCookie.Value = captchaImage.Cookies;
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -8,9 +8,6 @@ using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
@@ -21,6 +18,12 @@ namespace Jackett.Indexers
|
||||
private string MainUrl { get { return SiteLink + "?section=INDEX"; } }
|
||||
private string SearchUrl { get { return SiteLink + "?section=TORRENTS&exact=1&name={0}&submit=GO"; } }
|
||||
|
||||
new ConfigurationDataCookie configData
|
||||
{
|
||||
get { return (ConfigurationDataCookie)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public FrenchTorrentDb(IIndexerManagerService i, Logger l, IWebClient c)
|
||||
: base(name: "FrenchTorrentDb",
|
||||
description: "One the biggest French Torrent Tracker",
|
||||
@@ -28,30 +31,24 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataCookie())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataUrl(SiteLink));
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(Newtonsoft.Json.Linq.JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLoginFrenchTorrentDb();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
var cookies = "WebsiteID=" + config.Cookie.Value;
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var response = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = MainUrl,
|
||||
Type = RequestType.GET,
|
||||
Cookies = cookies
|
||||
Cookies = configData.Cookie.Value
|
||||
});
|
||||
|
||||
await ConfigureIfOK(cookies, response.Content.Contains("/?section=LOGOUT"), () =>
|
||||
await ConfigureIfOK(configData.Cookie.Value, response.Content.Contains("/?section=LOGOUT"), () =>
|
||||
{
|
||||
throw new ExceptionWithConfigData("Failed to login", (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData("Failed to login", configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.UI.WebControls;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -26,6 +27,12 @@ namespace Jackett.Indexers
|
||||
private string LoginPostUrl { get { return SiteLink + "login.php?action=makelogin"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public Freshon(IIndexerManagerService i, Logger l, IWebClient c)
|
||||
: base(name: "FreshOnTV",
|
||||
description: "Our goal is to provide the latest stuff in the TV show domain",
|
||||
@@ -33,34 +40,29 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return await Task.FromResult< ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 }
|
||||
};
|
||||
|
||||
// Get inital cookies
|
||||
cookieHeader = string.Empty;
|
||||
var response = await RequestLoginAndFollowRedirect(LoginPostUrl, pairs, cookieHeader, true, null, LoginUrl);
|
||||
CookieHeader = string.Empty;
|
||||
var response = await RequestLoginAndFollowRedirect(LoginPostUrl, pairs, CookieHeader, true, null, LoginUrl);
|
||||
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/logout.php"), () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
var messageEl = dom[".error_text"];
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ using CsQuery;
|
||||
using System.Web;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Globalization;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -21,6 +22,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "index.php?page=login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "index.php?page=torrents&active=0&options=0&category=21%3B22&search={0}"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public HDSpace(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "HD-Space",
|
||||
description: "Sharing The Universe",
|
||||
@@ -28,25 +35,20 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "uid", config.Username.Value },
|
||||
{ "pwd", config.Password.Value }
|
||||
{ "uid", configData.Username.Value },
|
||||
{ "pwd", configData.Password.Value }
|
||||
};
|
||||
|
||||
// Send Post
|
||||
@@ -58,7 +60,7 @@ namespace Jackett.Indexers
|
||||
var remainingAttemptSpan = new Regex(string.Format(errorStr, "(.*?)")).Match(loginPage.Content).Groups[1].ToString();
|
||||
var attempts = Regex.Replace(remainingAttemptSpan, "<.*?>", String.Empty);
|
||||
var errorMessage = string.Format(errorStr, attempts);
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private const int MAXPAGES = 3;
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public HDTorrents(IIndexerManagerService i, Logger l, IWebClient w)
|
||||
: base(name: "HD-Torrents",
|
||||
description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.",
|
||||
@@ -30,24 +37,19 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var incomingConfig = new ConfigurationDataBasicLogin();
|
||||
incomingConfig.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "uid", incomingConfig.Username.Value },
|
||||
{ "pwd", incomingConfig.Password.Value }
|
||||
{ "uid", configData.Username.Value },
|
||||
{ "pwd", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl);
|
||||
@@ -55,7 +57,7 @@ namespace Jackett.Indexers
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("If your browser doesn't have javascript enabled"), () =>
|
||||
{
|
||||
var errorMessage = "Couldn't login";
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Jackett.Models;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@@ -15,6 +15,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -22,6 +23,12 @@ namespace Jackett.Indexers
|
||||
{
|
||||
private string BrowseUrl { get { return SiteLink + "t"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public IPTorrents(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "IPTorrents",
|
||||
description: "Always a step ahead.",
|
||||
@@ -29,7 +36,8 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
AddCategoryMapping(72, TorznabCatType.Movies);
|
||||
AddCategoryMapping(77, TorznabCatType.MoviesSD);
|
||||
@@ -74,18 +82,12 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(94, TorznabCatType.Comic);
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 }
|
||||
};
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
@@ -104,7 +106,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = response.Content;
|
||||
var messageEl = dom["body > div"].First();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
private string QueryString { get { return "?do=search&keywords={0}&search_type=t_name&category=0&include_dead_torrents=no"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public ImmortalSeed(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "ImmortalSeed",
|
||||
description: "ImmortalSeed",
|
||||
@@ -30,7 +37,8 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
AddCategoryMapping(32, TorznabCatType.Anime);
|
||||
AddCategoryMapping(47, TorznabCatType.TVSD);
|
||||
@@ -58,18 +66,12 @@ namespace Jackett.Indexers
|
||||
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 }
|
||||
};
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
@@ -88,7 +90,7 @@ namespace Jackett.Indexers
|
||||
{
|
||||
var tries = resultDom["#main tr:eq(1) td font"].First().Text();
|
||||
var errorMessage = "Incorrect username or password! " + tries + " tries remaining.";
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -24,6 +25,12 @@ namespace Jackett.Indexers
|
||||
private string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
|
||||
private string GuidUrl { get { return SiteLink + "torrents.php?torrentid="; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public MoreThanTV(IIndexerManagerService i, IWebClient c, Logger l)
|
||||
: base(name: "MoreThanTV",
|
||||
description: "ROMANIAN Private Torrent Tracker for TV / MOVIES, and the internal tracker for the release group DRACULA.",
|
||||
@@ -31,25 +38,20 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "login", "Log in" },
|
||||
{ "keeplogged", "1" }
|
||||
};
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "login", "Log in" },
|
||||
{ "keeplogged", "1" }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SearchUrl, SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php?"), () =>
|
||||
@@ -57,7 +59,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = result.Content;
|
||||
dom["#loginform > table"].Remove();
|
||||
var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,12 @@ namespace Jackett.Indexers
|
||||
private string LoginReferer { get { return SiteLink + "index.php?cat=1"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php?tags=&st=1&tf=all&cat%5B%5D=7&search={0}"; } }
|
||||
|
||||
new ConfigurationDataPinNumber configData
|
||||
{
|
||||
get { return (ConfigurationDataPinNumber)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public Pretome(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "PreToMe",
|
||||
description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
|
||||
@@ -28,27 +34,22 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
client: wc,
|
||||
manager: i,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataPinNumber())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new PretomeConfiguration());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new PretomeConfiguration();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "returnto", "%2F" },
|
||||
{ "login_pin", config.Pin.Value },
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "login_pin", configData.Pin.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "login", "Login" }
|
||||
};
|
||||
|
||||
@@ -56,16 +57,16 @@ namespace Jackett.Indexers
|
||||
var result = await PostDataWithCookies(LoginUrl, pairs, loginPage.Cookies);
|
||||
if (result.RedirectingTo == null)
|
||||
{
|
||||
throw new ExceptionWithConfigData("Login failed. Did you use the PIN number that pretome emailed you?", (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData("Login failed. Did you use the PIN number that pretome emailed you?", configData);
|
||||
}
|
||||
var loginCookies = result.Cookies;
|
||||
// Get result from redirect
|
||||
await FollowIfRedirect(result,LoginUrl,null, loginCookies);
|
||||
await FollowIfRedirect(result, LoginUrl, null, loginCookies);
|
||||
|
||||
await ConfigureIfOK(loginCookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
cookieHeader = string.Empty;
|
||||
throw new ExceptionWithConfigData("Failed", (ConfigurationData)config);
|
||||
CookieHeader = string.Empty;
|
||||
throw new ExceptionWithConfigData("Failed", configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Web;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils.Clients;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -22,6 +23,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "auth/login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents?in=1&type=2&search={0}"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public PrivateHD(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "PrivateHD",
|
||||
description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
|
||||
@@ -29,20 +36,20 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var incomingConfig = new ConfigurationDataBasicLogin();
|
||||
incomingConfig.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
var token = new Regex("Avz.CSRF_TOKEN = '(.*?)';").Match(loginPage.Content).Groups[1].ToString();
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "_token", token },
|
||||
{ "username_email", incomingConfig.Username.Value },
|
||||
{ "password", incomingConfig.Password.Value },
|
||||
{ "username_email", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "remember", "on" }
|
||||
};
|
||||
|
||||
@@ -52,15 +59,10 @@ namespace Jackett.Indexers
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom[".form-error"];
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
@@ -12,6 +12,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -20,6 +21,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "{0}?method=1&c{1}=1&search={2}"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l)
|
||||
: base(name: "SceneAccess",
|
||||
description: "Your gateway to the scene",
|
||||
@@ -27,23 +34,18 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: c,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "submit", "come on in" }
|
||||
};
|
||||
|
||||
@@ -55,7 +57,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["#login_box_desc"];
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string SearchUrl { get { return SiteLink + "browse_API.php"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php/{0}/download.torrent"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public SceneTime(IIndexerManagerService i, Logger l, IWebClient w)
|
||||
: base(name: "SceneTime",
|
||||
description: "Always on time",
|
||||
@@ -30,40 +37,35 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom["td.text"].Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
private Dictionary<string, string> GetSearchFormData(string searchString)
|
||||
{
|
||||
return new Dictionary<string, string> {
|
||||
{ "c2", "1" }, { "c43", "1" }, { "c9", "1" }, { "c63", "1" }, { "c77", "1" }, { "c100", "1" }, { "c101", "1" },
|
||||
{ "c2", "1" }, { "c43", "1" }, { "c9", "1" }, { "c63", "1" }, { "c77", "1" }, { "c100", "1" }, { "c101", "1" },
|
||||
{ "cata", "yes" }, { "sec", "jax" },
|
||||
{ "search", searchString}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
|
@@ -14,57 +14,63 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class ShowRSS : BaseIndexer, IIndexer
|
||||
{
|
||||
private string searchAllUrl { get { return SiteLink + "feeds/all.rss"; } }
|
||||
private string BaseUrl;
|
||||
readonly static string defaultSiteLink = "http://showrss.info/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchAllUrl { get { return BaseUri + "feeds/all.rss"; } }
|
||||
|
||||
new ConfigurationDataUrl configData
|
||||
{
|
||||
get { return (ConfigurationDataUrl)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "ShowRSS",
|
||||
description: "showRSS is a service that allows you to keep track of your favorite TV shows",
|
||||
link: "http://showrss.info/",
|
||||
link: defaultSiteLink,
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataUrl(defaultSiteLink))
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataUrl(SiteLink));
|
||||
}
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
public async Task ApplyConfiguration(Newtonsoft.Json.Linq.JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataUrl(SiteLink);
|
||||
config.LoadValuesFromJson(configJson);
|
||||
|
||||
var formattedUrl = config.GetFormattedHostUrl();
|
||||
var releases = await PerformQuery(new TorznabQuery(), formattedUrl);
|
||||
if (releases.Count() == 0)
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
|
||||
BaseUrl = formattedUrl;
|
||||
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["base_url"] = BaseUrl;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
});
|
||||
}
|
||||
|
||||
public override void LoadFromSavedConfiguration(Newtonsoft.Json.Linq.JToken jsonConfig)
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
BaseUrl = (string)jsonConfig["base_url"];
|
||||
IsConfigured = true;
|
||||
}
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
return await PerformQuery(query, BaseUrl);
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public override Task<byte[]> Download(Uri link)
|
||||
@@ -72,11 +78,11 @@ namespace Jackett.Indexers
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, string baseUrl)
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||
var episodeSearchUrl = string.Format(searchAllUrl);
|
||||
var episodeSearchUrl = string.Format(SearchAllUrl);
|
||||
var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
|
||||
var xmlDoc = new XmlDocument();
|
||||
|
||||
|
@@ -15,6 +15,7 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -26,6 +27,12 @@ namespace Jackett.Indexers
|
||||
private string CommentsUrl { get { return SiteLink + "t/{0}"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "download.php?torrent={0}"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public SpeedCD(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "Speed.cd",
|
||||
description: "Your home now!",
|
||||
@@ -33,30 +40,25 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 },
|
||||
};
|
||||
|
||||
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, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -13,48 +13,65 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Strike : BaseIndexer, IIndexer
|
||||
{
|
||||
private string DownloadUrl { get { return baseUri + "torrents/api/download/{0}.torrent"; } }
|
||||
private string SearchUrl { get { return baseUri + "api/v2/torrents/search/?category=TV&phrase={0}"; } }
|
||||
private string baseUrl = null;
|
||||
private Uri baseUri { get { return new Uri(baseUrl); } }
|
||||
readonly static string defaultSiteLink = "https://getstrike.net/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchUrl { get { return BaseUri + "api/v2/torrents/search/?category=TV&phrase={0}"; } }
|
||||
private string DownloadUrl { get { return BaseUri + "torrents/api/download/{0}.torrent"; } }
|
||||
|
||||
new ConfigurationDataUrl configData
|
||||
{
|
||||
get { return (ConfigurationDataUrl)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
|
||||
public Strike(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "Strike",
|
||||
description: "Torrent search engine",
|
||||
link: "https://getstrike.net/",
|
||||
link: defaultSiteLink,
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataUrl(defaultSiteLink))
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataUrl(SiteLink));
|
||||
}
|
||||
|
||||
public Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataUrl(SiteLink);
|
||||
config.LoadValuesFromJson(configJson);
|
||||
baseUrl = config.GetFormattedHostUrl();
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["base_url"] = baseUrl;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
return Task.FromResult(0);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
baseUrl = (string)jsonConfig["base_url"];
|
||||
IsConfigured = !string.IsNullOrEmpty(baseUrl);
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -28,19 +29,21 @@ namespace Jackett.Indexers
|
||||
HttpClientHandler handler;
|
||||
HttpClient client;
|
||||
|
||||
string username = string.Empty;
|
||||
string password = string.Empty;
|
||||
string token = string.Empty;
|
||||
DateTime lastTokenFetch = DateTime.MinValue;
|
||||
new ConfigurationDataLoginTokin configData
|
||||
{
|
||||
get { return (ConfigurationDataLoginTokin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public T411(IIndexerManagerService i, Logger l,IWebClient wc)
|
||||
public T411(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "T411",
|
||||
description: "French Torrent Tracker",
|
||||
link: "http://www.t411.io/",
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataLoginTokin())
|
||||
{
|
||||
CommentsUrl = SiteLink + "/torrents/{0}";
|
||||
IsConfigured = false;
|
||||
@@ -51,23 +54,17 @@ namespace Jackett.Indexers
|
||||
client = new HttpClient(handler);
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
return Task.FromResult<ConfigurationData>(config);
|
||||
}
|
||||
|
||||
async Task<string> GetAuthToken(bool forceFetch = false)
|
||||
{
|
||||
if (!forceFetch && lastTokenFetch > DateTime.Now - TimeSpan.FromHours(48))
|
||||
if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
|
||||
{
|
||||
return token;
|
||||
return configData.ApiToken.Value;
|
||||
}
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", username },
|
||||
{ "password", password }
|
||||
};
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var content = new FormUrlEncodedContent(pairs);
|
||||
|
||||
@@ -78,44 +75,45 @@ namespace Jackett.Indexers
|
||||
{
|
||||
throw new ApplicationException((string)jsonResponse["error"]);
|
||||
}
|
||||
token = (string)jsonResponse["token"];
|
||||
lastTokenFetch = DateTime.Now;
|
||||
return token;
|
||||
configData.ApiToken.Value = (string)jsonResponse["token"];
|
||||
configData.LastTokenFetchDateTime = DateTime.Now;
|
||||
return configData.ApiToken.Value;
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
|
||||
username = config.Username.Value;
|
||||
password = config.Password.Value;
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
Exception tokenFetchEx = null;
|
||||
try
|
||||
{
|
||||
await GetAuthToken(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ExceptionWithConfigData(ex.Message, (ConfigurationData)config);
|
||||
tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
|
||||
}
|
||||
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["username"] = username;
|
||||
configSaveData["password"] = password;
|
||||
configSaveData["token"] = token;
|
||||
configSaveData["last_token_fetch"] = lastTokenFetch;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
|
||||
{
|
||||
throw tokenFetchEx;
|
||||
});
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
username = (string)jsonConfig["username"];
|
||||
password = (string)jsonConfig["password"];
|
||||
token = (string)jsonConfig["token"];
|
||||
lastTokenFetch = (DateTime)jsonConfig["last_token_fetch"];
|
||||
IsConfigured = true;
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
configData.ApiToken.Value = jsonConfig.Value<string>("token"); ;
|
||||
configData.Username.Value = jsonConfig.Value<string>("username");
|
||||
configData.Password.Value = jsonConfig.Value<string>("password");
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
|
@@ -15,67 +15,71 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class ThePirateBay : BaseIndexer, IIndexer
|
||||
{
|
||||
private const string SearchUrl = "/search/{0}/0/99/208,205";
|
||||
private string BaseUrl;
|
||||
readonly static string defaultSiteLink = "https://thepiratebay.mn/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchUrl { get { return BaseUri + "search/{0}/0/99/208,205"; } }
|
||||
|
||||
new ConfigurationDataUrl configData
|
||||
{
|
||||
get { return (ConfigurationDataUrl)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public ThePirateBay(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "The Pirate Bay",
|
||||
description: "The worlds largest bittorrent indexer",
|
||||
link: "https://thepiratebay.mn/",
|
||||
link: defaultSiteLink,
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataUrl(defaultSiteLink))
|
||||
{
|
||||
BaseUrl = SiteLink.ToString();
|
||||
IsConfigured = false;
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataUrl(BaseUrl));
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataUrl(SiteLink);
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
var formattedUrl = config.GetFormattedHostUrl();
|
||||
var releases = await PerformQuery(new TorznabQuery(), formattedUrl);
|
||||
if (releases.Count() == 0)
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
|
||||
BaseUrl = formattedUrl;
|
||||
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["base_url"] = BaseUrl;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
BaseUrl = (string)jsonConfig["base_url"];
|
||||
IsConfigured = true;
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
return await PerformQuery(query, BaseUrl);
|
||||
}
|
||||
|
||||
async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, string baseUrl)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||
var queryStr = HttpUtility.UrlEncode(searchString);
|
||||
var episodeSearchUrl = baseUrl + string.Format(SearchUrl, queryStr);
|
||||
var episodeSearchUrl = string.Format(SearchUrl, queryStr);
|
||||
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
|
||||
|
||||
try
|
||||
@@ -94,7 +98,7 @@ namespace Jackett.Indexers
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.Title = qLink.Text().Trim();
|
||||
release.Description = release.Title;
|
||||
release.Comments = new Uri(baseUrl + "/" + qLink.Attr("href").TrimStart('/'));
|
||||
release.Comments = new Uri(BaseUri + qLink.Attr("href").TrimStart('/'));
|
||||
release.Guid = release.Comments;
|
||||
|
||||
var downloadCol = row.ChildElements.ElementAt(1).Cq().Children("a");
|
||||
|
@@ -15,6 +15,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string BrowseUrl { get { return SiteLink + "browse.php"; } }
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public TorrentBytes(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "TorrentBytes",
|
||||
description: "A decade of torrentbytes",
|
||||
@@ -30,7 +37,8 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
|
||||
AddCategoryMapping(41, TorznabCatType.TV);
|
||||
@@ -62,18 +70,12 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(24, TorznabCatType.XXXImg);
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task 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 },
|
||||
{ "returnto", "/" },
|
||||
{ "login", "Log in!" }
|
||||
};
|
||||
@@ -86,7 +88,7 @@ namespace Jackett.Indexers
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["body > div"].First();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -23,6 +24,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php?search={0}&cata=yes&c2=1&c7=1&c14=1&c24=1&c26=1&c31=1&c32=1&c33=1"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public TorrentDay(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "TorrentDay",
|
||||
description: "TorrentDay",
|
||||
@@ -30,27 +37,22 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var startMessage = await RequestStringWithCookies(StartPageUrl, string.Empty);
|
||||
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value }
|
||||
};
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
@@ -59,7 +61,7 @@ namespace Jackett.Indexers
|
||||
var messageEl = dom["#login"];
|
||||
messageEl.Children("form").Remove();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -22,6 +23,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "user/account/login/"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents/browse/index/query/{0}/categories/2%2C26%2C27%2C32/orderby/added?"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public TorrentLeech(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "TorrentLeech",
|
||||
description: "This is what happens when you seed",
|
||||
@@ -29,33 +36,28 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "remember_me", "on" },
|
||||
{ "login", "submit" }
|
||||
};
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true,null, LoginUrl);
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("/user/account/logout"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom[".ui-state-error"].Last();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -22,6 +23,12 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?searchstr={0}&release_type=both&searchtags=&tags_type=0&order_by=s3&order_way=desc&torrent_preset=all&filter_cat%5B600%5D=1&filter_cat%5B620%5D=1&filter_cat%5B700%5D=1&filter_cat%5B981%5D=1&filter_cat%5B980%5D=1"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public TorrentShack(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "TorrentShack",
|
||||
description: "TorrentShack",
|
||||
@@ -29,26 +36,21 @@ namespace Jackett.Indexers
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
client: wc,
|
||||
manager: i,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataBasicLogin());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataBasicLogin();
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", config.Username.Value },
|
||||
{ "password", config.Password.Value },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "keeplogged", "1" },
|
||||
{ "login", "Login" }
|
||||
};
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
@@ -57,7 +59,7 @@ namespace Jackett.Indexers
|
||||
var messageEl = dom["#loginform"];
|
||||
messageEl.Children("table").Remove();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -14,48 +14,67 @@ using System.Web;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
using System.Linq;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Torrentz : BaseIndexer, IIndexer
|
||||
{
|
||||
private string SearchUrl { get { return SiteLink + "feed_verifiedP?f={0}"; } }
|
||||
private string BaseUrl;
|
||||
readonly static string defaultSiteLink = "https://torrentz.eu/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchUrl { get { return BaseUri + "feed_verifiedP?f={0}"; } }
|
||||
|
||||
new ConfigurationDataUrl configData
|
||||
{
|
||||
get { return (ConfigurationDataUrl)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
|
||||
public Torrentz(IIndexerManagerService i, Logger l, IWebClient wc)
|
||||
: base(name: "Torrentz",
|
||||
description: "Torrentz is a meta-search engine and a Multisearch. This means we just search other search engines.",
|
||||
link: "https://torrentz.eu/",
|
||||
link: defaultSiteLink,
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l)
|
||||
logger: l,
|
||||
configData: new ConfigurationDataUrl(defaultSiteLink))
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDataUrl(SiteLink));
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var config = new ConfigurationDataUrl(SiteLink);
|
||||
config.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
var formattedUrl = config.GetFormattedHostUrl();
|
||||
IEnumerable<ReleaseInfo> releases = await PerformQuery(new TorznabQuery(), formattedUrl);
|
||||
if (releases.Count() == 0)
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
|
||||
BaseUrl = formattedUrl;
|
||||
var configSaveData = new JObject();
|
||||
configSaveData["base_url"] = BaseUrl;
|
||||
SaveConfig(configSaveData);
|
||||
IsConfigured = true;
|
||||
});
|
||||
}
|
||||
|
||||
async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, string baseUrl)
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||
@@ -106,18 +125,6 @@ namespace Jackett.Indexers
|
||||
return releases;
|
||||
}
|
||||
|
||||
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
BaseUrl = (string)jsonConfig["base_url"];
|
||||
IsConfigured = true;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
return await PerformQuery(query, BaseUrl);
|
||||
}
|
||||
|
||||
public override Task<byte[]> Download(Uri link)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@@ -15,87 +15,114 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class nCore : BaseIndexer, IIndexer
|
||||
public class NCore : BaseIndexer, IIndexer
|
||||
{
|
||||
private string SearchUrl = "https://ncore.cc/torrents.php";
|
||||
private static string LoginUrl = "https://ncore.cc/login.php";
|
||||
private readonly string LoggedInUrl = "https://ncore.cc/index.php";
|
||||
//private JToken configData = null;
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
|
||||
|
||||
private readonly string enSearch = "torrents.php?oldal=1&tipus=kivalasztottak_kozott&kivalasztott_tipus=xvidser,dvdser,hdser&mire={0}&miben=name";
|
||||
private readonly string hunSearch = "torrents.php?oldal=1&tipus=kivalasztottak_kozott&kivalasztott_tipus=xvidser_hun,dvdser_hun,hdser_hun,mire={0}&miben=name";
|
||||
private readonly string enHunSearch = "torrents.php?oldal=1&tipus=kivalasztottak_kozott&kivalasztott_tipus=xvidser_hun,xvidser,dvdser_hun,dvdser,hdser_hun,hdser&mire={0}&miben=name";
|
||||
new ConfigurationDataNCore configData
|
||||
{
|
||||
get { return (ConfigurationDataNCore)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
private string SearchUrlEn { get { return SiteLink.ToString() + enSearch; } }
|
||||
private string SearchUrlHun { get { return SiteLink.ToString() + hunSearch; } }
|
||||
private string SearchUrlEnHun { get { return SiteLink.ToString() + enHunSearch; } }
|
||||
|
||||
|
||||
public nCore(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
public NCore(IIndexerManagerService i, IWebClient wc, Logger l)
|
||||
: base(name: "nCore",
|
||||
description: "A Hungarian private torrent site.",
|
||||
link: "https://ncore.cc/",
|
||||
caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client:wc,
|
||||
logger: l)
|
||||
client: wc,
|
||||
logger: l,
|
||||
configData: new ConfigurationDataNCore())
|
||||
{
|
||||
SearchUrl = SearchUrlEnHun;
|
||||
}
|
||||
|
||||
public Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
//var config = configData == null ? new ConfigurationDatanCore() : new ConfigurationDatanCore(configData);
|
||||
//return Task.FromResult<ConfigurationData>(config);
|
||||
return Task.FromResult<ConfigurationData>(new ConfigurationDatanCore());
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
var incomingConfig = new ConfigurationDatanCore();
|
||||
incomingConfig.LoadValuesFromJson(configJson);
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
if (incomingConfig.Hungarian.Value == false && incomingConfig.English.Value == false)
|
||||
throw new ExceptionWithConfigData("Please select atleast one language.", (ConfigurationData)incomingConfig);
|
||||
if (configData.Hungarian.Value == false && configData.English.Value == false)
|
||||
throw new ExceptionWithConfigData("Please select atleast one language.", configData);
|
||||
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "nev", incomingConfig.Username.Value },
|
||||
{ "pass", incomingConfig.Password.Value },
|
||||
{ "ne_leptessen_ki", "on"}
|
||||
};
|
||||
{ "nev", configData.Username.Value },
|
||||
{ "pass", configData.Password.Value },
|
||||
{ "ne_leptessen_ki", "1"},
|
||||
{ "set_lang", "en" },
|
||||
{ "submitted", "1" },
|
||||
{ "submit", "Access!" }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, LoggedInUrl, LoggedInUrl);
|
||||
ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Felhasználó"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["#hibauzenet table tbody tr"];
|
||||
var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
|
||||
var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
|
||||
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig);
|
||||
});
|
||||
|
||||
//var configSaveData = new JObject();
|
||||
//configSaveData["config"] = incomingConfig.ToJson();
|
||||
//SaveConfig(configSaveData);
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("profile.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["#hibauzenet table tbody tr"];
|
||||
var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
|
||||
var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, string>> CreateKeyValueList(params string[][] keyValues)
|
||||
{
|
||||
var list = new List<KeyValuePair<string, string>>();
|
||||
foreach (var d in keyValues)
|
||||
{
|
||||
list.Add(new KeyValuePair<string, string>(d[0], d[1]));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyValuePair<string, string>> GetSearchFormData(string searchString)
|
||||
{
|
||||
const string searchTypeKey = "kivalasztott_tipus[]";
|
||||
var baseList = CreateKeyValueList(
|
||||
new[] { "nyit_sorozat_resz", "true" },
|
||||
new[] { "miben", "name" },
|
||||
new[] { "tipus", "kivalasztottak_kozott" },
|
||||
new[] { "submit.x", "1" },
|
||||
new[] { "submit.y", "1" },
|
||||
new[] { "submit", "Ok" },
|
||||
new[] { "mire", searchString }
|
||||
);
|
||||
|
||||
if (configData.English.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser" },
|
||||
new[] { searchTypeKey, "dvdser" },
|
||||
new[] { searchTypeKey, "hdser" }
|
||||
));
|
||||
}
|
||||
|
||||
if (configData.Hungarian.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser_hun" },
|
||||
new[] { searchTypeKey, "dvdser_hun" },
|
||||
new[] { searchTypeKey, "hdser_hun" }
|
||||
));
|
||||
}
|
||||
return baseList;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
List<ReleaseInfo> releases = new List<ReleaseInfo>();
|
||||
|
||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
|
||||
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(searchString));
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
|
||||
try
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
CQ dom = results.Content;
|
||||
|
||||
ReleaseInfo release;
|
||||
var rows = dom[".box_torrent_all"].Find(".box_torrent");
|
||||
@@ -129,36 +156,12 @@ namespace Jackett.Indexers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
//if (jsonConfig["config"] != null)
|
||||
//{
|
||||
// string hun, eng;
|
||||
// Dictionary<string, string>[] configDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(jsonConfig["config"].ToString());
|
||||
// configDictionary[2].TryGetValue("value", out hun);
|
||||
// configDictionary[3].TryGetValue("value", out eng);
|
||||
|
||||
// bool isHun = Boolean.Parse(hun);
|
||||
// bool isEng = Boolean.Parse(eng);
|
||||
|
||||
// if (isHun && isEng)
|
||||
// SearchUrl = SearchUrlEnHun;
|
||||
// else if (isHun && !isEng)
|
||||
// SearchUrl = SearchUrlHun;
|
||||
// else if (!isHun && isEng)
|
||||
// SearchUrl = SearchUrlEn;
|
||||
|
||||
// configData = jsonConfig["config"];
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -187,7 +187,7 @@
|
||||
<Compile Include="Indexers\HDTorrents.cs" />
|
||||
<Compile Include="Indexers\IIndexer.cs" />
|
||||
<Compile Include="Indexers\ImmortalSeed.cs" />
|
||||
<Compile Include="Indexers\nCore.cs" />
|
||||
<Compile Include="Indexers\NCore.cs" />
|
||||
<Compile Include="Indexers\TorrentBytes.cs" />
|
||||
<Compile Include="Indexers\IPTorrents.cs" />
|
||||
<Compile Include="Indexers\MoreThanTV.cs" />
|
||||
@@ -206,11 +206,12 @@
|
||||
<Compile Include="Indexers\Torrentz.cs" />
|
||||
<Compile Include="Models\CachedResult.cs" />
|
||||
<Compile Include="Models\CategoryMapping.cs" />
|
||||
<Compile Include="Models\ConfigurationDatanCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\BmtvConfig.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginAnimeBytes.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginFrenchTorrentDb.cs" />
|
||||
<Compile Include="Models\IndexerConfig\PretomeConfiguration.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataNCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAnimeBytes.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ISerializableConfig.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataPinNumber.cs" />
|
||||
<Compile Include="Models\TorrentPotatoRequest.cs" />
|
||||
<Compile Include="Models\TorrentPotatoResponse.cs" />
|
||||
<Compile Include="Models\TorrentPotatoResponseItem.cs" />
|
||||
@@ -233,10 +234,10 @@
|
||||
<Compile Include="Utils\BrowserUtil.cs" />
|
||||
<Compile Include="Models\CachedQueryResult.cs" />
|
||||
<Compile Include="Models\ChannelInfo.cs" />
|
||||
<Compile Include="Models\ConfigurationData.cs" />
|
||||
<Compile Include="Models\ConfigurationDataBasicLogin.cs" />
|
||||
<Compile Include="Models\ConfigurationDataCookie.cs" />
|
||||
<Compile Include="Models\ConfigurationDataUrl.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationData.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCookie.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataUrl.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="CookieContainerExtensions.cs" />
|
||||
<Compile Include="Utils\Clients\WebRequest.cs" />
|
||||
|
@@ -3,10 +3,11 @@ using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public abstract class ConfigurationData
|
||||
{
|
||||
@@ -19,6 +20,8 @@ namespace Jackett.Models
|
||||
HiddenData
|
||||
}
|
||||
|
||||
public HiddenItem CookieHeader { get; private set; } = new HiddenItem { Name = "CookieHeader" };
|
||||
|
||||
public ConfigurationData()
|
||||
{
|
||||
|
||||
@@ -31,28 +34,31 @@ namespace Jackett.Models
|
||||
|
||||
public void LoadValuesFromJson(JToken json)
|
||||
{
|
||||
// todo: match up ids with items and fill values
|
||||
IDictionary<string, JToken> dictionary = (JObject)json;
|
||||
foreach (var item in GetItems())
|
||||
var arr = (JArray)json;
|
||||
foreach (var item in GetItems(forDisplay: false))
|
||||
{
|
||||
var arrItem = arr.FirstOrDefault(f => f.Value<string>("id") == item.ID);
|
||||
if (arrItem == null)
|
||||
continue;
|
||||
|
||||
switch (item.ItemType)
|
||||
{
|
||||
case ItemType.InputString:
|
||||
((StringItem)item).Value = (string)dictionary[item.ID];
|
||||
break;
|
||||
case ItemType.InputBool:
|
||||
((BoolItem)item).Value = (bool)dictionary[item.ID];
|
||||
((StringItem)item).Value = arrItem.Value<string>("value");
|
||||
break;
|
||||
case ItemType.HiddenData:
|
||||
((HiddenItem)item).Value = (string)dictionary[item.ID];
|
||||
((HiddenItem)item).Value = arrItem.Value<string>("value");
|
||||
break;
|
||||
case ItemType.InputBool:
|
||||
((BoolItem)item).Value = arrItem.Value<bool>("value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JToken ToJson()
|
||||
public JToken ToJson(bool forDisplay = true)
|
||||
{
|
||||
var items = GetItems();
|
||||
var items = GetItems(forDisplay);
|
||||
var jArray = new JArray();
|
||||
foreach (var item in items)
|
||||
{
|
||||
@@ -80,6 +86,24 @@ namespace Jackett.Models
|
||||
return jArray;
|
||||
}
|
||||
|
||||
Item[] GetItems(bool forDisplay)
|
||||
{
|
||||
var properties = GetType()
|
||||
.GetProperties()
|
||||
.Where(p => p.CanRead)
|
||||
.Where(p => p.PropertyType.IsSubclassOf(typeof(Item)))
|
||||
.Select(p => (Item)p.GetValue(this));
|
||||
|
||||
if (!forDisplay)
|
||||
{
|
||||
properties = properties
|
||||
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return properties.ToArray();
|
||||
}
|
||||
|
||||
public class Item
|
||||
{
|
||||
public ItemType ItemType { get; set; }
|
||||
@@ -89,7 +113,7 @@ namespace Jackett.Models
|
||||
|
||||
public class HiddenItem : StringItem
|
||||
{
|
||||
public HiddenItem(string value)
|
||||
public HiddenItem(string value = "")
|
||||
{
|
||||
Value = value;
|
||||
ItemType = ItemType.HiddenData;
|
||||
@@ -132,7 +156,6 @@ namespace Jackett.Models
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Item[] GetItems();
|
||||
|
||||
//public abstract Item[] GetItems();
|
||||
}
|
||||
}
|
@@ -7,21 +7,16 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class ConfigurationDataBasicLoginAnimeBytes : ConfigurationDataBasicLogin
|
||||
class ConfigurationDataAnimeBytes : ConfigurationDataBasicLogin
|
||||
{
|
||||
public BoolItem IncludeRaw { get; private set; }
|
||||
public DisplayItem DateWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataBasicLoginAnimeBytes()
|
||||
public ConfigurationDataAnimeBytes()
|
||||
: base()
|
||||
{
|
||||
IncludeRaw = new BoolItem() { Name = "IncludeRaw", Value = false };
|
||||
DateWarning = new DisplayItem("This tracker does not supply upload dates so they are based off year of release.") { Name = "DateWarning" };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Username, Password, IncludeRaw, DateWarning };
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataBasicLogin : ConfigurationData
|
||||
{
|
||||
@@ -18,9 +18,6 @@ namespace Jackett.Models
|
||||
Password = new StringItem { Name = "Password" };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Username, Password };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class ConfigurationDataBasicLoginFrenchTorrentDb : ConfigurationData
|
||||
{
|
||||
public StringItem Cookie { get; private set; }
|
||||
|
||||
public ConfigurationDataBasicLoginFrenchTorrentDb()
|
||||
{
|
||||
Cookie = new StringItem { Name = "Cookie" };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Cookie };
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class BmtvConfig : ConfigurationData
|
||||
class ConfigurationDataCaptchaLogin : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Jackett.Models.IndexerConfig
|
||||
|
||||
public HiddenItem CaptchaCookie { get; private set; }
|
||||
|
||||
public BmtvConfig()
|
||||
public ConfigurationDataCaptchaLogin()
|
||||
{
|
||||
Username = new StringItem { Name = "Username" };
|
||||
Password = new StringItem { Name = "Password" };
|
||||
@@ -26,10 +26,5 @@ namespace Jackett.Models.IndexerConfig
|
||||
CaptchaText = new StringItem { Name = "Captcha Text" };
|
||||
CaptchaCookie = new HiddenItem("") { Name = "Captcha Cookie" };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Username, Password, CaptchaImage, CaptchaText, CaptchaCookie };
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
|
||||
public class ConfigurationDataCookie : ConfigurationData
|
||||
@@ -17,7 +17,7 @@ namespace Jackett.Models
|
||||
{
|
||||
Cookie = new StringItem { Name = "Cookie" };
|
||||
CookieHint = new DisplayItem(
|
||||
"<ol><li>Login to BeyondHD in your browser <li>Open the developer console, go the network tab <li>Find 'cookie' in the request headers <li>Copy & paste it to here</ol>")
|
||||
"<ol><li>Login to this tracker in your browser <li>Open the developer console, go the network tab <li>Find 'cookie' in the request headers <li>Copy & paste it to here</ol>")
|
||||
{
|
||||
Name = "CookieHint"
|
||||
};
|
||||
@@ -27,19 +27,6 @@ namespace Jackett.Models
|
||||
Name = "CookieExample"
|
||||
};
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Cookie, CookieHint, CookieExample };
|
||||
}
|
||||
|
||||
public string CookieHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return Cookie.Value.Trim().TrimStart(new char[] { '"' }).TrimEnd(new char[] { '"' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using Jackett.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataLoginTokin : ConfigurationDataBasicLogin
|
||||
{
|
||||
public HiddenItem ApiToken { get; private set; }
|
||||
public HiddenItem LastTokenFetchDate { get; private set; }
|
||||
|
||||
public DateTime LastTokenFetchDateTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return DateTimeUtil.UnixTimestampToDateTime(ParseUtil.CoerceDouble(LastTokenFetchDate.Value));
|
||||
}
|
||||
set
|
||||
{
|
||||
LastTokenFetchDate.Value = DateTimeUtil.DateTimeToUnixTimestamp(value).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigurationDataLoginTokin() : base()
|
||||
{
|
||||
ApiToken = new HiddenItem { Name = "ApiToken" };
|
||||
LastTokenFetchDate = new HiddenItem { Name = "LastTokenFetchDate" };
|
||||
LastTokenFetchDateTime = DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,16 +7,16 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDatanCore : ConfigurationData
|
||||
public class ConfigurationDataNCore : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public BoolItem Hungarian { get; set; }
|
||||
public BoolItem English { get; set; }
|
||||
|
||||
public ConfigurationDatanCore()
|
||||
public ConfigurationDataNCore()
|
||||
{
|
||||
Username = new StringItem { Name = "Username", Value = "" };
|
||||
Password = new StringItem { Name = "Password", Value = "" };
|
||||
@@ -24,9 +24,9 @@ namespace Jackett.Models
|
||||
English = new BoolItem { Name = "English", Value = true };
|
||||
}
|
||||
|
||||
public ConfigurationDatanCore(JToken json)
|
||||
public ConfigurationDataNCore(JToken json)
|
||||
{
|
||||
ConfigurationDatanCore configData = new ConfigurationDatanCore();
|
||||
ConfigurationDataNCore configData = new ConfigurationDataNCore();
|
||||
|
||||
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
|
||||
foreach (var config in configArray)
|
||||
@@ -52,11 +52,6 @@ namespace Jackett.Models
|
||||
}
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Username, Password, Hungarian, English };
|
||||
}
|
||||
|
||||
static string UppercaseFirst(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
@@ -6,18 +6,13 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class PretomeConfiguration : ConfigurationDataBasicLogin
|
||||
class ConfigurationDataPinNumber : ConfigurationDataBasicLogin
|
||||
{
|
||||
public StringItem Pin { get; private set; }
|
||||
|
||||
public PretomeConfiguration() : base()
|
||||
public ConfigurationDataPinNumber() : base()
|
||||
{
|
||||
Pin = new StringItem { Name = "Login Pin Number" };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Pin, Username, Password };
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataUrl : ConfigurationData
|
||||
{
|
||||
@@ -19,16 +19,5 @@ namespace Jackett.Models
|
||||
{
|
||||
Url = new StringItem { Name = "Url", Value = defaultUrl };
|
||||
}
|
||||
|
||||
public override Item[] GetItems()
|
||||
{
|
||||
return new Item[] { Url };
|
||||
}
|
||||
|
||||
public string GetFormattedHostUrl()
|
||||
{
|
||||
var uri = new Uri(Url.Value);
|
||||
return string.Format("{0}://{1}", uri.Scheme, uri.Host);
|
||||
}
|
||||
}
|
||||
}
|
15
src/Jackett/Models/IndexerConfig/ISerializableConfig.cs
Normal file
15
src/Jackett/Models/IndexerConfig/ISerializableConfig.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
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 interface ISerializableConfig
|
||||
{
|
||||
JObject Serialize();
|
||||
ISerializableConfig Deserialize(JObject jobj);
|
||||
}
|
||||
}
|
@@ -50,8 +50,16 @@ namespace Jackett.Services
|
||||
var configFilePath = GetIndexerConfigFilePath(idx);
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
var jsonString = JObject.Parse(File.ReadAllText(configFilePath));
|
||||
idx.LoadFromSavedConfiguration(jsonString);
|
||||
var fileStr = File.ReadAllText(configFilePath);
|
||||
var jsonString = JToken.Parse(fileStr);
|
||||
try
|
||||
{
|
||||
idx.LoadFromSavedConfiguration(jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Failed loading configuration for {0}, you must reconfigure this indexer", idx.DisplayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -97,7 +97,7 @@ namespace Jackett.Utils.Clients
|
||||
var cookieBuilder = new StringBuilder();
|
||||
foreach (var c in cookieHeaders)
|
||||
{
|
||||
cookieBuilder.AppendFormat("{0} ", c.Substring(0, c.IndexOf(';')+1));
|
||||
cookieBuilder.AppendFormat("{0} ", c.Substring(0, c.IndexOf(';') + 1));
|
||||
}
|
||||
|
||||
result.Cookies = cookieBuilder.ToString().TrimEnd();
|
||||
|
@@ -27,7 +27,7 @@ namespace Jackett.Utils.Clients
|
||||
{
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetBytes(Url:{0})", request.Url));
|
||||
var result = await Run(request);
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetBytes Returning {0} => {1} bytes", result.Status, (result.Content==null?"<NULL>":result.Content.Length.ToString())));
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetBytes Returning {0} => {1} bytes", result.Status, (result.Content == null ? "<NULL>" : result.Content.Length.ToString())));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -35,20 +35,21 @@ namespace Jackett.Utils.Clients
|
||||
{
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetString(Url:{0})", request.Url));
|
||||
var result = await Run(request);
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetString Returning {0} => {1}", result.Status, (result.Content== null?"<NULL>": Encoding.UTF8.GetString(result.Content))));
|
||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetString Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
|
||||
return Mapper.Map<WebClientStringResult>(result);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
Engine.Logger.Info("LibCurl init " + Curl.GlobalInit(CurlInitFlag.All).ToString());
|
||||
CurlHelper.OnErrorMessage += (msg) =>
|
||||
{
|
||||
Engine.Logger.Error(msg);
|
||||
};
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
Engine.Logger.Warn("Libcurl failed to initalize. Did you install it?");
|
||||
Engine.Logger.Warn("Debian: apt-get install libcurl4-openssl-dev");
|
||||
@@ -59,7 +60,7 @@ namespace Jackett.Utils.Clients
|
||||
var version = Curl.Version;
|
||||
Engine.Logger.Info("LibCurl version " + version);
|
||||
|
||||
if (!Startup.DoSSLFix.HasValue && version.IndexOf("NSS")>-1)
|
||||
if (!Startup.DoSSLFix.HasValue && version.IndexOf("NSS") > -1)
|
||||
{
|
||||
Engine.Logger.Info("NSS Detected SSL ECC workaround enabled.");
|
||||
Startup.DoSSLFix = true;
|
||||
@@ -75,9 +76,9 @@ namespace Jackett.Utils.Clients
|
||||
}
|
||||
else
|
||||
{
|
||||
if (request.PostData != null && request.PostData.Count > 0)
|
||||
if (request.PostData != null && request.PostData.Count() > 0)
|
||||
{
|
||||
logger.Debug("UnixLibCurlWebClient: Posting " + new FormUrlEncodedContent(request.PostData).ReadAsStringAsync().Result);
|
||||
logger.Debug("UnixLibCurlWebClient: Posting " + StringUtil.PostDataFromDict(request.PostData));
|
||||
}
|
||||
|
||||
response = await CurlHelper.PostAsync(request.Url, request.PostData, request.Cookies, request.Referer);
|
||||
|
@@ -61,9 +61,9 @@ namespace Jackett.Utils.Clients
|
||||
args.AppendFormat("--referer \"{0}\" ", request.Referer);
|
||||
}
|
||||
|
||||
if (request.PostData != null && request.PostData.Count > 0)
|
||||
if (request.PostData != null && request.PostData.Count() > 0)
|
||||
{
|
||||
var postString = new FormUrlEncodedContent(request.PostData).ReadAsStringAsync().Result;
|
||||
var postString = StringUtil.PostDataFromDict(request.PostData);
|
||||
args.AppendFormat("--data \"{0}\" ", postString);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Jackett.Utils.Clients
|
||||
string stdout = null;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
stdout = processService.StartProcessAndGetOutput(System.Environment.OSVersion.Platform == PlatformID.Unix?"curl":"curl.exe", args.ToString(), true);
|
||||
stdout = processService.StartProcessAndGetOutput(System.Environment.OSVersion.Platform == PlatformID.Unix ? "curl" : "curl.exe", args.ToString(), true);
|
||||
});
|
||||
|
||||
var outputData = File.ReadAllBytes(tempFile);
|
||||
@@ -126,7 +126,7 @@ namespace Jackett.Utils.Clients
|
||||
|
||||
result.Content = new byte[outputData.Length - (headSplit + 3)];
|
||||
var dest = 0;
|
||||
for (int i= headSplit+4;i< outputData.Length; i++)
|
||||
for (int i = headSplit + 4; i < outputData.Length; i++)
|
||||
{
|
||||
result.Content[dest] = outputData[i];
|
||||
dest++;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -10,26 +11,27 @@ namespace Jackett.Utils.Clients
|
||||
{
|
||||
public WebRequest()
|
||||
{
|
||||
PostData = new Dictionary<string, string>();
|
||||
PostData = new List<KeyValuePair<string, string>>();
|
||||
Type = RequestType.GET;
|
||||
}
|
||||
|
||||
public WebRequest(string url)
|
||||
{
|
||||
PostData = new Dictionary<string, string>();
|
||||
PostData = new List<KeyValuePair<string, string>>();
|
||||
Type = RequestType.GET;
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public string Url { get; set; }
|
||||
public Dictionary<string, string> PostData { get; set; }
|
||||
public IEnumerable<KeyValuePair<string, string>> PostData { get; set; }
|
||||
public string Cookies { get; set; }
|
||||
public string Referer { get; set; }
|
||||
public RequestType Type { get; set; }
|
||||
|
||||
|
||||
public override bool Equals(System.Object obj)
|
||||
{
|
||||
if(obj is WebRequest)
|
||||
if (obj is WebRequest)
|
||||
{
|
||||
var other = obj as WebRequest;
|
||||
var postDataSame = PostData == null && other.PostData == null;
|
||||
@@ -37,16 +39,16 @@ namespace Jackett.Utils.Clients
|
||||
{
|
||||
if (!(PostData == null || other.PostData == null))
|
||||
{
|
||||
var ok = PostData.Count == other.PostData.Count;
|
||||
foreach(var i in PostData)
|
||||
var ok = PostData.Count() == other.PostData.Count();
|
||||
foreach (var i in PostData)
|
||||
{
|
||||
if (!other.PostData.ContainsKey(i.Key))
|
||||
if (!other.PostData.Any(item => item.Key == i.Key))
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(PostData[i.Key] != other.PostData[i.Key])
|
||||
if (PostData.FirstOrDefault(item => item.Key == i.Key).Value != other.PostData.FirstOrDefault(item => item.Key == i.Key).Value)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
@@ -66,7 +68,8 @@ namespace Jackett.Utils.Clients
|
||||
other.Type == Type &&
|
||||
postDataSame;
|
||||
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -15,6 +15,14 @@ namespace Jackett.Utils
|
||||
return new DateTime(unixStart.Ticks + unixTimeStampInTicks);
|
||||
}
|
||||
|
||||
public static double DateTimeToUnixTimestamp(DateTime dt)
|
||||
{
|
||||
var date = dt.ToUniversalTime();
|
||||
var ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks;
|
||||
var ts = ticks / TimeSpan.TicksPerSecond;
|
||||
return ts;
|
||||
}
|
||||
|
||||
// ex: "2 hours 1 day"
|
||||
public static DateTime FromTimeAgo(string str)
|
||||
{
|
||||
|
@@ -9,6 +9,11 @@ namespace Jackett.Utils
|
||||
{
|
||||
public static class ParseUtil
|
||||
{
|
||||
public static double CoerceDouble(string str)
|
||||
{
|
||||
return double.Parse(str.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static float CoerceFloat(string str)
|
||||
{
|
||||
return float.Parse(str.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
@@ -25,6 +30,11 @@ namespace Jackett.Utils
|
||||
}
|
||||
|
||||
|
||||
public static bool TryCoerceDouble(string str, out double result)
|
||||
{
|
||||
return double.TryParse(str.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
}
|
||||
|
||||
public static bool TryCoerceFloat(string str, out float result)
|
||||
{
|
||||
return float.TryParse(str.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -24,6 +25,11 @@ namespace Jackett.Utils
|
||||
return Encoding.UTF8.GetString(Convert.FromBase64String(str));
|
||||
}
|
||||
|
||||
public static string PostDataFromDict(IEnumerable<KeyValuePair<string, string>> dict)
|
||||
{
|
||||
return new FormUrlEncodedContent(dict).ReadAsStringAsync().Result;
|
||||
}
|
||||
|
||||
public static string Hash(string input)
|
||||
{
|
||||
// Use input string to calculate MD5 hash
|
||||
@@ -46,7 +52,8 @@ namespace Jackett.Utils
|
||||
var properties = exception.GetType()
|
||||
.GetProperties();
|
||||
var fields = properties
|
||||
.Select(property => new {
|
||||
.Select(property => new
|
||||
{
|
||||
Name = property.Name,
|
||||
Value = property.GetValue(exception, null)
|
||||
})
|
||||
|
Reference in New Issue
Block a user